Compare commits
43 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a1751e4b99 | |||
| 07e29c32aa | |||
| 3c5617b403 | |||
| 50c2203ebf | |||
| 7644df57d0 | |||
| 3273072fb3 | |||
| d9e651fe72 | |||
| 08b339e0cd | |||
| a81967ddbd | |||
| 1afb90f3ba | |||
| 21a3ec6198 | |||
| c5fc2469d7 | |||
| aa5941a324 | |||
| 8fe243356e | |||
| 83a7c67439 | |||
| 36174834a8 | |||
| f087e4aa61 | |||
| 7998312785 | |||
| 37d0b928ec | |||
| 5f8da12363 | |||
| f16b3e3678 | |||
| ad1c99c3e9 | |||
| 7722cc16ff | |||
| 35ca33315d | |||
| 8154473d1a | |||
| c235a138ee | |||
| 1b79aa9d14 | |||
| 095b310109 | |||
| f92fa65133 | |||
| d81b99fd7d | |||
| f900649724 | |||
| 0bb9da198b | |||
| 5baac4fdb7 | |||
| b66976b7c4 | |||
| bfd07ebe90 | |||
| 50b24a7282 | |||
| 27f936d4a9 | |||
| 63ca92e470 | |||
| bbd761508e | |||
| 88e50525bd | |||
| e44bc74b90 | |||
| 46cbcbde4c | |||
| 6fdce11152 |
+4223
File diff suppressed because it is too large
Load Diff
+8045
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,351 @@
|
|||||||
|
using DocumentFormat.OpenXml.Office2010.Excel;
|
||||||
|
using DocumentFormat.OpenXml.Wordprocessing;
|
||||||
|
using MINOM.COM.Utility;
|
||||||
|
using Model;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data.SqlClient;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http.ModelBinding;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// StyleDataAccess 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
public class StyleDataAccess
|
||||||
|
{
|
||||||
|
LogUtility log=new LogUtility();
|
||||||
|
object[] obj = new object[] { "Y", "" ,null};
|
||||||
|
public StyleDataAccess()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: 在這裡新增建構函式邏輯
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public object[] AddTabletPaper(TabletPaperSize tps)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var context = new ezEntities())
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
var sp = new List<SqlParameter>();
|
||||||
|
sb.Append("insert into TabletPaperSize (PaperID,PaperName,Width,Height,CUser,CDate,CTime,UUser,UDate,UTime ) ");
|
||||||
|
sb.Append("values (@PaperID,@PaperName,@Width,@Height,@CUser,@CDate,@CTime,@UUser,@UDate,@UTime )");
|
||||||
|
sp.Add(new SqlParameter("@PaperID",tps.PaperID));
|
||||||
|
sp.Add(new SqlParameter("@PaperName", tps.PaperName));
|
||||||
|
sp.Add(new SqlParameter("@Width", tps.Width));
|
||||||
|
sp.Add(new SqlParameter("@Height", tps.Height));
|
||||||
|
sp.Add(new SqlParameter("@CUser", tps.CUser));
|
||||||
|
sp.Add(new SqlParameter("@CDate", tps.CDate));
|
||||||
|
sp.Add(new SqlParameter("@CTime", tps.CTime));
|
||||||
|
sp.Add(new SqlParameter("@UUser", tps.UUser));
|
||||||
|
sp.Add(new SqlParameter("@UDate", tps.UDate));
|
||||||
|
sp.Add(new SqlParameter("@UTime", tps.UTime));
|
||||||
|
context.Database.ExecuteSqlCommand(sb.ToString(),sp.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
log.writeErrorPath("AddTabletPaper:" + ex.Message + ex.StackTrace);
|
||||||
|
obj[0] = "N";
|
||||||
|
obj[1] = ex.Message;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
public object[] GetTabletPaper(string paperID, string name)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var context = new ezEntities())
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
var sp = new List<SqlParameter>();
|
||||||
|
|
||||||
|
sb.Append("select * from TabletPaperSize where 1=1 ");
|
||||||
|
if (!string.IsNullOrEmpty(paperID))
|
||||||
|
{
|
||||||
|
sb.Append("and PaperID=@PaperID ");
|
||||||
|
sp.Add(new SqlParameter("@PaperID", paperID));
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(name))
|
||||||
|
{
|
||||||
|
sb.Append("and Name=@Name ");
|
||||||
|
sp.Add(new SqlParameter("@Name", name));
|
||||||
|
}
|
||||||
|
var data = context.Database.SqlQuery<TabletPaperSize>(sb.ToString(), sp.ToArray()).ToList();
|
||||||
|
obj[2] = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
log.writeErrorPath("GetTabletElement:" + ex.Message + ex.StackTrace);
|
||||||
|
obj[0] = "N";
|
||||||
|
obj[1] = ex.Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public object[] GetTabletElement(string elementID ,string name)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var context = new ezEntities())
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
var sp = new List<SqlParameter>();
|
||||||
|
|
||||||
|
sb.Append("select * from TabletElement where 1=1 ");
|
||||||
|
if (!string.IsNullOrEmpty(elementID))
|
||||||
|
{
|
||||||
|
sb.Append("and ElementID=@ElementID ");
|
||||||
|
sp.Add(new SqlParameter("@ElementID", elementID));
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(name))
|
||||||
|
{
|
||||||
|
sb.Append("and Name=@Name ");
|
||||||
|
sp.Add(new SqlParameter("@Name", name));
|
||||||
|
}
|
||||||
|
var data = context.Database.SqlQuery<TabletElement>(sb.ToString(), sp.ToArray()).ToList();
|
||||||
|
obj[2] = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
log.writeErrorPath("GetTabletElement:" + ex.Message + ex.StackTrace);
|
||||||
|
obj[0] = "N";
|
||||||
|
obj[1] = ex.Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object[] GetStyleDetail(string styleID,string elementID)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var context = new ezEntities())
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
var sp = new List<SqlParameter>();
|
||||||
|
|
||||||
|
sb.Append("select * from TabletStyleDetail where 1=1 ");
|
||||||
|
if (!string.IsNullOrEmpty(styleID))
|
||||||
|
{
|
||||||
|
sb.Append("and StyleID=@StyleID ");
|
||||||
|
sp.Add(new SqlParameter("@StyleID", styleID));
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(elementID))
|
||||||
|
{
|
||||||
|
sb.Append("and ElementID=@ElementID ");
|
||||||
|
sp.Add(new SqlParameter("@ElementID", elementID));
|
||||||
|
}
|
||||||
|
var data = context.Database.SqlQuery<TabletStyleDetail>(sb.ToString(), sp.ToArray()).ToList();
|
||||||
|
obj[2] = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
log.writeErrorPath("GetStyleDetail:" + ex.Message + ex.StackTrace);
|
||||||
|
obj[0] = "N";
|
||||||
|
obj[1] = ex.Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
public object[] GetStyle(string id,string name)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var context = new ezEntities())
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
var sp = new List<SqlParameter>();
|
||||||
|
|
||||||
|
sb.Append("select * from TabletStyle where 1=1 ");
|
||||||
|
if (!string.IsNullOrEmpty(id))
|
||||||
|
{
|
||||||
|
sb.Append("and StyleID=@StyleID ");
|
||||||
|
sp.Add(new SqlParameter( "@StyleID",id));
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(name))
|
||||||
|
{
|
||||||
|
sb.Append("and Name=@Name ");
|
||||||
|
sp.Add(new SqlParameter("@Name", name));
|
||||||
|
}
|
||||||
|
var data= context.Database.SqlQuery<TabletStyle>(sb.ToString(), sp.ToArray()).ToList();
|
||||||
|
obj[2]= data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
log.writeErrorPath("GetStyle:" + ex.Message + ex.StackTrace);
|
||||||
|
obj[0] = "N";
|
||||||
|
obj[1] = ex.Message;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object[] AddStyle(TabletStyle ts, List<TabletStyleDetail> list)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var context = new ezEntities())
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
SqlParameter[] sp = new SqlParameter[] {
|
||||||
|
new SqlParameter("@StyleID",ts.StyleID),
|
||||||
|
new SqlParameter("@Name",ts.Name),
|
||||||
|
new SqlParameter("@Descr",ts.Descr),
|
||||||
|
new SqlParameter("@PaperSize",ts.PaperSize),
|
||||||
|
new SqlParameter("@BackendImg",ts.BackendImg),
|
||||||
|
new SqlParameter("@PrintSize",ts.PrintSize),
|
||||||
|
new SqlParameter("@PrintMode",ts.PrintMode),
|
||||||
|
new SqlParameter("@Orientation",ts.Orientation),
|
||||||
|
new SqlParameter("@PrintPageCount",ts.PrintPageCount),
|
||||||
|
new SqlParameter("@RosterLimit",ts.RosterLimit),
|
||||||
|
new SqlParameter("@CUser",""),
|
||||||
|
new SqlParameter("@CDate",""),
|
||||||
|
new SqlParameter("@CTime",""),
|
||||||
|
new SqlParameter("@UUser",""),
|
||||||
|
new SqlParameter("@UDate",""),
|
||||||
|
new SqlParameter("@UTime",""),
|
||||||
|
};
|
||||||
|
|
||||||
|
sb.Append("insert into TabletStyle (StyleID,Name,Descr,PaperSize,BackendImg,PrintSize,PrintMode,Orientation,PrintPageCount,RosterLimit");
|
||||||
|
sb.Append(",CUser,CDate,CTime,UUser,UDate,UTime ) ");
|
||||||
|
sb.Append("values(@StyleID,@Name,@Descr,@PaperSize,@BackendImg,@PrintSize,@PrintMode,@Orientation,@PrintPageCount,@RosterLimit");
|
||||||
|
sb.Append(",@CUser,@CDate,@CTime,@UUser,@UDate,@UTime ) ");
|
||||||
|
context.Database.ExecuteSqlCommand(sb.ToString(), sp);
|
||||||
|
|
||||||
|
sb.Clear();
|
||||||
|
sb.Append("insert into TabletStyleDetail(StyleID,Name,Descr,ElementID,StartX,StartY,FontSize,BreakLen,FontFamily,TwoOffset,");
|
||||||
|
sb.Append("ThreeOffset,FourOffSet,IsActive,Width,Height,TextWidth,TextHeight,CUser,CDate,CTime,UUser,UDate,UTime) ");
|
||||||
|
sb.Append("values (@StyleID,@Name,@Descr,@ElementID,@StartX,@StartY,@FontSize,@BreakLen,@FontFamily,@TwoOffset,");
|
||||||
|
sb.Append("@ThreeOffset,@FourOffSet,@IsActive,@Width,@Height,@TextWidth,@TextHeight,@CUser,@CDate,@CTime,@UUser,@UDate,@UTime) ");
|
||||||
|
foreach (var item in list)
|
||||||
|
{
|
||||||
|
SqlParameter[] sp1 = new SqlParameter[] {
|
||||||
|
new SqlParameter("@StyleID",item.StyleID),
|
||||||
|
new SqlParameter("@Name",item.Name),
|
||||||
|
new SqlParameter("@Descr",item.Descr),
|
||||||
|
new SqlParameter("@ElementID",item.ElementID),
|
||||||
|
new SqlParameter("@StartX",item.StartX),
|
||||||
|
new SqlParameter("@StartY",item.StartY),
|
||||||
|
new SqlParameter("@FontSize",item.FontSize),
|
||||||
|
new SqlParameter("@BreakLen",item.BreakLen),
|
||||||
|
new SqlParameter("@FontFamily",item.FontFamily),
|
||||||
|
new SqlParameter("@TwoOffset",item.TwoOffset),
|
||||||
|
new SqlParameter("@ThreeOffset",item.ThreeOffset),
|
||||||
|
new SqlParameter("@FourOffset",item.FourOffset),
|
||||||
|
new SqlParameter("@IsActive",item.IsActive),
|
||||||
|
new SqlParameter("@Width",item.Width),
|
||||||
|
new SqlParameter("@Height",item.Height),
|
||||||
|
new SqlParameter("@TextWidth",item.TextWidth),
|
||||||
|
new SqlParameter("@TextHeight",item.TextHeight),
|
||||||
|
new SqlParameter("@CUser",""),
|
||||||
|
new SqlParameter("@CDate",""),
|
||||||
|
new SqlParameter("@CTime",""),
|
||||||
|
new SqlParameter("@UUser",""),
|
||||||
|
new SqlParameter("@UDate",""),
|
||||||
|
new SqlParameter("@UTime",""),
|
||||||
|
};
|
||||||
|
context.Database.ExecuteSqlCommand(sb.ToString(), sp1.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
log.writeErrorPath("AddStyle:" + ex.Message+ex.StackTrace);
|
||||||
|
obj[0] = "N";
|
||||||
|
obj[1] = ex.Message;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object[] UpdateStyle(TabletStyle ts, List<TabletStyleDetail> list)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var context = new ezEntities())
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
SqlParameter[] sp = new SqlParameter[] {
|
||||||
|
new SqlParameter("@StyleID",ts.StyleID),
|
||||||
|
new SqlParameter("@Name",ts.Name),
|
||||||
|
new SqlParameter("@Descr",ts.Descr),
|
||||||
|
new SqlParameter("@PaperSize",ts.PaperSize),
|
||||||
|
new SqlParameter("@BackendImg",ts.BackendImg),
|
||||||
|
new SqlParameter("@PrintSize",ts.PrintSize),
|
||||||
|
new SqlParameter("@PrintMode",ts.PrintMode),
|
||||||
|
new SqlParameter("@Orientation",ts.Orientation),
|
||||||
|
new SqlParameter("@PrintPageCount",ts.PrintPageCount),
|
||||||
|
new SqlParameter("@RosterLimit",ts.RosterLimit),
|
||||||
|
new SqlParameter("@CUser",""),
|
||||||
|
new SqlParameter("@CDate",""),
|
||||||
|
new SqlParameter("@CTime",""),
|
||||||
|
new SqlParameter("@UUser",""),
|
||||||
|
new SqlParameter("@UDate",""),
|
||||||
|
new SqlParameter("@UTime",""),
|
||||||
|
};
|
||||||
|
|
||||||
|
sb.Append("update TabletStyle set Descr=@Descr,PaperSize=@PaperSize,BackendImg=@BackendImg,PrintSize=@PrintSize,");
|
||||||
|
sb.Append("PrintMode=@PrintMode,Orientation=@Orientation,PrintPageCount=@PrintPageCount,RosterLimit=@RosterLimit,");
|
||||||
|
sb.Append("CUser=@CUser,CDate=@CDate,CTime=@CTime,UUser=@UUSer,UDate=@UDate,UTime=@UTime ");
|
||||||
|
sb.Append("where StyleID=@StyleID ");
|
||||||
|
|
||||||
|
context.Database.ExecuteSqlCommand(sb.ToString(), sp.ToArray());
|
||||||
|
|
||||||
|
sb.Clear();
|
||||||
|
sb.Append("update TabletStyleDetail set Descr=@Descr,StartX=@StartX,StartY=@StartY,FontSize=@FontSize,BreakLen=@BreakLen,");
|
||||||
|
sb.Append("FontFamily=@FontFamily,TwoOffset=@TwoOffset,ThreeOffset=@ThreeOffset,FourOffset=@FourOffset,IsActive=@IsActive,");
|
||||||
|
sb.Append("Width=@Width,Height=@Height,TextWidth=@TextWidth,TextHeight=@TextHeight,UUser=@UUser,UDate=@UDate,UTime=@UTime ");
|
||||||
|
sb.Append("where StyleID=@StyleID and ElementID=@ElementID ");
|
||||||
|
//sb.Append("insert into TabletStyleDetail(StyleID,Name,Descr,ElementID,StartX,StartY,FontSize,BreakLen,FontFamily,TwoOffset,");
|
||||||
|
//sb.Append("ThreeOffset,FourOffSet,IsActive,Width,Height,TextWidth,TextHeight,CUser,CDate,CTime,UUser,UDate,UTime) ");
|
||||||
|
//sb.Append("values (@StyleID,@Name,@Descr,@ElementID,@StartX,@StartY,@FontSize,@BreakLen,@FontFamily,@TwoOffset,");
|
||||||
|
//sb.Append("@ThreeOffset,@FourOffSet,@IsActive,@Width,@Height,@TextWidth,@TextHeight,@CUser,@CDate,@CTime,@UUser,@UDate,@UTime) ");
|
||||||
|
foreach (var item in list)
|
||||||
|
{
|
||||||
|
SqlParameter[] sp1 = new SqlParameter[] {
|
||||||
|
new SqlParameter("@StyleID",item.StyleID),
|
||||||
|
new SqlParameter("@Name",item.Name),
|
||||||
|
new SqlParameter("@Descr",item.Descr),
|
||||||
|
new SqlParameter("@ElementID",item.ElementID),
|
||||||
|
new SqlParameter("@StartX",item.StartX),
|
||||||
|
new SqlParameter("@StartY",item.StartY),
|
||||||
|
new SqlParameter("@FontSize",item.FontSize),
|
||||||
|
new SqlParameter("@BreakLen",item.BreakLen),
|
||||||
|
new SqlParameter("@FontFamily",item.FontFamily),
|
||||||
|
new SqlParameter("@TwoOffset",item.TwoOffset),
|
||||||
|
new SqlParameter("@ThreeOffset",item.ThreeOffset),
|
||||||
|
new SqlParameter("@FourOffset",item.FourOffset),
|
||||||
|
new SqlParameter("@IsActive",item.IsActive),
|
||||||
|
new SqlParameter("@Width",item.Width),
|
||||||
|
new SqlParameter("@Height",item.Height),
|
||||||
|
new SqlParameter("@TextWidth",item.TextWidth),
|
||||||
|
new SqlParameter("@TextHeight",item.TextHeight),
|
||||||
|
new SqlParameter("@CUser",""),
|
||||||
|
new SqlParameter("@CDate",""),
|
||||||
|
new SqlParameter("@CTime",""),
|
||||||
|
new SqlParameter("@UUser",""),
|
||||||
|
new SqlParameter("@UDate",""),
|
||||||
|
new SqlParameter("@UTime",""),
|
||||||
|
};
|
||||||
|
context.Database.ExecuteSqlCommand(sb.ToString(), sp1.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
log.writeErrorPath("UpdateStyle:" + ex.Message + ex.StackTrace);
|
||||||
|
obj[0] = "N";
|
||||||
|
obj[1] = ex.Message;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Style 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
public class TabletStyle
|
||||||
|
{
|
||||||
|
public TabletStyle()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: 在這裡新增建構函式邏輯
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public string StyleID { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Descr { get; set; }
|
||||||
|
public string PaperSize { get; set; }
|
||||||
|
public string BackendImg { get; set; }
|
||||||
|
public string PrintSize { get; set; }
|
||||||
|
public string PrintMode { get; set; }
|
||||||
|
public string Orientation { get; set; }
|
||||||
|
public string PrintPageCount { get; set; }
|
||||||
|
public string RosterLimit { get; set; }
|
||||||
|
public string CUser { get; set; }
|
||||||
|
public string CDate { get; set; }
|
||||||
|
public string CTime { get; set; }
|
||||||
|
public string UUser { get; set; }
|
||||||
|
public string UDate { get; set; }
|
||||||
|
public string UTime { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TabletStyleDetail
|
||||||
|
{
|
||||||
|
public TabletStyleDetail() { }
|
||||||
|
public string StyleID { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Descr { get; set; }
|
||||||
|
public string ElementID { get; set; }
|
||||||
|
public string StartX { get; set; }
|
||||||
|
public string StartY { get; set; }
|
||||||
|
public string FontSize { get; set; }
|
||||||
|
public string FontFamily { get; set; }
|
||||||
|
public string TwoOffset { get; set; }
|
||||||
|
public string ThreeOffset { get; set; }
|
||||||
|
public string FourOffset { get; set; }
|
||||||
|
public string IsActive { get; set; }
|
||||||
|
public string Width { get; set; }
|
||||||
|
public string Height { get; set; }
|
||||||
|
public string TextWidth { get; set; }
|
||||||
|
public string TextHeight { get; set; }
|
||||||
|
public string BreakLen { get; set; }
|
||||||
|
public string CUser { get; set; }
|
||||||
|
public string CDate { get; set; }
|
||||||
|
public string CTime { get; set; }
|
||||||
|
public string UUser { get; set; }
|
||||||
|
public string UDate { get; set; }
|
||||||
|
public string UTime { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TabletElement
|
||||||
|
{
|
||||||
|
public TabletElement() { }
|
||||||
|
public string ElementID { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string ElementType { get; set; }
|
||||||
|
public string SampleContent { get; set; }
|
||||||
|
public string CUser { get; set; }
|
||||||
|
public string CDate { get; set; }
|
||||||
|
public string CTime { get; set; }
|
||||||
|
public string UUser { get; set; }
|
||||||
|
public string UDate { get; set; }
|
||||||
|
public string UTime { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TabletPaperSize
|
||||||
|
{
|
||||||
|
public TabletPaperSize() { }
|
||||||
|
public string PaperID { get; set; }
|
||||||
|
public string PaperName { get; set; }
|
||||||
|
public string Width { get; set; }
|
||||||
|
public string Height { get; set; }
|
||||||
|
public string CUser { get; set; }
|
||||||
|
public string CDate { get; set; }
|
||||||
|
public string CTime { get; set; }
|
||||||
|
public string UUser { get; set; }
|
||||||
|
public string UDate { get; set; }
|
||||||
|
public string UTime { get; set; }
|
||||||
|
}
|
||||||
Generated
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// 已啟用模型 'D:\dev\ez\17168erp\git_17888\web\App_Code\Model\Model.edmx' 的 T4 程式碼產生。
|
// 已啟用模型 'D:\17168ERP\web\App_Code\Model\Model.edmx' 的 T4 程式碼產生。
|
||||||
// 若要啟用舊版程式碼產生,請將 [程式碼產生策略] 設計工具屬性的值
|
// 若要啟用舊版程式碼產生,請將 [程式碼產生策略] 設計工具屬性的值
|
||||||
//變更為 [舊版 ObjectContext]。當模型在設計工具中開啟時,這個屬性便可
|
//變更為 [舊版 ObjectContext]。當模型在設計工具中開啟時,這個屬性便可
|
||||||
//以在 [屬性] 視窗中使用。
|
//以在 [屬性] 視窗中使用。
|
||||||
|
|||||||
@@ -184,6 +184,10 @@ namespace Model
|
|||||||
public string partno { get; set; }
|
public string partno { get; set; }
|
||||||
public string print_init { get; set; }
|
public string print_init { get; set; }
|
||||||
public string is_reconcile { get; set; }
|
public string is_reconcile { get; set; }
|
||||||
|
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; }
|
public virtual actItem_kind actItem_kind { get; set; }
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||||
@@ -1389,6 +1393,7 @@ namespace Model
|
|||||||
public Nullable<int> parent_num { get; set; }
|
public Nullable<int> parent_num { get; set; }
|
||||||
public string print_id { get; set; }
|
public string print_id { get; set; }
|
||||||
public Nullable<System.DateTime> UpdateTime { get; set; }
|
public Nullable<System.DateTime> UpdateTime { get; set; }
|
||||||
|
public string style { get; set; }
|
||||||
|
|
||||||
public virtual actItem actItem { get; set; }
|
public virtual actItem actItem { get; set; }
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||||
|
|||||||
@@ -91,6 +91,10 @@
|
|||||||
<Property Name="customize_data" Type="nvarchar(max)" />
|
<Property Name="customize_data" Type="nvarchar(max)" />
|
||||||
<Property Name="reg_time" Type="datetime" />
|
<Property Name="reg_time" Type="datetime" />
|
||||||
<Property Name="is_reconcile" Type="nvarchar" MaxLength="1" />
|
<Property Name="is_reconcile" Type="nvarchar" MaxLength="1" />
|
||||||
|
<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>
|
||||||
<EntityType Name="actItem_files">
|
<EntityType Name="actItem_files">
|
||||||
<Key>
|
<Key>
|
||||||
@@ -480,7 +484,7 @@
|
|||||||
<Property Name="country" Type="nvarchar" MaxLength="5" />
|
<Property Name="country" Type="nvarchar" MaxLength="5" />
|
||||||
<Property Name="appellation_id" Type="int" />
|
<Property Name="appellation_id" Type="int" />
|
||||||
<Property Name="follower_hash" Type="nvarchar" MaxLength="100" />
|
<Property Name="follower_hash" Type="nvarchar" MaxLength="100" />
|
||||||
<Property Name="search_keywords" Type="nvarchar(max)" />
|
<Property Name="search_keywords" Type="varchar(max)" />
|
||||||
</EntityType>
|
</EntityType>
|
||||||
<EntityType Name="followers_tablet">
|
<EntityType Name="followers_tablet">
|
||||||
<Key>
|
<Key>
|
||||||
@@ -604,8 +608,8 @@
|
|||||||
</Key>
|
</Key>
|
||||||
<Property Name="num" Type="int" StoreGeneratedPattern="Identity" Nullable="false" />
|
<Property Name="num" Type="int" StoreGeneratedPattern="Identity" Nullable="false" />
|
||||||
<Property Name="kind" Type="nvarchar" MaxLength="100" />
|
<Property Name="kind" Type="nvarchar" MaxLength="100" />
|
||||||
<Property Name="starttime" Type="time" Precision="0" />
|
<Property Name="starttime" Type="time" Precision="7" />
|
||||||
<Property Name="offtime" Type="time" Precision="0" />
|
<Property Name="offtime" Type="time" Precision="7" />
|
||||||
<Property Name="resttime" Type="int" />
|
<Property Name="resttime" Type="int" />
|
||||||
<Property Name="root" Type="int" />
|
<Property Name="root" Type="int" />
|
||||||
<Property Name="range" Type="int" />
|
<Property Name="range" Type="int" />
|
||||||
@@ -724,6 +728,7 @@
|
|||||||
<Property Name="customize_data" Type="nvarchar(max)" />
|
<Property Name="customize_data" Type="nvarchar(max)" />
|
||||||
<Property Name="printed_files" Type="nvarchar(max)" />
|
<Property Name="printed_files" Type="nvarchar(max)" />
|
||||||
<Property Name="UpdateTime" Type="datetime2" Precision="7" />
|
<Property Name="UpdateTime" Type="datetime2" Precision="7" />
|
||||||
|
<Property Name="style" Type="varchar" MaxLength="50" />
|
||||||
</EntityType>
|
</EntityType>
|
||||||
<EntityType Name="pro_order_record">
|
<EntityType Name="pro_order_record">
|
||||||
<Key>
|
<Key>
|
||||||
@@ -980,7 +985,7 @@
|
|||||||
<Property Name="balance_act_item" Type="int" />
|
<Property Name="balance_act_item" Type="int" />
|
||||||
<Property Name="balance_pro_order_detail" Type="int" />
|
<Property Name="balance_pro_order_detail" Type="int" />
|
||||||
</EntityType>
|
</EntityType>
|
||||||
<Association Name="FK__Ancestral__Regis__4DF47A4E">
|
<Association Name="FK__Ancestral__Regis__1A9EF37A">
|
||||||
<End Role="AncestralTabletRegistrant" Type="Self.AncestralTabletRegistrant" Multiplicity="1" />
|
<End Role="AncestralTabletRegistrant" Type="Self.AncestralTabletRegistrant" Multiplicity="1" />
|
||||||
<End Role="AncestralTabletPositionRecord" Type="Self.AncestralTabletPositionRecord" Multiplicity="*" />
|
<End Role="AncestralTabletPositionRecord" Type="Self.AncestralTabletPositionRecord" Multiplicity="*" />
|
||||||
<ReferentialConstraint>
|
<ReferentialConstraint>
|
||||||
@@ -1079,7 +1084,9 @@
|
|||||||
</ReferentialConstraint>
|
</ReferentialConstraint>
|
||||||
</Association>
|
</Association>
|
||||||
<Association Name="FK_act_bom_actItem1">
|
<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="*" />
|
<End Role="act_bom" Type="Self.act_bom" Multiplicity="*" />
|
||||||
<ReferentialConstraint>
|
<ReferentialConstraint>
|
||||||
<Principal Role="actItem">
|
<Principal Role="actItem">
|
||||||
@@ -1128,18 +1135,6 @@
|
|||||||
</Dependent>
|
</Dependent>
|
||||||
</ReferentialConstraint>
|
</ReferentialConstraint>
|
||||||
</Association>
|
</Association>
|
||||||
<Association Name="FK_activity_activity_kind">
|
|
||||||
<End Role="activity_kind" Type="Self.activity_kind" Multiplicity="0..1" />
|
|
||||||
<End Role="activity" Type="Self.activity" Multiplicity="*" />
|
|
||||||
<ReferentialConstraint>
|
|
||||||
<Principal Role="activity_kind">
|
|
||||||
<PropertyRef Name="num" />
|
|
||||||
</Principal>
|
|
||||||
<Dependent Role="activity">
|
|
||||||
<PropertyRef Name="kind" />
|
|
||||||
</Dependent>
|
|
||||||
</ReferentialConstraint>
|
|
||||||
</Association>
|
|
||||||
<Association Name="FK_activity_check_activity">
|
<Association Name="FK_activity_check_activity">
|
||||||
<End Role="activity" Type="Self.activity" Multiplicity="0..1">
|
<End Role="activity" Type="Self.activity" Multiplicity="0..1">
|
||||||
<OnDelete Action="Cascade" />
|
<OnDelete Action="Cascade" />
|
||||||
@@ -1211,7 +1206,9 @@
|
|||||||
</ReferentialConstraint>
|
</ReferentialConstraint>
|
||||||
</Association>
|
</Association>
|
||||||
<Association Name="FK_activity_relating_activity">
|
<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="*" />
|
<End Role="activity_relating" Type="Self.activity_relating" Multiplicity="*" />
|
||||||
<ReferentialConstraint>
|
<ReferentialConstraint>
|
||||||
<Principal Role="activity">
|
<Principal Role="activity">
|
||||||
@@ -1637,7 +1634,9 @@
|
|||||||
</ReferentialConstraint>
|
</ReferentialConstraint>
|
||||||
</Association>
|
</Association>
|
||||||
<Association Name="FK_pro_order_activity">
|
<Association Name="FK_pro_order_activity">
|
||||||
<End Role="activity" Type="Self.activity" Multiplicity="0..1" />
|
<End Role="activity" Type="Self.activity" Multiplicity="0..1">
|
||||||
|
<OnDelete Action="Cascade" />
|
||||||
|
</End>
|
||||||
<End Role="pro_order" Type="Self.pro_order" Multiplicity="*" />
|
<End Role="pro_order" Type="Self.pro_order" Multiplicity="*" />
|
||||||
<ReferentialConstraint>
|
<ReferentialConstraint>
|
||||||
<Principal Role="activity">
|
<Principal Role="activity">
|
||||||
@@ -1687,7 +1686,9 @@
|
|||||||
</ReferentialConstraint>
|
</ReferentialConstraint>
|
||||||
</Association>
|
</Association>
|
||||||
<Association Name="FK_pro_order_detail_pro_order">
|
<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="*" />
|
<End Role="pro_order_detail" Type="Self.pro_order_detail" Multiplicity="*" />
|
||||||
<ReferentialConstraint>
|
<ReferentialConstraint>
|
||||||
<Principal Role="pro_order">
|
<Principal Role="pro_order">
|
||||||
@@ -1699,7 +1700,9 @@
|
|||||||
</ReferentialConstraint>
|
</ReferentialConstraint>
|
||||||
</Association>
|
</Association>
|
||||||
<Association Name="FK_pro_order_followers">
|
<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="*" />
|
<End Role="pro_order" Type="Self.pro_order" Multiplicity="*" />
|
||||||
<ReferentialConstraint>
|
<ReferentialConstraint>
|
||||||
<Principal Role="followers">
|
<Principal Role="followers">
|
||||||
@@ -2157,7 +2160,7 @@
|
|||||||
<EntitySet Name="supplier" EntityType="Self.supplier" Schema="dbo" store:Type="Tables" />
|
<EntitySet Name="supplier" EntityType="Self.supplier" Schema="dbo" store:Type="Tables" />
|
||||||
<EntitySet Name="supplier_kind" EntityType="Self.supplier_kind" Schema="dbo" store:Type="Tables" />
|
<EntitySet Name="supplier_kind" EntityType="Self.supplier_kind" Schema="dbo" store:Type="Tables" />
|
||||||
<EntitySet Name="transfer_register" EntityType="Self.transfer_register" Schema="dbo" store:Type="Tables" />
|
<EntitySet Name="transfer_register" EntityType="Self.transfer_register" Schema="dbo" store:Type="Tables" />
|
||||||
<AssociationSet Name="FK__Ancestral__Regis__4DF47A4E" Association="Self.FK__Ancestral__Regis__4DF47A4E">
|
<AssociationSet Name="FK__Ancestral__Regis__1A9EF37A" Association="Self.FK__Ancestral__Regis__1A9EF37A">
|
||||||
<End Role="AncestralTabletRegistrant" EntitySet="AncestralTabletRegistrant" />
|
<End Role="AncestralTabletRegistrant" EntitySet="AncestralTabletRegistrant" />
|
||||||
<End Role="AncestralTabletPositionRecord" EntitySet="AncestralTabletPositionRecord" />
|
<End Role="AncestralTabletPositionRecord" EntitySet="AncestralTabletPositionRecord" />
|
||||||
</AssociationSet>
|
</AssociationSet>
|
||||||
@@ -2205,10 +2208,6 @@
|
|||||||
<End Role="activity_category_kind" EntitySet="activity_category_kind" />
|
<End Role="activity_category_kind" EntitySet="activity_category_kind" />
|
||||||
<End Role="activity" EntitySet="activity" />
|
<End Role="activity" EntitySet="activity" />
|
||||||
</AssociationSet>
|
</AssociationSet>
|
||||||
<AssociationSet Name="FK_activity_activity_kind" Association="Self.FK_activity_activity_kind">
|
|
||||||
<End Role="activity_kind" EntitySet="activity_kind" />
|
|
||||||
<End Role="activity" EntitySet="activity" />
|
|
||||||
</AssociationSet>
|
|
||||||
<AssociationSet Name="FK_activity_check_activity" Association="Self.FK_activity_check_activity">
|
<AssociationSet Name="FK_activity_check_activity" Association="Self.FK_activity_check_activity">
|
||||||
<End Role="activity" EntitySet="activity" />
|
<End Role="activity" EntitySet="activity" />
|
||||||
<End Role="activity_check" EntitySet="activity_check" />
|
<End Role="activity_check" EntitySet="activity_check" />
|
||||||
@@ -2613,6 +2612,10 @@
|
|||||||
<Property Name="print_init" Type="String" MaxLength="100" FixedLength="false" Unicode="true" />
|
<Property Name="print_init" Type="String" MaxLength="100" FixedLength="false" Unicode="true" />
|
||||||
<NavigationProperty Name="transfer_register" Relationship="Model.FK_transfer_register_actItem" FromRole="actItem" ToRole="transfer_register" />
|
<NavigationProperty Name="transfer_register" Relationship="Model.FK_transfer_register_actItem" FromRole="actItem" ToRole="transfer_register" />
|
||||||
<Property Name="is_reconcile" Type="String" MaxLength="1" FixedLength="false" Unicode="true" />
|
<Property Name="is_reconcile" Type="String" MaxLength="1" FixedLength="false" Unicode="true" />
|
||||||
|
<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>
|
||||||
<EntityType Name="actItem_files">
|
<EntityType Name="actItem_files">
|
||||||
<Key>
|
<Key>
|
||||||
@@ -2972,7 +2975,7 @@
|
|||||||
<NavigationProperty Name="transfer_register" Relationship="Model.FK_transfer_register_followers" FromRole="follower" ToRole="transfer_register" />
|
<NavigationProperty Name="transfer_register" Relationship="Model.FK_transfer_register_followers" FromRole="follower" ToRole="transfer_register" />
|
||||||
<NavigationProperty Name="transfer_register1" Relationship="Model.FK_transfer_register_followers_match" FromRole="follower" ToRole="transfer_register" />
|
<NavigationProperty Name="transfer_register1" Relationship="Model.FK_transfer_register_followers_match" FromRole="follower" ToRole="transfer_register" />
|
||||||
<NavigationProperty Name="GuaDanOrder" Relationship="Model.FK_GuaDanOrder_Followers" FromRole="follower" ToRole="GuaDanOrder" />
|
<NavigationProperty Name="GuaDanOrder" Relationship="Model.FK_GuaDanOrder_Followers" FromRole="follower" ToRole="GuaDanOrder" />
|
||||||
<Property Name="search_keywords" Type="String" MaxLength="Max" FixedLength="false" Unicode="true" />
|
<Property Name="search_keywords" Type="String" MaxLength="Max" FixedLength="false" Unicode="false" />
|
||||||
<NavigationProperty Name="GuaDanOrderGuest" Relationship="Model.FK_GuaDanOrderGuest_FOLLOWERS" FromRole="follower" ToRole="GuaDanOrderGuest" />
|
<NavigationProperty Name="GuaDanOrderGuest" Relationship="Model.FK_GuaDanOrderGuest_FOLLOWERS" FromRole="follower" ToRole="GuaDanOrderGuest" />
|
||||||
</EntityType>
|
</EntityType>
|
||||||
<EntityType Name="followers_tablet">
|
<EntityType Name="followers_tablet">
|
||||||
@@ -3062,8 +3065,8 @@
|
|||||||
</Key>
|
</Key>
|
||||||
<Property Name="num" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
|
<Property Name="num" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
|
||||||
<Property Name="kind" Type="String" MaxLength="100" FixedLength="false" Unicode="true" />
|
<Property Name="kind" Type="String" MaxLength="100" FixedLength="false" Unicode="true" />
|
||||||
<Property Name="starttime" Type="Time" Precision="0" />
|
<Property Name="starttime" Type="Time" Precision="7" />
|
||||||
<Property Name="offtime" Type="Time" Precision="0" />
|
<Property Name="offtime" Type="Time" Precision="7" />
|
||||||
<Property Name="resttime" Type="Int32" />
|
<Property Name="resttime" Type="Int32" />
|
||||||
<Property Name="root" Type="Int32" />
|
<Property Name="root" Type="Int32" />
|
||||||
<Property Name="range" Type="Int32" />
|
<Property Name="range" Type="Int32" />
|
||||||
@@ -3188,6 +3191,7 @@
|
|||||||
<Property Name="UpdateTime" Type="DateTime" Precision="7" />
|
<Property Name="UpdateTime" Type="DateTime" Precision="7" />
|
||||||
<NavigationProperty Name="accountings" Relationship="Model.FK_accounting_pro_order_detail" FromRole="pro_order_detail" ToRole="accounting" />
|
<NavigationProperty Name="accountings" Relationship="Model.FK_accounting_pro_order_detail" FromRole="pro_order_detail" ToRole="accounting" />
|
||||||
<NavigationProperty Name="transfer_register" Relationship="Model.FK_transfer_register_pro_order_detail" FromRole="pro_order_detail" ToRole="transfer_register" />
|
<NavigationProperty Name="transfer_register" Relationship="Model.FK_transfer_register_pro_order_detail" FromRole="pro_order_detail" ToRole="transfer_register" />
|
||||||
|
<Property Name="style" Type="String" Unicode="false" FixedLength="false" MaxLength="50" Nullable="true" />
|
||||||
</EntityType>
|
</EntityType>
|
||||||
<EntityType Name="pro_order_record">
|
<EntityType Name="pro_order_record">
|
||||||
<Key>
|
<Key>
|
||||||
@@ -5334,6 +5338,10 @@
|
|||||||
<EntitySetMapping Name="actItems">
|
<EntitySetMapping Name="actItems">
|
||||||
<EntityTypeMapping TypeName="Model.actItem">
|
<EntityTypeMapping TypeName="Model.actItem">
|
||||||
<MappingFragment StoreEntitySet="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" />
|
||||||
<ScalarProperty Name="is_reconcile" ColumnName="is_reconcile" />
|
<ScalarProperty Name="is_reconcile" ColumnName="is_reconcile" />
|
||||||
<ScalarProperty Name="print_init" ColumnName="print_init" />
|
<ScalarProperty Name="print_init" ColumnName="print_init" />
|
||||||
<ScalarProperty Name="partno" ColumnName="partno" />
|
<ScalarProperty Name="partno" ColumnName="partno" />
|
||||||
@@ -5863,6 +5871,7 @@
|
|||||||
<ScalarProperty Name="demo" ColumnName="demo" />
|
<ScalarProperty Name="demo" ColumnName="demo" />
|
||||||
<ScalarProperty Name="customize_data" ColumnName="customize_data" />
|
<ScalarProperty Name="customize_data" ColumnName="customize_data" />
|
||||||
<ScalarProperty Name="printed_files" ColumnName="printed_files" />
|
<ScalarProperty Name="printed_files" ColumnName="printed_files" />
|
||||||
|
<ScalarProperty Name="style" ColumnName="style" />
|
||||||
</MappingFragment>
|
</MappingFragment>
|
||||||
</EntityTypeMapping>
|
</EntityTypeMapping>
|
||||||
</EntitySetMapping>
|
</EntitySetMapping>
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
<edmx:Designer xmlns="http://schemas.microsoft.com/ado/2009/11/edmx">
|
<edmx:Designer xmlns="http://schemas.microsoft.com/ado/2009/11/edmx">
|
||||||
<!-- Diagram content (shape and connector positions) -->
|
<!-- Diagram content (shape and connector positions) -->
|
||||||
<edmx:Diagrams>
|
<edmx:Diagrams>
|
||||||
<Diagram DiagramId="b267a343dc0c4bf0ae194b775754b108" Name="Diagram1" ZoomLevel="78">
|
<Diagram DiagramId="b267a343dc0c4bf0ae194b775754b108" Name="Diagram1" ZoomLevel="116">
|
||||||
<EntityTypeShape EntityType="Model.accounting" Width="1.5" PointX="22.5" PointY="22.125" IsExpanded="true" />
|
<EntityTypeShape EntityType="Model.accounting" Width="1.5" PointX="22.5" PointY="22.125" IsExpanded="true" />
|
||||||
<EntityTypeShape EntityType="Model.accounting_files" Width="1.5" PointX="15.75" PointY="27.75" IsExpanded="true" />
|
<EntityTypeShape EntityType="Model.accounting_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_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.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_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.actItem_kind" Width="1.5" PointX="6.125" PointY="7.875" IsExpanded="true" />
|
||||||
<EntityTypeShape EntityType="Model.activity" Width="1.5" PointX="3" PointY="8.875" IsExpanded="true" />
|
<EntityTypeShape EntityType="Model.activity" Width="1.5" PointX="3" PointY="8.875" IsExpanded="true" />
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
<EntityTypeShape EntityType="Model.activity_check" Width="1.5" PointX="5.25" PointY="18.5" IsExpanded="true" />
|
<EntityTypeShape EntityType="Model.activity_check" Width="1.5" PointX="5.25" PointY="18.5" IsExpanded="true" />
|
||||||
<EntityTypeShape EntityType="Model.activity_kind" Width="1.5" PointX="0.75" PointY="11.625" IsExpanded="true" />
|
<EntityTypeShape EntityType="Model.activity_kind" Width="1.5" PointX="0.75" PointY="11.625" IsExpanded="true" />
|
||||||
<EntityTypeShape EntityType="Model.activity_kind_detail" Width="1.5" PointX="13.5" PointY="3.875" IsExpanded="true" />
|
<EntityTypeShape EntityType="Model.activity_kind_detail" Width="1.5" PointX="13.5" PointY="3.875" IsExpanded="true" />
|
||||||
<EntityTypeShape EntityType="Model.activity_relating" Width="1.5" PointX="10.5" PointY="9.875" IsExpanded="true" />
|
<EntityTypeShape EntityType="Model.activity_relating" Width="1.5" PointX="11.25" PointY="9.875" IsExpanded="true" />
|
||||||
<EntityTypeShape EntityType="Model.activity_spares" Width="1.5" PointX="13.5" PointY="7.75" IsExpanded="true" />
|
<EntityTypeShape EntityType="Model.activity_spares" Width="1.5" PointX="13.5" PointY="7.75" IsExpanded="true" />
|
||||||
<EntityTypeShape EntityType="Model.admin" Width="1.5" PointX="6" PointY="1.375" IsExpanded="true" />
|
<EntityTypeShape EntityType="Model.admin" Width="1.5" PointX="6" PointY="1.375" IsExpanded="true" />
|
||||||
<EntityTypeShape EntityType="Model.admin_group" Width="1.5" PointX="3.75" PointY="3.625" IsExpanded="true" />
|
<EntityTypeShape EntityType="Model.admin_group" Width="1.5" PointX="3.75" PointY="3.625" IsExpanded="true" />
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace MyWeb
|
|||||||
public AdmItem info { get; set; }
|
public AdmItem info { get; set; }
|
||||||
|
|
||||||
//定義欄位cookie==================start
|
//定義欄位cookie==================start
|
||||||
public class AdmItem
|
public class AdmItem
|
||||||
{
|
{
|
||||||
public int num { get; set; }
|
public int num { get; set; }
|
||||||
public string u_id { get; set; }
|
public string u_id { get; set; }
|
||||||
|
|||||||
@@ -103,17 +103,18 @@ public class FollowerController : ApiController
|
|||||||
{
|
{
|
||||||
foreach (var item in prod)
|
foreach (var item in prod)
|
||||||
{
|
{
|
||||||
foreach (var item2 in item.pro_order_detail1)
|
//foreach (var item2 in item.pro_order_detail1)
|
||||||
item2.from_id = null; //清空訂單明細的陽上報恩者from_id //f_num設定串聯刪除
|
// item2.from_id = null; //清空訂單明細的陽上報恩者from_id //f_num設定串聯刪除
|
||||||
|
|
||||||
foreach (var item2 in item.pro_order)
|
//foreach (var item2 in item.pro_order)
|
||||||
item2.introducer = null;
|
// 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();
|
_db.SaveChanges();
|
||||||
|
|
||||||
Model.admin_log admin_log = new Model.admin_log();
|
Model.admin_log admin_log = new Model.admin_log();
|
||||||
@@ -150,8 +151,10 @@ public class FollowerController : ApiController
|
|||||||
qry = qry.Where(o => o.u_name.Contains(q.u_name.Trim()));
|
qry = qry.Where(o => o.u_name.Contains(q.u_name.Trim()));
|
||||||
if (q.birthday.HasValue)
|
if (q.birthday.HasValue)
|
||||||
qry = qry.Where(o => o.birthday >= q.birthday.Value);
|
qry = qry.Where(o => o.birthday >= q.birthday.Value);
|
||||||
if (q.birthday2.HasValue)
|
if (q.birthday2.HasValue) {
|
||||||
qry = qry.Where(o => o.birthday < Convert.ToDateTime(q.birthday2.Value).AddDays(1));
|
var tmpBirthday2 = Convert.ToDateTime(q.birthday2.Value).AddDays(1);
|
||||||
|
qry = qry.Where(o => o.birthday < tmpBirthday2);
|
||||||
|
}
|
||||||
if (!string.IsNullOrEmpty(q.address))
|
if (!string.IsNullOrEmpty(q.address))
|
||||||
qry = qry.Where(o => o.address !=null && o.address.Contains(q.address.Trim()));
|
qry = qry.Where(o => o.address !=null && o.address.Contains(q.address.Trim()));
|
||||||
//if (q.num.HasValue && q.num.Value>0)
|
//if (q.num.HasValue && q.num.Value>0)
|
||||||
@@ -655,8 +658,10 @@ public class FollowerController : ApiController
|
|||||||
list = orderrecord.Select(x => new
|
list = orderrecord.Select(x => new
|
||||||
{
|
{
|
||||||
orderno = x.order_no,
|
orderno = x.order_no,
|
||||||
startdate = x.reg_time,
|
//startdate = x.reg_time,
|
||||||
endtime = x.up_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(),
|
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(),
|
amount = x.pro_order_detail.Select(o => (float?)o.price).Sum(),
|
||||||
activityname = x.activity.subject,
|
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.Collections.Generic;
|
||||||
|
using System.Data.Entity;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Web.Http;
|
using System.Web.Http;
|
||||||
using PagedList;
|
using System.Web.Services;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using System.Collections;
|
|
||||||
using static TreeView;
|
using static TreeView;
|
||||||
using System.Data.Entity;
|
|
||||||
|
|
||||||
// api/activity
|
// api/activity
|
||||||
//[ezAuthorize(Roles = "admin")]//群組:*
|
//[ezAuthorize(Roles = "admin")]//群組:*
|
||||||
@@ -126,6 +130,12 @@ public class activityController : ApiController
|
|||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
////prod.IsDel = true; ////不確定是否新增欄位? 先註解
|
////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();
|
_db.SaveChanges();
|
||||||
Model.admin_log admin_log = new Model.admin_log();
|
Model.admin_log admin_log = new Model.admin_log();
|
||||||
MyWeb.admin admin = new MyWeb.admin();//api裡不可以用MyWeb
|
MyWeb.admin admin = new MyWeb.admin();//api裡不可以用MyWeb
|
||||||
@@ -190,12 +200,18 @@ public class activityController : ApiController
|
|||||||
if (prod.Count() > 0)
|
if (prod.Count() > 0)
|
||||||
{
|
{
|
||||||
//var prod2 = _db.actItem_files.AsEnumerable().Where(q => ids.Contains(Convert.ToInt32(q.actItem_num))).ToList();
|
//var prod2 = _db.actItem_files.AsEnumerable().Where(q => ids.Contains(Convert.ToInt32(q.actItem_num))).ToList();
|
||||||
var prod2 = _db.actItem_files.Where(q => ids.Contains(q.actItem_num)).ToList();
|
//var prod2 = _db.actItem_files.Where(q => ids.Contains(q.actItem_num)).ToList();
|
||||||
if (prod2.Count > 0)
|
//if (prod2.Count > 0)
|
||||||
{
|
//{
|
||||||
_db.actItem_files.RemoveRange(prod2);
|
// _db.actItem_files.RemoveRange(prod2);
|
||||||
//_db.SaveChanges();
|
// //_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.actItems.RemoveRange(prod);
|
||||||
_db.SaveChanges();
|
_db.SaveChanges();
|
||||||
@@ -282,6 +298,7 @@ public class activityController : ApiController
|
|||||||
|
|
||||||
var count = qry.Count(); //pageSize = count;//一次取回??
|
var count = qry.Count(); //pageSize = count;//一次取回??
|
||||||
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
|
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qryList.Select(x => new
|
list = qryList.Select(x => new
|
||||||
@@ -301,17 +318,48 @@ public class activityController : ApiController
|
|||||||
startDate_lunar = x.startDate_lunar,
|
startDate_lunar = x.startDate_lunar,
|
||||||
endDate_lunar = x.endDate_lunar,
|
endDate_lunar = x.endDate_lunar,
|
||||||
dueDate = x.dueDate,
|
dueDate = x.dueDate,
|
||||||
|
orderCounts= _db.pro_order.Where(y => y.activity_num == x.num).Count(),
|
||||||
|
}),
|
||||||
|
count = count,
|
||||||
|
|
||||||
}),
|
|
||||||
count = count
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
if (ret.list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
if (ret.list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
return Ok(ret);
|
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]
|
[HttpPost]
|
||||||
[Route("api/activity/GetItemList")]
|
[Route("api/activity/GetItemList")]
|
||||||
public IHttpActionResult GetItemList([FromBody] Model.ViewModel.actItem q, int page, int pageSize = 10,
|
public IHttpActionResult GetItemList([FromBody] Model.ViewModel.actItem q, int page, int pageSize = 10,
|
||||||
@@ -416,8 +464,14 @@ public class activityController : ApiController
|
|||||||
else
|
else
|
||||||
qry = qry.OrderBy(o => o.status);
|
qry = qry.OrderBy(o => o.status);
|
||||||
}
|
}
|
||||||
else
|
else if (sortBy.Equals("num"))
|
||||||
|
{
|
||||||
qry = qry.OrderByDescending(o => o.num);
|
qry = qry.OrderByDescending(o => o.num);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qry = qry.OrderByDescending(o => o.sort_order);
|
||||||
|
}
|
||||||
|
|
||||||
var tdesc = publicFun.enum_desc<Model.activity.category>();
|
var tdesc = publicFun.enum_desc<Model.activity.category>();
|
||||||
var count = qry.Count(); //pageSize = count;//一次取回??
|
var count = qry.Count(); //pageSize = count;//一次取回??
|
||||||
@@ -750,7 +804,7 @@ public class activityController : ApiController
|
|||||||
|
|
||||||
//已有值
|
//已有值
|
||||||
var count = qry.Count(); //pageSize = count;//一次取回??
|
var count = qry.Count(); //pageSize = count;//一次取回??
|
||||||
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
var qryList = (pageSize > 0) ? qry.OrderBy(a=>a.num).ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qryList.Select(x => new
|
list = qryList.Select(x => new
|
||||||
@@ -1301,7 +1355,7 @@ public class activityController : ApiController
|
|||||||
[Route("api/activity/OrderCheckIn")]
|
[Route("api/activity/OrderCheckIn")]
|
||||||
public IHttpActionResult OrderCheckIn([FromBody] Model.activity_check item)
|
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
|
Model.activity_check check = _db.activity_check
|
||||||
|
|||||||
@@ -0,0 +1,302 @@
|
|||||||
|
using Microsoft.Ajax.Utilities;
|
||||||
|
using MINOM.COM.Utility;
|
||||||
|
using Model;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// designerController 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
public class designerController : ApiController
|
||||||
|
{
|
||||||
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
public designerController()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: 在這裡新增建構函式邏輯
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/tablet/GetActItem")]
|
||||||
|
public IHttpActionResult GetActItem([FromBody] dynamic data)
|
||||||
|
{
|
||||||
|
LogUtility log = new LogUtility();
|
||||||
|
var json = data;
|
||||||
|
string itemNum = (json == null || json.itemNum == null) ? "" : (string)json.itemNum;
|
||||||
|
int num = int.Parse(itemNum);
|
||||||
|
var item=_db.actItems.AsQueryable().Where(x => x.num == num).FirstOrDefault();
|
||||||
|
return Ok(new { result = "Y", data =item});
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/tablet/GetTabletElement")]
|
||||||
|
public IHttpActionResult GetTabletElement([FromBody] dynamic data)
|
||||||
|
{
|
||||||
|
LogUtility log = new LogUtility();
|
||||||
|
var json = data;
|
||||||
|
string elementID = (json == null || json.elementID == null) ? "" : (string)json.elementID;
|
||||||
|
object[] obj = new StyleDataAccess().GetTabletElement(elementID, "");
|
||||||
|
if (obj[0].ToString() == "Y")
|
||||||
|
{
|
||||||
|
return Ok(new { result = "Y", data = obj[2] });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Ok(new { result = "N", message = obj[1] });
|
||||||
|
//throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
}
|
||||||
|
//return Ok(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/tablet/GetStyleDetailData")]
|
||||||
|
public IHttpActionResult GetStyleDetailData([FromBody] dynamic data)
|
||||||
|
{
|
||||||
|
LogUtility log = new LogUtility();
|
||||||
|
var json = data;
|
||||||
|
string styleID = (json == null || json.styleID == null) ? "" : (string)json.styleID;
|
||||||
|
object[] obj = new StyleDataAccess().GetStyleDetail(styleID, "");
|
||||||
|
if (obj[0].ToString() == "Y")
|
||||||
|
{
|
||||||
|
return Ok(new { result = "Y", data = obj[2] });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Ok(new { result = "N", message = obj[1] });
|
||||||
|
//throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
}
|
||||||
|
//return Ok(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/tablet/saveFamily")]
|
||||||
|
public IHttpActionResult saveFamily([FromBody] family_members familyMember)
|
||||||
|
{
|
||||||
|
LogUtility log = new LogUtility();
|
||||||
|
_db.family_members.Add(familyMember);
|
||||||
|
_db.SaveChanges();
|
||||||
|
return Ok(new { result = "Y", data= familyMember });
|
||||||
|
|
||||||
|
//object[] obj = new StyleDataAccess().GetStyle("", "");
|
||||||
|
//if (obj[0].ToString() == "Y")
|
||||||
|
//{
|
||||||
|
// return Ok(new { result = "Y", data = obj[2] });
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// return Ok(new { result = "N", message = obj[1] });
|
||||||
|
// //throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
//}
|
||||||
|
//return Ok(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/tablet/GetStyleData")]
|
||||||
|
public IHttpActionResult GetStyleData([FromBody] dynamic data)
|
||||||
|
{
|
||||||
|
LogUtility log = new LogUtility();
|
||||||
|
|
||||||
|
object[] obj = new StyleDataAccess().GetStyle("", "");
|
||||||
|
if (obj[0].ToString() == "Y")
|
||||||
|
{
|
||||||
|
return Ok(new { result = "Y", data = obj[2] });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Ok(new { result = "N", message = obj[1] });
|
||||||
|
//throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
}
|
||||||
|
//return Ok(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/tablet/SavDegignerData")]
|
||||||
|
public IHttpActionResult SavDegignerData([FromBody] dynamic data)
|
||||||
|
{
|
||||||
|
LogUtility log = new LogUtility();
|
||||||
|
var json = data;
|
||||||
|
//json.detail.Children<JObject>()
|
||||||
|
log.writeLogPath((string)json.styleName);
|
||||||
|
TabletStyle ts = new TabletStyle();
|
||||||
|
List<TabletStyleDetail> list = new List<TabletStyleDetail>();
|
||||||
|
ts.StyleID = (json == null || json.styleID == null) ? "" : (string)json.styleID;
|
||||||
|
string mode = "edit";
|
||||||
|
if (string.IsNullOrEmpty(ts.StyleID))
|
||||||
|
{
|
||||||
|
ts.StyleID = DateTime.Now.ToString("yyyyMMddHHmmss");
|
||||||
|
mode = "add";
|
||||||
|
}
|
||||||
|
ts.Name = (json == null || json.styleName == null) ? "" : (string)json.styleName;
|
||||||
|
ts.Descr = (json == null || json.descr == null) ? "" : (string)json.descr;
|
||||||
|
ts.PaperSize = (json == null || json.paperSize == null) ? "" : (string)json.paperSize;
|
||||||
|
ts.BackendImg = (json == null || json.backendImg == null) ? "" : (string)json.backendImg;
|
||||||
|
ts.PrintSize = (json == null || json.printSize == null) ? "" : (string)json.printSize;
|
||||||
|
ts.Orientation = (json == null || json.orientation == null) ? "" : (string)json.orientation;
|
||||||
|
ts.PrintPageCount = (json == null || json.printPageCount == null) ? "" : (string)json.printPageCount;
|
||||||
|
ts.PrintMode = (json == null || json.printMode == null) ? "" : (string)json.printMode;
|
||||||
|
ts.RosterLimit=(json == null || json.rosterLimit == null) ? "" : (string)json.rosterLimit;
|
||||||
|
foreach (var item in json.detail.Children<JObject>())
|
||||||
|
{
|
||||||
|
TabletStyleDetail tsd = new TabletStyleDetail();
|
||||||
|
tsd.StyleID = ts.StyleID;
|
||||||
|
tsd.Name = item.name == null ? "" : (string)item.name;
|
||||||
|
tsd.Descr = item.descr == null ? "" : (string)item.descr;
|
||||||
|
tsd.ElementID = item.elementID == null ? "" : (string)item.elementID;
|
||||||
|
tsd.StartX = item.startX == null ? "" : (string)item.startX;
|
||||||
|
tsd.StartY = item.startY == null ? "" : (string)item.startY;
|
||||||
|
tsd.FontSize = item.fontSize == null ? "" : (string)item.fontSize;
|
||||||
|
tsd.FontFamily = item.fontFamily == null ? "" : (string)item.fontFamily;
|
||||||
|
tsd.BreakLen = item.breakLen == null ? "" : (string)item.breakLen;
|
||||||
|
tsd.Width = item.width == null ? "" : (string)item.width;
|
||||||
|
tsd.Height = item.height == null ? "" : (string)item.height;
|
||||||
|
tsd.TextWidth = item.textWidth == null ? "" : (string)item.textWidth;
|
||||||
|
tsd.TextHeight = item.textHeight == null ? "" : (string)item.textHeight;
|
||||||
|
tsd.TwoOffset = item.twoOffset == null ? "" : (string)item.twoOffset;
|
||||||
|
tsd.ThreeOffset = item.threeOffset == null ? "" : (string)item.threeOffset;
|
||||||
|
tsd.FourOffset = item.fourOffset == null ? "" : (string)item.fourOffset;
|
||||||
|
tsd.IsActive = item.isActive == null ? "" : (string)item.isActive;
|
||||||
|
list.Add(tsd);
|
||||||
|
}
|
||||||
|
if (mode == "add")
|
||||||
|
{
|
||||||
|
object[] obj = new StyleDataAccess().AddStyle(ts, list);
|
||||||
|
if (obj[0].ToString() == "Y")
|
||||||
|
{
|
||||||
|
return Ok(new { result = "Y" });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Ok(new { result = "N" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/tablet/UpdateDegignerData")]
|
||||||
|
public IHttpActionResult UpdateDegignerData([FromBody] dynamic data)
|
||||||
|
{
|
||||||
|
LogUtility log = new LogUtility();
|
||||||
|
var json = data;
|
||||||
|
//json.detail.Children<JObject>()
|
||||||
|
log.writeLogPath((string)json.styleName);
|
||||||
|
TabletStyle ts = new TabletStyle();
|
||||||
|
List<TabletStyleDetail> list = new List<TabletStyleDetail>();
|
||||||
|
ts.StyleID = (json == null || json.styleID == null) ? "" : (string)json.styleID;
|
||||||
|
string mode = "edit";
|
||||||
|
if (string.IsNullOrEmpty(ts.StyleID))
|
||||||
|
{
|
||||||
|
ts.StyleID = DateTime.Now.ToString("yyyyMMddHHmmss");
|
||||||
|
mode = "add";
|
||||||
|
}
|
||||||
|
ts.Name = (json == null || json.styleName == null) ? "" : (string)json.styleName;
|
||||||
|
ts.Descr = (json == null || json.descr == null) ? "" : (string)json.descr;
|
||||||
|
ts.PaperSize = (json == null || json.paperSize == null) ? "" : (string)json.paperSize;
|
||||||
|
ts.BackendImg = (json == null || json.backendImg == null) ? "" : (string)json.backendImg;
|
||||||
|
ts.PrintSize = (json == null || json.printSize == null) ? "" : (string)json.printSize;
|
||||||
|
ts.Orientation = (json == null || json.orientation == null) ? "" : (string)json.orientation;
|
||||||
|
ts.PrintPageCount = (json == null || json.printPageCount == null) ? "" : (string)json.printPageCount;
|
||||||
|
ts.PrintMode = (json == null || json.printMode == null) ? "" : (string)json.printMode;
|
||||||
|
ts.RosterLimit = (json == null || json.rosterLimit == null) ? "" : (string)json.rosterLimit;
|
||||||
|
foreach (var item in json.detail.Children<JObject>())
|
||||||
|
{
|
||||||
|
TabletStyleDetail tsd = new TabletStyleDetail();
|
||||||
|
tsd.StyleID = ts.StyleID;
|
||||||
|
tsd.Name = item.name == null ? "" : (string)item.name;
|
||||||
|
tsd.Descr = item.descr == null ? "" : (string)item.descr;
|
||||||
|
tsd.ElementID = item.elementID == null ? "" : (string)item.elementID;
|
||||||
|
tsd.StartX = item.startX == null ? "" : (string)item.startX;
|
||||||
|
tsd.StartY = item.startY == null ? "" : (string)item.startY;
|
||||||
|
tsd.FontSize = item.fontSize == null ? "" : (string)item.fontSize;
|
||||||
|
tsd.FontFamily = item.fontFamily == null ? "" : (string)item.fontFamily;
|
||||||
|
tsd.BreakLen = item.breakLen == null ? "" : (string)item.breakLen;
|
||||||
|
tsd.Width = item.width == null ? "" : (string)item.width;
|
||||||
|
tsd.TwoOffset = item.twoOffset == null ? "" : (string)item.twoOffset;
|
||||||
|
tsd.ThreeOffset = item.threeOffset == null ? "" : (string)item.threeOffset;
|
||||||
|
tsd.FourOffset = item.fourOffset == null ? "" : (string)item.fourOffset;
|
||||||
|
tsd.IsActive = item.isActive == null ? "" : (string)item.isActive;
|
||||||
|
tsd.Width = item.width == null ? "" : (string)item.width;
|
||||||
|
tsd.Height = item.height == null ? "" : (string)item.height;
|
||||||
|
tsd.TextWidth = item.textWidth == null ? "" : (string)item.textWidth;
|
||||||
|
tsd.TextHeight = item.textHeight == null ? "" : (string)item.textHeight;
|
||||||
|
list.Add(tsd);
|
||||||
|
}
|
||||||
|
|
||||||
|
object[] obj = new StyleDataAccess().UpdateStyle(ts, list);
|
||||||
|
if (obj[0].ToString() == "Y")
|
||||||
|
{
|
||||||
|
return Ok(new { result = "Y" });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Ok(new { result = "N" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/tablet/GetPaperSize")]
|
||||||
|
public IHttpActionResult GetPaperSize([FromBody] dynamic data)
|
||||||
|
{
|
||||||
|
LogUtility log = new LogUtility();
|
||||||
|
|
||||||
|
object[] obj = new StyleDataAccess().GetTabletPaper("", "");
|
||||||
|
if (obj[0].ToString() == "Y")
|
||||||
|
{
|
||||||
|
return Ok(new { result = "Y", data = obj[2] });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Ok(new { result = "N", message = obj[1] });
|
||||||
|
//throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
}
|
||||||
|
//return Ok(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/tablet/SavePaperSize")]
|
||||||
|
public IHttpActionResult SavePaperSize([FromBody] dynamic data)
|
||||||
|
{
|
||||||
|
LogUtility log = new LogUtility();
|
||||||
|
var json = data;
|
||||||
|
//json.detail.Children<JObject>()
|
||||||
|
log.writeLogPath((string)json.styleName);
|
||||||
|
TabletPaperSize tps = new TabletPaperSize();
|
||||||
|
tps.PaperID = (json == null || json.paperID == null) ? "" : (string)json.paperID;
|
||||||
|
if (string.IsNullOrEmpty(tps.PaperID))
|
||||||
|
{
|
||||||
|
tps.PaperID = DateTime.Now.ToString("yyyyMMddHHmmss");
|
||||||
|
}
|
||||||
|
tps.PaperName = (json == null || json.paperName == null) ? "" : (string)json.paperName;
|
||||||
|
tps.Width = (json == null || json.width == null) ? "" : (string)json.width;
|
||||||
|
tps.Height = (json == null || json.height == null) ? "" : (string)json.height;
|
||||||
|
tps.CUser = "";
|
||||||
|
tps.CDate = DateTime.Now.ToString("yyyyMMdd");
|
||||||
|
tps.CTime = DateTime.Now.ToString("HHmmss");
|
||||||
|
tps.UUser = "";
|
||||||
|
tps.UDate = DateTime.Now.ToString("yyyyMMdd");
|
||||||
|
tps.UTime = DateTime.Now.ToString("HHmmss");
|
||||||
|
|
||||||
|
object[] obj = new StyleDataAccess().AddTabletPaper(tps);
|
||||||
|
if (obj[0].ToString()=="Y")
|
||||||
|
{
|
||||||
|
return Ok(new { result = "Y" });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Ok(new { result = "N"});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,17 +1,19 @@
|
|||||||
using System;
|
using DocumentFormat.OpenXml.Drawing.Charts;
|
||||||
|
using Model;
|
||||||
|
using MyWeb;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using PagedList;
|
||||||
|
using System;
|
||||||
|
using System.Activities.Expressions;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IdentityModel.Metadata;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Web.Http;
|
using System.Web.Http;
|
||||||
using PagedList;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using System.Collections;
|
|
||||||
using static TreeView;
|
using static TreeView;
|
||||||
using Model;
|
|
||||||
using System.IdentityModel.Metadata;
|
|
||||||
using MyWeb;
|
|
||||||
using DocumentFormat.OpenXml.Drawing.Charts;
|
|
||||||
|
|
||||||
|
|
||||||
// api/order
|
// api/order
|
||||||
@@ -206,7 +208,7 @@ public class orderController : ApiController
|
|||||||
string sortBy = "", bool sortDesc = false)
|
string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
|
|
||||||
var qry = _db.pro_order.AsQueryable();
|
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);//品項
|
//var aIDt = _db.actItems.AsEnumerable().Where(f => f.subject.Contains(q.actItemTxt.Trim())).Select(f => f.num);//品項
|
||||||
|
|
||||||
|
|
||||||
@@ -221,7 +223,10 @@ public class orderController : ApiController
|
|||||||
if (q.up_time1.HasValue)
|
if (q.up_time1.HasValue)
|
||||||
qry = qry.Where(o => o.up_time >= q.up_time1.Value);
|
qry = qry.Where(o => o.up_time >= q.up_time1.Value);
|
||||||
if (q.up_time2.HasValue)
|
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))
|
if (!string.IsNullOrEmpty(q.address))
|
||||||
qry = qry.Where(o => o.address.Contains(q.address.Trim()));
|
qry = qry.Where(o => o.address.Contains(q.address.Trim()));
|
||||||
if (!string.IsNullOrEmpty(q.subject))
|
if (!string.IsNullOrEmpty(q.subject))
|
||||||
@@ -291,6 +296,13 @@ public class orderController : ApiController
|
|||||||
else
|
else
|
||||||
qry = qry.OrderBy(o => o.activity != null ? o.activity.subject : "");
|
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
|
else
|
||||||
qry = qry.OrderByDescending(o => o.reg_time);
|
qry = qry.OrderByDescending(o => o.reg_time);
|
||||||
|
|
||||||
@@ -307,6 +319,7 @@ public class orderController : ApiController
|
|||||||
keyin1 = x.keyin1,
|
keyin1 = x.keyin1,
|
||||||
up_time = x.up_time,
|
up_time = x.up_time,
|
||||||
keyin1_txt = Model.pro_order.keyin1_value_to_text(x.keyin1),
|
keyin1_txt = Model.pro_order.keyin1_value_to_text(x.keyin1),
|
||||||
|
status = x.activity.activity_check.FirstOrDefault(a => x.activity_num == a.activity_num && x.f_num == a.f_num)?.status ?? 0,
|
||||||
}),
|
}),
|
||||||
count = count
|
count = count
|
||||||
};
|
};
|
||||||
@@ -447,6 +460,7 @@ public class orderController : ApiController
|
|||||||
? x.num.ToString()
|
? x.num.ToString()
|
||||||
: (x.parent_num.ToString() + x.num.ToString())
|
: (x.parent_num.ToString() + x.num.ToString())
|
||||||
),
|
),
|
||||||
|
style=x.style??""
|
||||||
//cash_record = x.pro_order_record.Select( c => new {
|
//cash_record = x.pro_order_record.Select( c => new {
|
||||||
// c,
|
// c,
|
||||||
// //pay_kind = tdesc2[c.payment.HasValue && x.keyin1.Value > 0 ? x.keyin1.Value : 1],
|
// //pay_kind = tdesc2[c.payment.HasValue && x.keyin1.Value > 0 ? x.keyin1.Value : 1],
|
||||||
@@ -712,6 +726,7 @@ public class orderController : ApiController
|
|||||||
order.demo = item.demo;
|
order.demo = item.demo;
|
||||||
order.customize_data = item.customize_data;
|
order.customize_data = item.customize_data;
|
||||||
order.UpdateTime = DateTime.Now;
|
order.UpdateTime = DateTime.Now;
|
||||||
|
order.style = item.style;
|
||||||
_db.SaveChanges();
|
_db.SaveChanges();
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
@@ -765,6 +780,7 @@ public class orderController : ApiController
|
|||||||
demo = item.demo,
|
demo = item.demo,
|
||||||
customize_data = item.customize_data,
|
customize_data = item.customize_data,
|
||||||
UpdateTime = DateTime.Now,
|
UpdateTime = DateTime.Now,
|
||||||
|
style=item.style
|
||||||
};
|
};
|
||||||
_db.pro_order_detail.Add(orderDetail);
|
_db.pro_order_detail.Add(orderDetail);
|
||||||
_db.SaveChanges();
|
_db.SaveChanges();
|
||||||
|
|||||||
@@ -1,14 +1,18 @@
|
|||||||
using System;
|
using com.itextpdf.text.pdf;
|
||||||
|
using Model;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using PagedList;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Data.Entity;
|
||||||
|
using System.Data.SqlClient;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Web.Http;
|
using System.Web.Http;
|
||||||
using PagedList;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using System.Collections;
|
|
||||||
using static TreeView;
|
using static TreeView;
|
||||||
using System.Data.Entity;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// orderdetail 的摘要说明
|
/// orderdetail 的摘要说明
|
||||||
@@ -59,4 +63,39 @@ public class orderdetailController:ApiController
|
|||||||
if (ret.list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
if (ret.list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
return Ok(ret);
|
return Ok(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/orderdetail/GetDetailToPrint")]
|
||||||
|
public IHttpActionResult GetDetailToPrint([FromBody] dynamic data)
|
||||||
|
{
|
||||||
|
if (data.param is Newtonsoft.Json.Linq.JArray items)
|
||||||
|
{
|
||||||
|
string[] details = new string[items.Count];
|
||||||
|
int i = 0;
|
||||||
|
foreach (var item in items)
|
||||||
|
{
|
||||||
|
details[i] = item["order_no"] + item["num"].ToString();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
var parameters = details.Select((s,j)=>"@p"+j).ToArray();
|
||||||
|
string sql = $"select * from pro_order_detail where order_no+convert(varchar,num) in ({string.Join(",",parameters)}) ";
|
||||||
|
|
||||||
|
int l =0;
|
||||||
|
List<SqlParameter> sqlList = new List<SqlParameter>();
|
||||||
|
foreach (var item in details)
|
||||||
|
{
|
||||||
|
sqlList.Add( new SqlParameter("@p" + l, item));
|
||||||
|
l++;
|
||||||
|
}
|
||||||
|
SqlParameter[] p = sqlList.ToArray();
|
||||||
|
var ret = _db.Database.SqlQuery<pro_order_detail>(sql, p).ToList();
|
||||||
|
if (ret == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,7 @@ using System.Collections;
|
|||||||
using MyWeb;
|
using MyWeb;
|
||||||
using System.Web.WebPages;
|
using System.Web.WebPages;
|
||||||
using System.Data.Entity;
|
using System.Data.Entity;
|
||||||
|
using Model;
|
||||||
|
|
||||||
[ezAuthorize]
|
[ezAuthorize]
|
||||||
public class transfer_registerController : ApiController
|
public class transfer_registerController : ApiController
|
||||||
@@ -269,6 +270,7 @@ public class transfer_registerController : ApiController
|
|||||||
public string check_memo { get; set; }
|
public string check_memo { get; set; }
|
||||||
public string draft { get; set; }
|
public string draft { get; set; }
|
||||||
public int? acc_kind { get; set; } // 新增關聯欄位
|
public int? acc_kind { get; set; } // 新增關聯欄位
|
||||||
|
public int? kind { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
@@ -315,7 +317,7 @@ public class transfer_registerController : ApiController
|
|||||||
{
|
{
|
||||||
uptime = dto.check_date,
|
uptime = dto.check_date,
|
||||||
category = 1, // 收入
|
category = 1, // 收入
|
||||||
kind = 27, // 固定值:法會收入/功德項目
|
kind = dto.kind,//27, // 固定值:法會收入/功德項目
|
||||||
kind2 = dto.acc_num,
|
kind2 = dto.acc_num,
|
||||||
price = (float)(dto.check_amount ?? 0),
|
price = (float)(dto.check_amount ?? 0),
|
||||||
tax = 0,
|
tax = 0,
|
||||||
@@ -346,6 +348,7 @@ public class transfer_registerController : ApiController
|
|||||||
item.check_memo = dto.check_memo;
|
item.check_memo = dto.check_memo;
|
||||||
item.draft = dto.draft;
|
item.draft = dto.draft;
|
||||||
item.acc_kind = dto.acc_kind;
|
item.acc_kind = dto.acc_kind;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_db.SaveChanges();
|
_db.SaveChanges();
|
||||||
@@ -958,7 +961,10 @@ public class transfer_registerController : ApiController
|
|||||||
activity_name = x.activity != null ? x.activity.subject : "",
|
activity_name = x.activity != null ? x.activity.subject : "",
|
||||||
activity_num = x.activity_num,
|
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() : "",
|
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_record 資訊 (透過 transfer_id 關聯)
|
||||||
pro_order_records = x.pro_order_record.Select(pr => new {
|
pro_order_records = x.pro_order_record.Select(pr => new {
|
||||||
pr.num,
|
pr.num,
|
||||||
@@ -1275,3 +1281,22 @@ 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,7 +8,7 @@
|
|||||||
<LastUsedPlatform>Any CPU</LastUsedPlatform>
|
<LastUsedPlatform>Any CPU</LastUsedPlatform>
|
||||||
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
|
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
|
||||||
<PublishProvider>FileSystem</PublishProvider>
|
<PublishProvider>FileSystem</PublishProvider>
|
||||||
<PublishUrl>D:\17168web</PublishUrl>
|
<PublishUrl>C:\17168web</PublishUrl>
|
||||||
<WebPublishMethod>FileSystem</WebPublishMethod>
|
<WebPublishMethod>FileSystem</WebPublishMethod>
|
||||||
<_TargetId>Folder</_TargetId>
|
<_TargetId>Folder</_TargetId>
|
||||||
<SiteUrlToLaunchAfterPublish />
|
<SiteUrlToLaunchAfterPublish />
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
<link href="~/js/sweetalert2/sweetalert2.min.css" rel="stylesheet" />
|
<link href="~/js/sweetalert2/sweetalert2.min.css" rel="stylesheet" />
|
||||||
|
|
||||||
<link href="~/admin/Templates/TBS5ADM001/css/Style.css" rel="stylesheet" />
|
<link href="~/admin/Templates/TBS5ADM001/css/Style.css" rel="stylesheet" />
|
||||||
|
<link href="~/admin/item/css/floating.css" rel="stylesheet" />
|
||||||
|
<link href="~/admin/item/css/tablet-design.css" rel="stylesheet" />
|
||||||
<asp:ContentPlaceHolder id="page_header" runat="server">
|
<asp:ContentPlaceHolder id="page_header" runat="server">
|
||||||
</asp:ContentPlaceHolder>
|
</asp:ContentPlaceHolder>
|
||||||
</head>
|
</head>
|
||||||
@@ -67,14 +69,14 @@
|
|||||||
let HTTP_HOST = "<%=UrlHost()%>";
|
let HTTP_HOST = "<%=UrlHost()%>";
|
||||||
</script>
|
</script>
|
||||||
<script src="<%=ResolveUrl("~/js/bootstrap5/js/bootstrap.bundle.min.js")%>"></script>
|
<script src="<%=ResolveUrl("~/js/bootstrap5/js/bootstrap.bundle.min.js")%>"></script>
|
||||||
<script src="<%=ResolveUrl("~/js/jquery-3.6.0.min.js")%>"></script>
|
<script src="<%=ResolveUrl("~/js/jquery-4.0.0.min.js")%>"></script>
|
||||||
<script src="<%=ResolveUrl("~/js/vue.min.js")%>"></script>
|
<script src="<%=ResolveUrl("~/js/vue.min.js")%>"></script>
|
||||||
<script src="<%=ResolveUrl("~/js/vuetify.min.js")%>"></script>
|
<script src="<%=ResolveUrl("~/js/vuetify.min.js")%>"></script>
|
||||||
<script src="<%=ResolveUrl("~/js/axios.min.js")%>"></script>
|
<script src="<%=ResolveUrl("~/js/axios.min.js")%>"></script>
|
||||||
<script src="<%=ResolveUrl("~/js/moment.min.js")%>"></script>
|
<script src="<%=ResolveUrl("~/js/moment.min.js")%>"></script>
|
||||||
<script src="<%=ResolveUrl("~/js/sweetalert2/sweetalert2.all.min.js") %>"></script>
|
<script src="<%=ResolveUrl("~/js/sweetalert2/sweetalert2.all.min.js") %>"></script>
|
||||||
<script src="<%=ResolveUrl("~/admin/Templates/TBS5ADM001/js/Script.js")%>"></script>
|
<script src="<%=ResolveUrl("~/admin/Templates/TBS5ADM001/js/Script.js")%>"></script>
|
||||||
|
<script src="<%=ResolveUrl("~/admin/item/jquery-ui/jquery-ui.min.js")%>"></script>
|
||||||
<script>
|
<script>
|
||||||
//全局的VUE組件,操作提示組件
|
//全局的VUE組件,操作提示組件
|
||||||
Vue.component('message-modal', {
|
Vue.component('message-modal', {
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
<asp:Repeater ID="Repeater2" runat="server" OnItemDataBound="Repeater2_ItemDataBound">
|
<asp:Repeater ID="Repeater2" runat="server" OnItemDataBound="Repeater2_ItemDataBound">
|
||||||
<ItemTemplate>
|
<ItemTemplate>
|
||||||
<a class="nav-link" href="<%#ResolveUrl(ValString(Eval("url"))) %>"
|
<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") %>">
|
target="<%#(ValString(Eval("target"))=="B"?"_blank":"_self") %>">
|
||||||
<%#Eval("title") %></a>
|
<%#Eval("title") %></a>
|
||||||
</ItemTemplate>
|
</ItemTemplate>
|
||||||
|
|||||||
+202
-101
@@ -7,19 +7,20 @@
|
|||||||
<div class="mb-2 mb-sm-0">
|
<div class="mb-2 mb-sm-0">
|
||||||
<ul class="nav ps-0">
|
<ul class="nav ps-0">
|
||||||
<li class="nav-item pe-3">
|
<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 value="">選擇分類</option>
|
||||||
<option v-for="item in itemKindList" :value="item.num">{{item.kind}}</option>
|
<option v-for="item in itemKindList" :value="item.num">{{item.kind}}</option>
|
||||||
</select>
|
</select>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item pe-1">
|
<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>新增
|
<i class="mdi mdi-plus"></i>新增
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</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 class="nav-item pe-1">
|
||||||
</li>
|
<a @click="deleteAll" class="btn btn-outline-danger" title="刪除勾選的資料" :class="{ 'disabled': isEditing }" ><i class="mdi mdi-trash-can"></i> 刪除勾選</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<%-- <div class="input-group mb-3" data-search-control="search1" @click="search_show(search_dialog.controls.search1)">
|
<%-- <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
|
<input class="form-control search-text" type="text" readonly
|
||||||
@@ -30,25 +31,30 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>--%>
|
</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;">
|
||||||
|
|
||||||
</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> </div>
|
||||||
</asp:Content>
|
</asp:Content>
|
||||||
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" runat="Server">
|
<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>
|
<script>
|
||||||
Vue.filter('timeString', function (value, myFormat) {
|
Vue.filter('timeString', function (value, myFormat) {
|
||||||
return value == null || value == "" ? "" : moment(value).format(myFormat || 'YYYY-MM-DD, HH:mm:ss');
|
return value == null || value == "" ? "" : moment(value).format(myFormat || 'YYYY-MM-DD, HH:mm:ss');
|
||||||
});
|
});
|
||||||
|
|
||||||
let VueApp=new Vue({
|
let VueApp = new Vue({
|
||||||
el: '#app',
|
el: '#app',
|
||||||
vuetify: new Vuetify(vuetify_options),
|
vuetify: new Vuetify(vuetify_options),
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
isEditing: false,
|
||||||
options: { multiSort: false },
|
options: { multiSort: false },
|
||||||
data_table: {
|
data_table: {
|
||||||
loading: true,
|
loading: true,
|
||||||
@@ -68,15 +74,15 @@
|
|||||||
{ text: '', value: 'slot_btn', sortable: false, align: 'end' },
|
{ text: '', value: 'slot_btn', sortable: false, align: 'end' },
|
||||||
|
|
||||||
],
|
],
|
||||||
footer:{
|
footer: {
|
||||||
showFirstLastPage: true,
|
showFirstLastPage: true,
|
||||||
itemsPerPageOptions:[5,10,20,30],
|
itemsPerPageOptions: [5, 10, 20, 30],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
search: {
|
search: {
|
||||||
kind: '',
|
kind: '',
|
||||||
subject: '',
|
subject: '',
|
||||||
selltime1:'',
|
selltime1: '',
|
||||||
selltime2: '',
|
selltime2: '',
|
||||||
uptime1: '',
|
uptime1: '',
|
||||||
uptime2: '',
|
uptime2: '',
|
||||||
@@ -98,7 +104,7 @@
|
|||||||
{ id: 'kind', title: '品項分類', value: '' },
|
{ id: 'kind', title: '品項分類', value: '' },
|
||||||
],
|
],
|
||||||
selected: {},
|
selected: {},
|
||||||
select(t,data) {
|
select(t, data) {
|
||||||
data.search.kind = t.num;
|
data.search.kind = t.num;
|
||||||
data.btn_search()
|
data.btn_search()
|
||||||
console.log("select search1", t);
|
console.log("select search1", t);
|
||||||
@@ -120,9 +126,9 @@
|
|||||||
}, snackbar: {
|
}, snackbar: {
|
||||||
show: false,
|
show: false,
|
||||||
text: "",
|
text: "",
|
||||||
}, itemKindList:{
|
}, itemKindList: {
|
||||||
num: 0,
|
num: 0,
|
||||||
kind:''
|
kind: ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -174,20 +180,39 @@
|
|||||||
|
|
||||||
},
|
},
|
||||||
getDefault(clearpage = false) {
|
getDefault(clearpage = false) {
|
||||||
const { sortBy, sortDesc, page, itemsPerPage } = this.options
|
if (this.isEditing) {
|
||||||
const params = {
|
const { sortBy, sortDesc, page, itemsPerPage } = this.options
|
||||||
sortBy: sortBy[0], sortDesc: sortDesc[0],
|
const params = {
|
||||||
page: clearpage ? '1' :page, pageSize: itemsPerPage
|
sortBy: "sort_order", sortDesc: sortDesc[0],
|
||||||
};
|
page: clearpage ? '1' : page, pageSize: 0
|
||||||
this.data_table.loading = true
|
};
|
||||||
axios
|
this.data_table.loading = true
|
||||||
.post(HTTP_HOST + 'api/activity/GetItemList', this.search, { params: params })
|
axios
|
||||||
.then(response => {
|
.post(HTTP_HOST + 'api/activity/GetItemList', this.search, { params: params })
|
||||||
this.data_table.list = response.data.list
|
.then(response => {
|
||||||
this.data_table.count = response.data.count;
|
this.data_table.list = response.data.list
|
||||||
this.data_table.loading = false
|
this.data_table.count = response.data.count;
|
||||||
})
|
this.data_table.loading = false
|
||||||
.catch(error => console.log(error))
|
})
|
||||||
|
.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))
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
editItem(item) {
|
editItem(item) {
|
||||||
console.log("edit", item);
|
console.log("edit", item);
|
||||||
@@ -225,6 +250,29 @@
|
|||||||
.catch(error => console.log(error))
|
.catch(error => console.log(error))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
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() {
|
btn_search() {
|
||||||
this.getDefault(true)
|
this.getDefault(true)
|
||||||
},
|
},
|
||||||
@@ -232,86 +280,115 @@
|
|||||||
clearObjProps(this.search);
|
clearObjProps(this.search);
|
||||||
this.btn_search()
|
this.btn_search()
|
||||||
},
|
},
|
||||||
//===
|
//===
|
||||||
search_show(curr) {
|
search_show(curr) {
|
||||||
//console.log("btn_click:", curr, curr.api_url);
|
//console.log("btn_click:", curr, curr.api_url);
|
||||||
this.search_dialog.current = curr;
|
this.search_dialog.current = curr;
|
||||||
this.search_clear()
|
this.search_clear()
|
||||||
//this.search_get()//清除完自動會重抓, 故取消
|
//this.search_get()//清除完自動會重抓, 故取消
|
||||||
this.search_dialog.show = true;
|
this.search_dialog.show = true;
|
||||||
},
|
},
|
||||||
search_clear() {
|
search_clear() {
|
||||||
if (!this.search_dialog.current.keys) return;
|
if (!this.search_dialog.current.keys) return;
|
||||||
this.search_dialog.current.keys.forEach((t, i) => { t.value = '' })
|
this.search_dialog.current.keys.forEach((t, i) => { t.value = '' })
|
||||||
this.search_get()
|
this.search_get()
|
||||||
},
|
},
|
||||||
search_get() {
|
search_get() {
|
||||||
if (!this.search_dialog.current.keys) return;
|
if (!this.search_dialog.current.keys) return;
|
||||||
let api_url = this.search_dialog.current.api_url;
|
let api_url = this.search_dialog.current.api_url;
|
||||||
let keys = this.search_dialog.current.keys;
|
let keys = this.search_dialog.current.keys;
|
||||||
//const { page, itemsPerPage } = this.options
|
//const { page, itemsPerPage } = this.options
|
||||||
//const { sortBy, sortDesc, page, itemsPerPage } = this.options
|
//const { sortBy, sortDesc, page, itemsPerPage } = this.options
|
||||||
this.search_dialog.page = this.options.page ?? 1
|
this.search_dialog.page = this.options.page ?? 1
|
||||||
let params = { page: this.search_dialog.page, pageSize: 10 };//url params
|
let params = { page: this.search_dialog.page, pageSize: 10 };//url params
|
||||||
var search = {};//post body
|
var search = {};//post body
|
||||||
keys.forEach((t, i) => {
|
keys.forEach((t, i) => {
|
||||||
search[t.id] = t.value;
|
search[t.id] = t.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("search_get", api_url, search, params, this.options);
|
console.log("search_get", api_url, search, params, this.options);
|
||||||
this.search_dialog.loading = true
|
this.search_dialog.loading = true
|
||||||
axios.post(api_url, search, { params: params })
|
axios.post(api_url, search, { params: params })
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.search_dialog.list = response.data.list
|
this.search_dialog.list = response.data.list
|
||||||
this.search_dialog.count = response.data.count
|
this.search_dialog.count = response.data.count
|
||||||
this.search_dialog.loading = false
|
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 => {
|
return r
|
||||||
console.log(error)
|
},
|
||||||
this.search_dialog.list = []
|
search_select(row) {
|
||||||
this.search_dialog.count = 0
|
let curr = this.search_dialog.current;
|
||||||
this.search_dialog.loading = false
|
let target = $(`[data-search-control=${curr.id}]`);
|
||||||
this.snackbar.text = "錯誤:" + error
|
curr.selected = row;
|
||||||
this.snackbar.show = true
|
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) {
|
||||||
search_headers() {
|
curr.select(row, this);
|
||||||
if (!this.search_dialog.current.columns) return;
|
}
|
||||||
r = [];
|
this.search_dialog.show = false;
|
||||||
this.search_dialog.current.columns.forEach((t, i) => {
|
},
|
||||||
r.push({
|
saveOrder(event) {
|
||||||
text: t.title,
|
const movedItem = this.data_table.list.splice(event.oldIndex, 1)[0];
|
||||||
align: 'start',
|
this.data_table.list.splice(event.newIndex, 0, movedItem);
|
||||||
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;
|
|
||||||
},
|
|
||||||
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
pageCount() {
|
pageCount() {
|
||||||
return Math.ceil(this.data_table.count / this.data_table.pageSize)
|
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: {
|
filters: {
|
||||||
currency: function (value) {
|
currency: function (value) {
|
||||||
return value == null || value == "" ? "" :
|
return value == null || value == "" ? "" :
|
||||||
('$' + parseFloat(value).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1,").replace(".00", ""));
|
('$' + 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>
|
</script>
|
||||||
</asp:Content>
|
</asp:Content>
|
||||||
@@ -319,6 +396,9 @@
|
|||||||
<uc1:alert runat="server" ID="L_msg" Text="" />
|
<uc1:alert runat="server" ID="L_msg" Text="" />
|
||||||
<div id="content" class="container-fluid">
|
<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"
|
v-model="data_table.selected"
|
||||||
:items="data_table.list"
|
:items="data_table.list"
|
||||||
:search-props="search"
|
:search-props="search"
|
||||||
@@ -332,8 +412,29 @@
|
|||||||
show-select
|
show-select
|
||||||
hide-default-footer
|
hide-default-footer
|
||||||
:page.sync="data_table.page"
|
:page.sync="data_table.page"
|
||||||
:items-per-page.sync="data_table.pageSize"
|
:items-per-page.sync= "isEditing ? -1 :data_table.pageSize"
|
||||||
class="elevation-1">
|
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 }" >
|
<template #item.price="{ item }" >
|
||||||
{{item.price | currency }}
|
{{item.price | currency }}
|
||||||
</template>
|
</template>
|
||||||
@@ -352,12 +453,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<template #item.slot_btn="{ item }">
|
<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 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 @click="deleteItem(item)" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-trash-can"></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>
|
</template>
|
||||||
</v-data-table>
|
</v-data-table>
|
||||||
<v-container>
|
<v-container v-if="!isEditing">
|
||||||
<v-row class="align-baseline" wrap>
|
<v-row class="align-baseline" wrap>
|
||||||
<v-col cols="12" md="9">
|
<v-col cols="12" md="9">
|
||||||
<v-pagination
|
<v-pagination
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ public partial class admin_activity_index2 : MyWeb.config
|
|||||||
}
|
}
|
||||||
|
|
||||||
var tdesc = publicFun.enum_desc<Model.activity.category>();
|
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();
|
var list = qry.ToList();
|
||||||
if (list.Count > 0)
|
if (list.Count > 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
this_id: '<%= Request["num"] %>',
|
this_id: '<%= Request["num"] %>',
|
||||||
|
paperlist: [],
|
||||||
|
stylelist: [],
|
||||||
options: {},
|
options: {},
|
||||||
optionsDetail: {
|
optionsDetail: {
|
||||||
multiSort: false,
|
multiSort: false,
|
||||||
@@ -43,7 +45,7 @@
|
|||||||
{ id: 'kind', title: '分類名稱' },
|
{ id: 'kind', title: '分類名稱' },
|
||||||
],
|
],
|
||||||
selected: {},
|
selected: {},
|
||||||
select(item,t) {
|
select(item, t) {
|
||||||
console.log("select search1", t);
|
console.log("select search1", t);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -60,7 +62,7 @@
|
|||||||
{ id: 'subject', title: '文件名稱' },
|
{ id: 'subject', title: '文件名稱' },
|
||||||
],
|
],
|
||||||
selected: {},
|
selected: {},
|
||||||
select(item,t) {
|
select(item, t) {
|
||||||
console.log("select search2", t);
|
console.log("select search2", t);
|
||||||
|
|
||||||
item.files_num_selected.text = t.subject //=====?
|
item.files_num_selected.text = t.subject //=====?
|
||||||
@@ -71,26 +73,26 @@
|
|||||||
id: 'search3',
|
id: 'search3',
|
||||||
title: '子項目',
|
title: '子項目',
|
||||||
text_prop: 'subject',
|
text_prop: 'subject',
|
||||||
value_prop: 'num',
|
value_prop: 'num',
|
||||||
keys: [
|
keys: [
|
||||||
{ id: 'subject', title: '項目名稱', value: '' },
|
{ id: 'subject', title: '項目名稱', value: '' },
|
||||||
{ id: 'kindTxt', title: '項目分類' },
|
{ id: 'kindTxt', title: '項目分類' },
|
||||||
],
|
],
|
||||||
api_url: HTTP_HOST + 'api/activity/GetItemList',
|
api_url: HTTP_HOST + 'api/activity/GetItemList',
|
||||||
columns: [
|
columns: [
|
||||||
{ id: 'subject', title: '項目名稱', value: '' },
|
{ id: 'subject', title: '項目名稱', value: '' },
|
||||||
{ id: 'kindTxt', title: '項目分類' },
|
{ id: 'kindTxt', title: '項目分類' },
|
||||||
],
|
],
|
||||||
selected: {},
|
selected: {},
|
||||||
select(item,t) {
|
select(item, t) {
|
||||||
console.log("select search3", item, t);
|
console.log("select search3", item, t);
|
||||||
//debugger;
|
//debugger;
|
||||||
item.actItem.subject = t.subject
|
item.actItem.subject = t.subject
|
||||||
item.actItem.num = t.num
|
item.actItem.num = t.num
|
||||||
item.item_num_selected={
|
item.item_num_selected = {
|
||||||
text: t.subject,
|
text: t.subject,
|
||||||
val : t.num
|
val: t.num
|
||||||
}
|
}
|
||||||
// item.bom_editedItem.actItem.subject = t.subject
|
// item.bom_editedItem.actItem.subject = t.subject
|
||||||
// item.bom_editedItem.actItem.num = t.num
|
// item.bom_editedItem.actItem.num = t.num
|
||||||
|
|
||||||
@@ -98,8 +100,8 @@
|
|||||||
// text : t.subject,
|
// text : t.subject,
|
||||||
// val = t.num
|
// val = t.num
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
////新增/修改+關閉時, 會清空/還原
|
////新增/修改+關閉時, 會清空/還原
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
@@ -243,8 +245,8 @@
|
|||||||
});
|
});
|
||||||
//necessary parameter===
|
//necessary parameter===
|
||||||
if (this.search_dialog.current.id == 'search1') {
|
if (this.search_dialog.current.id == 'search1') {
|
||||||
if (this.this_id=="")
|
if (this.this_id == "")
|
||||||
search['status'] = "Y";//啟用
|
search['status'] = "Y";//啟用
|
||||||
}
|
}
|
||||||
console.log("search_get", api_url, search, params, this.options);
|
console.log("search_get", api_url, search, params, this.options);
|
||||||
this.search_dialog.loading = true
|
this.search_dialog.loading = true
|
||||||
@@ -292,7 +294,7 @@
|
|||||||
target.children("input.search-text").val(curr.selected[curr.text_prop])//text
|
target.children("input.search-text").val(curr.selected[curr.text_prop])//text
|
||||||
target.children("input:hidden").val(curr.selected[curr.value_prop])//value
|
target.children("input:hidden").val(curr.selected[curr.value_prop])//value
|
||||||
if (curr.select instanceof Function) {
|
if (curr.select instanceof Function) {
|
||||||
curr.select(editem,row);
|
curr.select(editem, row);
|
||||||
}
|
}
|
||||||
this.search_dialog.show = false;
|
this.search_dialog.show = false;
|
||||||
//console.log(row, row["u_name"], row["f_number"], curr.id, target);
|
//console.log(row, row["u_name"], row["f_number"], curr.id, target);
|
||||||
@@ -334,6 +336,50 @@
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
)
|
||||||
|
|
||||||
|
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())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(
|
||||||
|
error => console.log(error)
|
||||||
|
)
|
||||||
|
|
||||||
},
|
},
|
||||||
editItem(item) {
|
editItem(item) {
|
||||||
this.editedIndex = this.desserts.indexOf(item);
|
this.editedIndex = this.desserts.indexOf(item);
|
||||||
@@ -404,7 +450,7 @@
|
|||||||
if (this.editedIndex > -1) {
|
if (this.editedIndex > -1) {
|
||||||
if (this.this_id != '') {
|
if (this.this_id != '') {
|
||||||
//chcck necessary params
|
//chcck necessary params
|
||||||
if (this.editedItem.files_num_selected.val != 0 ) {
|
if (this.editedItem.files_num_selected.val != 0) {
|
||||||
//insert or update data
|
//insert or update data
|
||||||
var pro_order_detail =
|
var pro_order_detail =
|
||||||
{
|
{
|
||||||
@@ -443,16 +489,16 @@
|
|||||||
const _subject = $('#<%= subject.ClientID%>').val();
|
const _subject = $('#<%= subject.ClientID%>').val();
|
||||||
return "(" + strUser + ")" + " " + _kind_txt + " " + _subject;
|
return "(" + strUser + ")" + " " + _kind_txt + " " + _subject;
|
||||||
},
|
},
|
||||||
bom_editItem(item){
|
bom_editItem(item) {
|
||||||
this.bom_editedIndex = this.bom_list.indexOf(item);
|
this.bom_editedIndex = this.bom_list.indexOf(item);
|
||||||
this.bom_editedItem = $.extend(true, {}, item);
|
this.bom_editedItem = $.extend(true, {}, item);
|
||||||
console.log("bom_editItem:", this.bom_editedIndex, this.bom_editedItem);
|
console.log("bom_editItem:", this.bom_editedIndex, this.bom_editedItem);
|
||||||
//debugger;
|
//debugger;
|
||||||
},
|
},
|
||||||
bom_deleteItem(item){
|
bom_deleteItem(item) {
|
||||||
confirm('確定要刪除此筆資料嗎?') && this.bom_list.splice(index, 1);
|
confirm('確定要刪除此筆資料嗎?') && this.bom_list.splice(index, 1);
|
||||||
},
|
},
|
||||||
bom_cancel(){
|
bom_cancel() {
|
||||||
this.bom_spliceNullData();
|
this.bom_spliceNullData();
|
||||||
this.bom_close();
|
this.bom_close();
|
||||||
},
|
},
|
||||||
@@ -472,7 +518,7 @@
|
|||||||
this.bom_editedItem = -1;
|
this.bom_editedItem = -1;
|
||||||
}, 300)
|
}, 300)
|
||||||
},
|
},
|
||||||
bom_addNew(){
|
bom_addNew() {
|
||||||
this.spliceNullData();
|
this.spliceNullData();
|
||||||
|
|
||||||
//addObj.id = this.desserts.length + 1;
|
//addObj.id = this.desserts.length + 1;
|
||||||
@@ -491,11 +537,11 @@
|
|||||||
if (!!this.bom_list) this.bom_list?.unshift(addObj);
|
if (!!this.bom_list) this.bom_list?.unshift(addObj);
|
||||||
this.bom_editItem(addObj);
|
this.bom_editItem(addObj);
|
||||||
},
|
},
|
||||||
bom_save(){
|
bom_save() {
|
||||||
if (this.bom_editedIndex > -1) {
|
if (this.bom_editedIndex > -1) {
|
||||||
if (this.this_id != '') {
|
if (this.this_id != '') {
|
||||||
//chcck necessary params
|
//chcck necessary params
|
||||||
if (this.bom_editedItem.item_num_selected.val != 0 ) {
|
if (this.bom_editedItem.item_num_selected.val != 0) {
|
||||||
//insert or update data
|
//insert or update data
|
||||||
var package_num = $(".packageNum input[type=hidden]").val();
|
var package_num = $(".packageNum input[type=hidden]").val();
|
||||||
var bom_detail =
|
var bom_detail =
|
||||||
@@ -525,6 +571,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
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())
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
},
|
},
|
||||||
@@ -625,6 +680,27 @@
|
|||||||
<asp:RegularExpressionValidator ControlToValidate="price" Display="Dynamic" SetFocusOnError="true" ErrorMessage="只能輸入數字" ID="RegularExpressionValidator3" runat="server" ValidationExpression="^(-?\d+)(\.\d+)?$" />
|
<asp:RegularExpressionValidator ControlToValidate="price" Display="Dynamic" SetFocusOnError="true" ErrorMessage="只能輸入數字" ID="RegularExpressionValidator3" runat="server" ValidationExpression="^(-?\d+)(\.\d+)?$" />
|
||||||
</div>
|
</div>
|
||||||
</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>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<select ID="ddlPrintSize" runat="server" onchange="VueApp.changeSel('ddlPrintSize')"></select>
|
||||||
|
<asp:HiddenField ID="hidPrintSize" 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">
|
<asp:UpdatePanel ID="UpdatePanel1" runat="server" class="row mb-1 label-sm-right">
|
||||||
<ContentTemplate>
|
<ContentTemplate>
|
||||||
<label class="col-sm-2 col-form-label"></label>
|
<label class="col-sm-2 col-form-label"></label>
|
||||||
|
|||||||
@@ -44,6 +44,21 @@ public partial class admin_activity_item_reg : MyWeb.config
|
|||||||
print_init.Text = prod.print_init;
|
print_init.Text = prod.print_init;
|
||||||
PARTNO.Text = prod.partno;
|
PARTNO.Text = prod.partno;
|
||||||
//kind.SelectedValue = prod.kind.ToString();
|
//kind.SelectedValue = prod.kind.ToString();
|
||||||
|
if (!isStrNull(prod.pageSize))
|
||||||
|
{
|
||||||
|
ddlPageSize.Value = prod.pageSize.ToString();
|
||||||
|
hidPageSize.Value = prod.pageSize.ToString();
|
||||||
|
}
|
||||||
|
if (!isStrNull(prod.printSize))
|
||||||
|
{
|
||||||
|
ddlPrintSize.Value = prod.printSize.ToString();
|
||||||
|
hidPrintSize.Value = prod.printSize.ToString();
|
||||||
|
}
|
||||||
|
if (!isStrNull(prod.defaultStyle))
|
||||||
|
{
|
||||||
|
ddlDefaultStyle.Value = prod.defaultStyle.ToString();
|
||||||
|
hidDefaultStyle.Value = prod.defaultStyle.ToString();
|
||||||
|
}
|
||||||
if (prod.kind.HasValue)
|
if (prod.kind.HasValue)
|
||||||
{
|
{
|
||||||
kind_txt.Value = prod.actItem_kind.kind;
|
kind_txt.Value = prod.actItem_kind.kind;
|
||||||
@@ -118,9 +133,22 @@ public partial class admin_activity_item_reg : MyWeb.config
|
|||||||
L_msg.Text = "";
|
L_msg.Text = "";
|
||||||
|
|
||||||
Model.actItem actItem = new Model.actItem();//新增
|
Model.actItem actItem = new Model.actItem();//新增
|
||||||
|
int maxSort = _db.actItems.Max(x => (int?)x.sort_order) ?? 0;
|
||||||
actItem.subject = subject.Text;
|
actItem.subject = subject.Text;
|
||||||
actItem.print_init = print_init.Text;
|
actItem.print_init = print_init.Text;
|
||||||
actItem.partno = PARTNO.Text;
|
actItem.partno = PARTNO.Text;
|
||||||
|
if (!isStrNull(ddlPageSize.Value))
|
||||||
|
{
|
||||||
|
actItem.pageSize = ddlPageSize.Value;
|
||||||
|
}
|
||||||
|
if (!isStrNull(ddlPrintSize.Value))
|
||||||
|
{
|
||||||
|
actItem.printSize = ddlPrintSize.Value;
|
||||||
|
}
|
||||||
|
if (!isStrNull(ddlDefaultStyle.Value))
|
||||||
|
{
|
||||||
|
actItem.defaultStyle = (ddlDefaultStyle.Value);
|
||||||
|
}
|
||||||
//if (!isStrNull(kind.SelectedValue)) { actItem.kind = Val(kind.SelectedValue); } else { actItem.kind = null; }
|
//if (!isStrNull(kind.SelectedValue)) { actItem.kind = Val(kind.SelectedValue); } else { actItem.kind = null; }
|
||||||
if (!isStrNull(category.SelectedValue)) { actItem.category = Val(category.SelectedValue); } else { actItem.category = null; }
|
if (!isStrNull(category.SelectedValue)) { actItem.category = Val(category.SelectedValue); } else { actItem.category = null; }
|
||||||
if (!isStrNull(kind.Value)) { actItem.kind = Val(kind.Value); } else { actItem.kind = null; }
|
if (!isStrNull(kind.Value)) { actItem.kind = Val(kind.Value); } else { actItem.kind = null; }
|
||||||
@@ -131,6 +159,7 @@ public partial class admin_activity_item_reg : MyWeb.config
|
|||||||
actItem.is_reconcile = is_reconcile_item.Checked ? "Y" : "N";
|
actItem.is_reconcile = is_reconcile_item.Checked ? "Y" : "N";
|
||||||
actItem.demo = demo.Text;
|
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.actItems.Add(actItem);
|
||||||
_db.SaveChanges();
|
_db.SaveChanges();
|
||||||
@@ -168,6 +197,18 @@ public partial class admin_activity_item_reg : MyWeb.config
|
|||||||
actItem.subject = subject.Text;
|
actItem.subject = subject.Text;
|
||||||
actItem.print_init = print_init.Text;
|
actItem.print_init = print_init.Text;
|
||||||
actItem.partno = PARTNO.Text;
|
actItem.partno = PARTNO.Text;
|
||||||
|
if (!isStrNull(hidPageSize.Value))
|
||||||
|
{
|
||||||
|
actItem.pageSize = hidPageSize.Value;
|
||||||
|
}
|
||||||
|
if (!isStrNull(hidPrintSize.Value))
|
||||||
|
{
|
||||||
|
actItem.printSize = hidPrintSize.Value;
|
||||||
|
}
|
||||||
|
if (!isStrNull(hidDefaultStyle.Value))
|
||||||
|
{
|
||||||
|
actItem.defaultStyle = (hidDefaultStyle.Value);
|
||||||
|
}
|
||||||
//if (!isStrNull(kind.SelectedValue)) { actItem.kind = Val(kind.SelectedValue); } else { actItem.kind = null; }
|
//if (!isStrNull(kind.SelectedValue)) { actItem.kind = Val(kind.SelectedValue); } else { actItem.kind = null; }
|
||||||
if (!isStrNull(category.SelectedValue)) { actItem.category = Val(category.SelectedValue); } else { actItem.category = null; }
|
if (!isStrNull(category.SelectedValue)) { actItem.category = Val(category.SelectedValue); } else { actItem.category = null; }
|
||||||
if (!isStrNull(kind.Value)) { actItem.kind = Val(kind.Value); } else { actItem.kind = null; }
|
if (!isStrNull(kind.Value)) { actItem.kind = Val(kind.Value); } else { actItem.kind = null; }
|
||||||
@@ -246,4 +287,16 @@ public partial class admin_activity_item_reg : MyWeb.config
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//protected override void Render(HtmlTextWriter writer)
|
||||||
|
//{
|
||||||
|
// ClientScript.RegisterForEventValidation(
|
||||||
|
// ddlDefaultStyle.UniqueID, "ddlDefaultStyle");
|
||||||
|
// ClientScript.RegisterForEventValidation(
|
||||||
|
// ddlPageSize.UniqueID, "ddlPageSize");
|
||||||
|
// ClientScript.RegisterForEventValidation(
|
||||||
|
// ddlPrintSize.UniqueID, "ddlPrintSize");
|
||||||
|
|
||||||
|
// base.Render(writer);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
el: '#app',
|
el: '#app',
|
||||||
vuetify: new Vuetify(vuetify_options),
|
vuetify: new Vuetify(vuetify_options),
|
||||||
data() {
|
data() {
|
||||||
|
console.log("yes",<%= _this_id %>);
|
||||||
return {
|
return {
|
||||||
this_id: '<%= _this_id %>',
|
this_id: '<%= _this_id %>',
|
||||||
options: {},
|
options: {},
|
||||||
@@ -124,6 +125,9 @@
|
|||||||
deep: true,
|
deep: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
//this.initialize();
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
search_show(curr) {
|
search_show(curr) {
|
||||||
//console.log("btn_click:", curr, curr.api_url);
|
//console.log("btn_click:", curr, curr.api_url);
|
||||||
|
|||||||
@@ -590,7 +590,8 @@
|
|||||||
this.data_table.selected.push(this.data_table.editFilesItem[i])
|
this.data_table.selected.push(this.data_table.editFilesItem[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, multiPrint() {
|
},
|
||||||
|
multiPrintNew() {
|
||||||
var params = {
|
var params = {
|
||||||
item: this.thisItemSelected.val,
|
item: this.thisItemSelected.val,
|
||||||
file: this.thisFilesSelected.val,
|
file: this.thisFilesSelected.val,
|
||||||
@@ -601,8 +602,81 @@
|
|||||||
//list = this.data_table.selected.map(x => x.num);
|
//list = this.data_table.selected.map(x => x.num);
|
||||||
|
|
||||||
list = this.data_table.selected
|
list = this.data_table.selected
|
||||||
.sort((a, b) => a.print_id.localeCompare(b.print_id))
|
.sort((a, b) => (a.print_id == null ? "" : a.print_id).localeCompare(b.print_id == null ? "" : b.print_id))
|
||||||
.map(x => x.num);
|
.map(x => x.num);
|
||||||
|
|
||||||
|
//console.log("what:",list);
|
||||||
|
|
||||||
|
if (list.length > 0) {
|
||||||
|
// 記錄已列印
|
||||||
|
let _url = HTTP_HOST + 'api/order/printMultiFileLog';
|
||||||
|
axios.post(_url, list, { params: params })
|
||||||
|
.then(response => {
|
||||||
|
for (let i = 0; i < this.data_table.selected.length; i++) {
|
||||||
|
for (let j = 0; i < this.data_table.editFilesItem.length; j++) {
|
||||||
|
if (this.data_table.selected[i].num == this.data_table.editFilesItem[j].num) {
|
||||||
|
this.data_table.editFilesItem[j].isPrinted = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log(error)
|
||||||
|
|
||||||
|
})
|
||||||
|
// 送出列印
|
||||||
|
_url = HTTP_HOST + 'admin/print/print_multi_new.aspx';
|
||||||
|
var form = document.createElement("form");
|
||||||
|
form.method = "POST";
|
||||||
|
form.action = _url;
|
||||||
|
form.target = "_blank"; // Open the result in a new tab
|
||||||
|
|
||||||
|
// Helper function to add hidden fields
|
||||||
|
const addHiddenField = (name, value) => {
|
||||||
|
const hiddenField = document.createElement("input");
|
||||||
|
hiddenField.type = "hidden";
|
||||||
|
hiddenField.name = name;
|
||||||
|
hiddenField.value = value;
|
||||||
|
form.appendChild(hiddenField);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add form fields
|
||||||
|
console.log(this.thisItemSelected.val, this.thisFilesSelected.val, JSON.stringify(list));
|
||||||
|
addHiddenField("item", this.thisItemSelected.val);
|
||||||
|
addHiddenField("file", this.thisFilesSelected.val);
|
||||||
|
addHiddenField("list", JSON.stringify(list));
|
||||||
|
addHiddenField("title", `${this.thisItemSelected.text} / ${this.thisFilesSelected.text}`);
|
||||||
|
//console.log("底家:",this.data_table.selected);
|
||||||
|
localStorage.setItem("item", this.thisItemSelected.val);
|
||||||
|
localStorage.setItem("list", JSON.stringify(this.data_table.selected));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
document.body.appendChild(form); // Not entirely sure if this is necessary
|
||||||
|
form.submit();
|
||||||
|
document.body.removeChild(form);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.snackbar.text = "未選擇列印項目";
|
||||||
|
this.snackbar.show = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
multiPrint() {
|
||||||
|
var params = {
|
||||||
|
item: this.thisItemSelected.val,
|
||||||
|
file: this.thisFilesSelected.val,
|
||||||
|
//list: this.data_table.selected.map(x => x.num)
|
||||||
|
};
|
||||||
|
|
||||||
|
var list = [];
|
||||||
|
//list = this.data_table.selected.map(x => x.num);
|
||||||
|
|
||||||
|
list = this.data_table.selected
|
||||||
|
.sort((a, b) => (a.print_id==null?"":a.print_id).localeCompare(b.print_id==null?"":b.print_id))
|
||||||
|
.map(x => x.num);
|
||||||
|
|
||||||
|
//console.log("what:",list);
|
||||||
|
|
||||||
if (list.length > 0) {
|
if (list.length > 0) {
|
||||||
// 記錄已列印
|
// 記錄已列印
|
||||||
@@ -638,11 +712,15 @@
|
|||||||
form.appendChild(hiddenField);
|
form.appendChild(hiddenField);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add form fields
|
// Add form fields
|
||||||
|
console.log(this.thisItemSelected.val, this.thisFilesSelected.val,JSON.stringify(list));
|
||||||
addHiddenField("item", this.thisItemSelected.val);
|
addHiddenField("item", this.thisItemSelected.val);
|
||||||
addHiddenField("file", this.thisFilesSelected.val);
|
addHiddenField("file", this.thisFilesSelected.val);
|
||||||
addHiddenField("list", JSON.stringify(list));
|
addHiddenField("list", JSON.stringify(list));
|
||||||
addHiddenField("title", `${this.thisItemSelected.text} / ${this.thisFilesSelected.text}`);
|
addHiddenField("title", `${this.thisItemSelected.text} / ${this.thisFilesSelected.text}`);
|
||||||
|
//console.log("底家:",this.data_table.selected);
|
||||||
|
localStorage.setItem("item", this.thisItemSelected.val);
|
||||||
|
localStorage.setItem("list", JSON.stringify(this.data_table.selected));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
var hiddenField = document.createElement("input");
|
var hiddenField = document.createElement("input");
|
||||||
@@ -827,7 +905,7 @@
|
|||||||
<div class="">
|
<div class="">
|
||||||
<asp:Button ID="add" runat="server" Text="送出" OnClick="add_Click" CssClass="btn btn-primary" />
|
<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="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>
|
</div>
|
||||||
</asp:Content>
|
</asp:Content>
|
||||||
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
|
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
|
||||||
@@ -1199,6 +1277,12 @@
|
|||||||
@click="multiPrint">
|
@click="multiPrint">
|
||||||
列印<v-icon dark>mdi-turn-right</v-icon>
|
列印<v-icon dark>mdi-turn-right</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
<v-btn
|
||||||
|
color="primary"
|
||||||
|
class="ml-2 white--text"
|
||||||
|
@click="multiPrintNew">
|
||||||
|
列印(New)<v-icon dark>mdi-turn-right</v-icon>
|
||||||
|
</v-btn>
|
||||||
</div>
|
</div>
|
||||||
</v-toolbar>
|
</v-toolbar>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -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,295 @@
|
|||||||
|
<%@ 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="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>
|
||||||
|
<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')
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
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,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>
|
||||||
+140
-14
@@ -13,10 +13,12 @@
|
|||||||
<a @click="print_dialog.show=true" class="btn btn-outline-primary btn-print" target="_blank">
|
<a @click="print_dialog.show=true" class="btn btn-outline-primary btn-print" target="_blank">
|
||||||
<i class="mdi mdi-printer"></i>列印管理報表
|
<i class="mdi mdi-printer"></i>列印管理報表
|
||||||
</a>
|
</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>列印查詢資料
|
<i class="mdi mdi-printer"></i>列印查詢資料
|
||||||
</a>
|
</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>
|
</div>
|
||||||
</asp:Content>
|
</asp:Content>
|
||||||
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" runat="Server">
|
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" runat="Server">
|
||||||
@@ -24,11 +26,13 @@
|
|||||||
Vue.filter('timeString', function (value, myFormat) {
|
Vue.filter('timeString', function (value, myFormat) {
|
||||||
return value == null || value == "" ? "" : moment(value).format(myFormat || 'YYYY-MM-DD, HH:mm:ss');
|
return value == null || value == "" ? "" : moment(value).format(myFormat || 'YYYY-MM-DD, HH:mm:ss');
|
||||||
});
|
});
|
||||||
let VueApp=new Vue({
|
let VueApp = new Vue({
|
||||||
el: '#app',
|
el: '#app',
|
||||||
vuetify: new Vuetify(vuetify_options),
|
vuetify: new Vuetify(vuetify_options),
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
isSearched: false,
|
||||||
|
print_error_msg: '',
|
||||||
options: { multiSort: false },
|
options: { multiSort: false },
|
||||||
search_options: { multiSort: false },
|
search_options: { multiSort: false },
|
||||||
data_table: {
|
data_table: {
|
||||||
@@ -41,7 +45,7 @@
|
|||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
header: [
|
header: [
|
||||||
{ text: '信眾編號', value: 'f_number', align: 'start' },
|
{ text: '信眾編號', value: 'f_number', align: 'start' },
|
||||||
{ text: '信眾姓名', value: 'u_name'},
|
{ text: '信眾姓名', value: 'u_name' },
|
||||||
{ text: '身分別', value: 'identity_type_desc' },
|
{ text: '身分別', value: 'identity_type_desc' },
|
||||||
{ text: '性別', value: 'sex' },
|
{ text: '性別', value: 'sex' },
|
||||||
{ text: '生日', value: 'birthday' },
|
{ text: '生日', value: 'birthday' },
|
||||||
@@ -49,9 +53,9 @@
|
|||||||
{ text: '', value: 'slot', sortable: false },
|
{ text: '', value: 'slot', sortable: false },
|
||||||
{ text: '', value: 'slot_btn', sortable: false, align: 'end' },
|
{ text: '', value: 'slot_btn', sortable: false, align: 'end' },
|
||||||
],
|
],
|
||||||
footer:{
|
footer: {
|
||||||
showFirstLastPage: true,
|
showFirstLastPage: true,
|
||||||
pageSizeOptions:[5,10,20,30],
|
pageSizeOptions: [5, 10, 20, 30],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
search: {
|
search: {
|
||||||
@@ -60,7 +64,7 @@
|
|||||||
sex: '',
|
sex: '',
|
||||||
//birthday: new Date().toISOString().split('T')[0],
|
//birthday: new Date().toISOString().split('T')[0],
|
||||||
//birthday2: new Date().toISOString().split('T')[0]
|
//birthday2: new Date().toISOString().split('T')[0]
|
||||||
birthday:'',
|
birthday: '',
|
||||||
birthday2: '',
|
birthday2: '',
|
||||||
address: '',
|
address: '',
|
||||||
country: '',
|
country: '',
|
||||||
@@ -69,7 +73,7 @@
|
|||||||
/*注意這邊的參數不能跟下方print_search重複*/
|
/*注意這邊的參數不能跟下方print_search重複*/
|
||||||
},
|
},
|
||||||
//列印管理報表
|
//列印管理報表
|
||||||
print_conditions:'yy',
|
print_conditions: 'yy',
|
||||||
print_search: {
|
print_search: {
|
||||||
year: '',
|
year: '',
|
||||||
month: '',
|
month: '',
|
||||||
@@ -132,7 +136,12 @@
|
|||||||
watch: {
|
watch: {
|
||||||
options: {
|
options: {
|
||||||
handler() {
|
handler() {
|
||||||
this.getList()
|
if (this.isSearched) {
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.data_table.loading = false;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
deep: true,
|
deep: true,
|
||||||
},
|
},
|
||||||
@@ -141,23 +150,101 @@
|
|||||||
this.search_get()
|
this.search_get()
|
||||||
},
|
},
|
||||||
deep: true,
|
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.search_dialog.current = this.search_dialog.controls.search1 ///default
|
||||||
this.initPrintSearch();
|
this.initPrintSearch();
|
||||||
|
|
||||||
const navEntries = performance.getEntriesByType("navigation");
|
const navEntries = performance.getEntriesByType("navigation");
|
||||||
const isReload = navEntries.length > 0 && navEntries[0].type === "reload";
|
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) {
|
if (isReload) {
|
||||||
sessionStorage.removeItem("followerpage");
|
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 {
|
else {
|
||||||
const savedPage = parseInt(sessionStorage.getItem('followerpage'));
|
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) {
|
if (savedPage) {
|
||||||
this.options.page = 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: {
|
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) {
|
search_show(curr) {
|
||||||
//console.log("btn_click:", curr, curr.api_url);
|
//console.log("btn_click:", curr, curr.api_url);
|
||||||
this.search_dialog.current = curr;
|
this.search_dialog.current = curr;
|
||||||
@@ -228,6 +315,7 @@
|
|||||||
//console.log(row, row["u_name"], row["f_number"], curr.id, target);
|
//console.log(row, row["u_name"], row["f_number"], curr.id, target);
|
||||||
},
|
},
|
||||||
getList(clearpage = false) {
|
getList(clearpage = false) {
|
||||||
|
console.log("do getlist")
|
||||||
const { sortBy, sortDesc, page, itemsPerPage } = this.options
|
const { sortBy, sortDesc, page, itemsPerPage } = this.options
|
||||||
const params = {
|
const params = {
|
||||||
sortBy: sortBy[0], sortDesc: sortDesc[0],
|
sortBy: sortBy[0], sortDesc: sortDesc[0],
|
||||||
@@ -241,6 +329,9 @@
|
|||||||
this.data_table.list = response.data.list
|
this.data_table.list = response.data.list
|
||||||
this.data_table.count = response.data.count;
|
this.data_table.count = response.data.count;
|
||||||
this.data_table.loading = false
|
this.data_table.loading = false
|
||||||
|
|
||||||
|
const dataToStore = JSON.stringify(this.data_table);
|
||||||
|
sessionStorage.setItem("member_list_cache", dataToStore);
|
||||||
})
|
})
|
||||||
.catch(
|
.catch(
|
||||||
error => console.log(error)
|
error => console.log(error)
|
||||||
@@ -262,7 +353,7 @@
|
|||||||
const index = this.data_table.list.indexOf(item)
|
const index = this.data_table.list.indexOf(item)
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
axios
|
axios
|
||||||
.delete(HTTP_HOST + 'api/follower/' + item.num)
|
.delete(HTTP_HOST + 'api/follower/Delete/' + item.num)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.getList();
|
this.getList();
|
||||||
})
|
})
|
||||||
@@ -282,18 +373,23 @@
|
|||||||
//}
|
//}
|
||||||
//this.data_table.selected = [];
|
//this.data_table.selected = [];
|
||||||
//this.data_table.count = this.data_table.list.length
|
//this.data_table.count = this.data_table.list.length
|
||||||
location.reload();
|
//location.reload();
|
||||||
|
this.getList();
|
||||||
})
|
})
|
||||||
.catch(error => console.log(error))
|
.catch(error => console.log(error))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
btn_search() {
|
btn_search() {
|
||||||
|
this.isSearched = true;
|
||||||
|
sessionStorage.setItem("member_query_params", JSON.stringify(this.search));
|
||||||
this.getList(true)
|
this.getList(true)
|
||||||
bootstrap.Offcanvas.getInstance(document.getElementById("offcanvasRight")).hide()
|
bootstrap.Offcanvas.getInstance(document.getElementById("offcanvasRight")).hide()
|
||||||
},
|
},
|
||||||
btn_all() {
|
btn_all() {
|
||||||
|
this.isSearched = false;
|
||||||
clearObjProps(this.search);
|
clearObjProps(this.search);
|
||||||
this.btn_search()
|
sessionStorage.setItem("member_query_params", JSON.stringify(this.search));
|
||||||
|
//this.btn_search()
|
||||||
},
|
},
|
||||||
goPrint() {
|
goPrint() {
|
||||||
//debugger;
|
//debugger;
|
||||||
@@ -309,6 +405,7 @@
|
|||||||
//列印管理報表
|
//列印管理報表
|
||||||
print_close() {
|
print_close() {
|
||||||
this.print_dialog.show = false;
|
this.print_dialog.show = false;
|
||||||
|
this.print_error_msg = "";
|
||||||
}
|
}
|
||||||
,
|
,
|
||||||
initPrintSearch() {
|
initPrintSearch() {
|
||||||
@@ -391,10 +488,31 @@
|
|||||||
$('#country2').val('');
|
$('#country2').val('');
|
||||||
VueApp.search.country2 = '';
|
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>
|
</script>
|
||||||
</asp:Content>
|
</asp:Content>
|
||||||
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
|
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
|
||||||
<uc1:alert runat="server" ID="L_msg" Text="" />
|
<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">
|
<div id="content" class="container-fluid">
|
||||||
<v-data-table
|
<v-data-table
|
||||||
v-model="data_table.selected"
|
v-model="data_table.selected"
|
||||||
@@ -508,9 +626,17 @@
|
|||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
</v-row>
|
</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-row densee class="pt-3" >
|
||||||
<v-col :cols="12" class="pt-3 text-center" >
|
<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-btn class="ma-2" color="green" dark @click="print_close" > 取消 </v-btn>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
|
|||||||
+287
-176
@@ -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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Configuration;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.OleDb;
|
using System.Data.OleDb;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using System.Web.UI;
|
using System.Web.UI;
|
||||||
using System.Web.UI.WebControls;
|
using System.Web.UI.WebControls;
|
||||||
using System.Configuration;
|
using System.Windows.Controls;
|
||||||
using System.IO;
|
using System.Windows.Interop;
|
||||||
using DocumentFormat.OpenXml.Packaging;
|
|
||||||
using DocumentFormat.OpenXml;
|
|
||||||
using DocumentFormat.OpenXml.Spreadsheet;
|
|
||||||
using System.Linq;
|
|
||||||
using static TreeView;
|
using static TreeView;
|
||||||
|
|
||||||
|
|
||||||
@@ -19,11 +22,17 @@ public partial class admin_follower_index : MyWeb.config
|
|||||||
{
|
{
|
||||||
public int page = 1;
|
public int page = 1;
|
||||||
private Model.ezEntities _db = new Model.ezEntities();
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
protected string lastAddedID;
|
||||||
protected void Page_Load(object sender, EventArgs e)
|
protected void Page_Load(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!IsPostBack)
|
if (!IsPostBack)
|
||||||
{
|
{
|
||||||
|
if (Session["LastAddedID"] != null)
|
||||||
|
{
|
||||||
|
lastAddedID = Session["LastAddedID"].ToString();
|
||||||
|
Session.Remove("LastAddedID");
|
||||||
|
}
|
||||||
BuildKind();
|
BuildKind();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -42,10 +51,10 @@ public partial class admin_follower_index : MyWeb.config
|
|||||||
//國籍
|
//國籍
|
||||||
s_country.Items.Clear();
|
s_country.Items.Clear();
|
||||||
s_country.Items.Add(new ListItem("請選擇", ""));
|
s_country.Items.Add(new ListItem("請選擇", ""));
|
||||||
var qry =_db.countries.OrderBy(x => x.range).ThenBy(x => x.name_en).ToList();
|
var qry = _db.countries.OrderBy(x => x.range).ThenBy(x => x.name_en).ToList();
|
||||||
if (qry.Count > 0)
|
if (qry.Count > 0)
|
||||||
{
|
{
|
||||||
foreach(var x in qry)
|
foreach (var x in qry)
|
||||||
s_country.Items.Add(new ListItem(x.name_zh, x.ID));
|
s_country.Items.Add(new ListItem(x.name_zh, x.ID));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,208 +77,310 @@ public partial class admin_follower_index : MyWeb.config
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region 匯出Excel
|
#region 匯出
|
||||||
|
|
||||||
protected void excel_Click(object sender, EventArgs e)
|
protected void export_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var memoryStream = new MemoryStream();
|
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)
|
if (list.Count > 0)
|
||||||
{
|
{
|
||||||
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
using (var doc = SpreadsheetDocument.Create(memoryStream, SpreadsheetDocumentType.Workbook))
|
||||||
Model.country country = new Model.country();
|
|
||||||
var tdesc = publicFun.enum_desc<Model.follower.type>();
|
|
||||||
foreach (var item in list)
|
|
||||||
{
|
{
|
||||||
//新增資料列
|
var wb = doc.AddWorkbookPart();
|
||||||
tr = new Row();
|
wb.Workbook = new Workbook();
|
||||||
string s1, s2, sha;
|
var sheets = wb.Workbook.AppendChild(new Sheets());
|
||||||
s1= encrypt.DecryptAutoKey(item.phone);
|
|
||||||
s2= encrypt.DecryptAutoKey(item.id_code);
|
//建立第一個頁籤
|
||||||
sha = encrypt.followerHash(s1, s2);
|
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(
|
tr.Append(
|
||||||
new Cell() { CellValue = new CellValue(item.f_number), DataType = CellValues.String },
|
new Cell() { CellValue = new CellValue("信眾編號"), DataType = CellValues.String },
|
||||||
new Cell() { CellValue = new CellValue(item.u_name), DataType = CellValues.String },
|
new Cell() { CellValue = new CellValue("信眾姓名"), DataType = CellValues.String },
|
||||||
new Cell() { CellValue = new CellValue(item.sex), DataType = CellValues.String },
|
new Cell() { CellValue = new CellValue("性別"), 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("身分別"), 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("生日(國曆)"), DataType = CellValues.String },
|
||||||
new Cell() { CellValue = new CellValue(encrypt.DecryptAutoKey(item.phone)), DataType = CellValues.String },
|
new Cell() { CellValue = new CellValue("聯絡電話"), DataType = CellValues.String },
|
||||||
new Cell() { CellValue = new CellValue(encrypt.DecryptAutoKey(item.cellphone)), DataType = CellValues.String },
|
new Cell() { CellValue = new CellValue("手機號碼"), DataType = CellValues.String },
|
||||||
new Cell() { CellValue = new CellValue(item.refuge_area), DataType = CellValues.String },
|
new Cell() { CellValue = new CellValue("皈依道場"), DataType = CellValues.String },
|
||||||
new Cell() { CellValue = new CellValue(item.refuge_name), DataType = CellValues.String },
|
new Cell() { CellValue = new CellValue("皈依法名"), 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("皈依日期"), 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("加入日期"), DataType = CellValues.String },
|
||||||
new Cell() { CellValue = new CellValue(item.contactor), DataType = CellValues.String },
|
new Cell() { CellValue = new CellValue("緊急連絡人"), DataType = CellValues.String },
|
||||||
new Cell() { CellValue = new CellValue(encrypt.DecryptAutoKey(item.contactor_phone)), DataType = CellValues.String },
|
new Cell() { CellValue = new CellValue("緊急連絡人電話"), DataType = CellValues.String },
|
||||||
new Cell() { CellValue = new CellValue(item.blood), DataType = CellValues.String },
|
new Cell() { CellValue = new CellValue("血型"), DataType = CellValues.String },
|
||||||
new Cell() { CellValue = new CellValue(!isStrNull(item.country) ? item.country1.name_zh : ""), DataType = CellValues.String },
|
new Cell() { CellValue = new CellValue("國籍"), DataType = CellValues.String },
|
||||||
new Cell() { CellValue = new CellValue(item.address), DataType = CellValues.String },
|
new Cell() { CellValue = new CellValue("收件地址"), DataType = CellValues.String },
|
||||||
new Cell() { CellValue = new CellValue(item.introducer), DataType = CellValues.String },
|
new Cell() { CellValue = new CellValue("介紹人"), DataType = CellValues.String },
|
||||||
new Cell() { CellValue = new CellValue(item.socialid1), DataType = CellValues.String },
|
new Cell() { CellValue = new CellValue("LINE帳號"), DataType = CellValues.String },
|
||||||
new Cell() { CellValue = new CellValue(item.socialid2), DataType = CellValues.String },
|
new Cell() { CellValue = new CellValue("其它社群帳號"), 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("建檔日期"), DataType = CellValues.String }
|
||||||
,new Cell() { CellValue = new CellValue(encrypt.DecryptAutoKey(item.id_code)), DataType = CellValues.String }
|
, new Cell() { CellValue = new CellValue("身分證號"), DataType = CellValues.String }
|
||||||
//, new Cell() { CellValue = new CellValue(sha), DataType = CellValues.String }
|
//,new Cell() { CellValue = new CellValue("SHA"), DataType = CellValues.String }
|
||||||
);
|
);
|
||||||
sd.AppendChild(tr);
|
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();
|
||||||
|
|
||||||
//空一列
|
hid_err_msg.Value = "success";
|
||||||
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()));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
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 : "";
|
||||||
|
|
||||||
HttpContext.Current.Response.Clear();
|
var qry = _db.followers.AsQueryable();
|
||||||
HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=信眾_data.xlsx");
|
if (selYear > 0)
|
||||||
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
{
|
||||||
HttpContext.Current.Response.BinaryWrite(memoryStream.ToArray());
|
urlParams += "&year=" + selYear;
|
||||||
HttpContext.Current.Response.End();
|
}
|
||||||
|
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}', '列印信眾資料', '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();
|
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()));
|
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 (selYear > 0)
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// 匯出查詢資料
|
||||||
|
{
|
||||||
|
//紀錄匯出條件
|
||||||
|
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";
|
_query += "信眾編號:" + s_f_number.Value.Trim() + "\n";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isStrNull(s_u_name.Value))
|
if (!isStrNull(s_u_name.Value))
|
||||||
{
|
{
|
||||||
qry = qry.Where(o => o.u_name.Contains(s_u_name.Value.Trim()));
|
qry = qry.Where(o => o.u_name.Contains(s_u_name.Value.Trim()));
|
||||||
|
|
||||||
_query += "信眾姓名:" + s_u_name.Value.Trim() + "\n";
|
_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))
|
|
||||||
{
|
|
||||||
qry = qry.Where(o => o.search_keywords != null && o.search_keywords.Contains(hexSearch));
|
|
||||||
_query += "電話/證號:" + s_phone_idcode.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";
|
||||||
|
}
|
||||||
|
|
||||||
if (!isStrNull(s_birthday.Value) && isDate(s_birthday.Value))
|
// 電話/證號搜尋 (使用 search_keywords HEX 編碼)
|
||||||
{
|
if (!isStrNull(s_phone_idcode.Value) && GlobalVariables.UseSearchKeywords)
|
||||||
qry = qry.Where(o => o.birthday >= ValDate(s_birthday.Value));
|
{
|
||||||
_query += "生日(起):" + s_birthday.Value.Trim() + "\n";
|
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>
|
<span>信眾姓名:</span><asp:Literal runat="server" ID="username"></asp:Literal>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<a href="index.aspx" class="btn btn-outline-secondary">返回</a>
|
||||||
</asp:Content>
|
</asp:Content>
|
||||||
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
|
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
|||||||
@@ -4,10 +4,11 @@
|
|||||||
</asp:Content>
|
</asp:Content>
|
||||||
<asp:Content ID="Content2" ContentPlaceHolderID="page_nav" Runat="Server">
|
<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="scroll-nav nav nav-tabs mb-2 mb-sm-0 d-none d-sm-flex">
|
||||||
<div class="ms-3">
|
<div class="ms-3">
|
||||||
<span>信眾姓名:</span><asp:Literal runat="server" ID="username"></asp:Literal>
|
<span>信眾姓名:</span><asp:Literal runat="server" ID="username"></asp:Literal>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<a href="order_record.aspx?userid=<%=Request["userid"] %>" class="btn btn-outline-secondary">返回</a>
|
||||||
</asp:Content>
|
</asp:Content>
|
||||||
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
|
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using DocumentFormat.OpenXml.Vml.Office;
|
|||||||
using OfficeOpenXml.FormulaParsing.Excel.Functions.Information;
|
using OfficeOpenXml.FormulaParsing.Excel.Functions.Information;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using System.Web.UI;
|
using System.Web.UI;
|
||||||
@@ -60,7 +61,8 @@ public partial class admin_follower_print_ : System.Web.UI.Page
|
|||||||
if (!string.IsNullOrEmpty(Request["birthday2"]))
|
if (!string.IsNullOrEmpty(Request["birthday2"]))
|
||||||
{
|
{
|
||||||
DateTime birthday2Param = Convert.ToDateTime(Request["birthday2"].Trim());
|
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";
|
_query += "生日(訖):" + birthday2Param.ToString("yyyy/MM/dd") + "\n";
|
||||||
}
|
}
|
||||||
// ❌ 錯誤寫法: _db.countries.Where(x => x.ID == Request["country"].ToString())
|
// ❌ 錯誤寫法: _db.countries.Where(x => x.ID == Request["country"].ToString())
|
||||||
@@ -86,6 +88,18 @@ 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";
|
_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"]))
|
if (!string.IsNullOrEmpty(Request["year"]))
|
||||||
{
|
{
|
||||||
|
|||||||
+36
-16
@@ -230,7 +230,7 @@
|
|||||||
{ id: 'f_number', title: '編號' },
|
{ id: 'f_number', title: '編號' },
|
||||||
{ id: 'u_name', title: '姓名' },
|
{ id: 'u_name', title: '姓名' },
|
||||||
{ id: 'address', title: '地址' },
|
{ id: 'address', title: '地址' },
|
||||||
{ id: 'onlyfamily', title: '只查親屬'},
|
{ id: 'onlyfamily', title: '只查親屬' },
|
||||||
],
|
],
|
||||||
api_url: HTTP_HOST + 'api/follower/GetList',
|
api_url: HTTP_HOST + 'api/follower/GetList',
|
||||||
columns: [
|
columns: [
|
||||||
@@ -314,10 +314,10 @@
|
|||||||
birthday: '',
|
birthday: '',
|
||||||
phoneDes: '',
|
phoneDes: '',
|
||||||
demo: '',
|
demo: '',
|
||||||
appellation_id_selected :
|
appellation_id_selected:
|
||||||
{
|
{
|
||||||
text : '',
|
text: '',
|
||||||
val : 0,
|
val: 0,
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
@@ -372,7 +372,7 @@
|
|||||||
],
|
],
|
||||||
tabletsDetail: { multiSort: false },
|
tabletsDetail: { multiSort: false },
|
||||||
tabletTable: {
|
tabletTable: {
|
||||||
Loading:true,
|
Loading: true,
|
||||||
disableButton: true,
|
disableButton: true,
|
||||||
searchDetail: '',
|
searchDetail: '',
|
||||||
headersDetail: [
|
headersDetail: [
|
||||||
@@ -394,11 +394,11 @@
|
|||||||
num: 0,
|
num: 0,
|
||||||
f_num: 0,
|
f_num: 0,
|
||||||
type: this.selectedTabletType,
|
type: this.selectedTabletType,
|
||||||
title:'',
|
title: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
//新:家人
|
//新:家人
|
||||||
family:{
|
family: {
|
||||||
dialog: false,
|
dialog: false,
|
||||||
isEditing: false,
|
isEditing: false,
|
||||||
is_tw: true,
|
is_tw: true,
|
||||||
@@ -420,8 +420,8 @@
|
|||||||
chinese_year: "",
|
chinese_year: "",
|
||||||
zodiac: "",
|
zodiac: "",
|
||||||
birth_time: "",
|
birth_time: "",
|
||||||
city:"",
|
city: "",
|
||||||
area:"",
|
area: "",
|
||||||
address: "",
|
address: "",
|
||||||
phone: "",
|
phone: "",
|
||||||
mobile: "",
|
mobile: "",
|
||||||
@@ -440,8 +440,8 @@
|
|||||||
chinese_year: "",
|
chinese_year: "",
|
||||||
zodiac: "",
|
zodiac: "",
|
||||||
birth_time: "",
|
birth_time: "",
|
||||||
city:"",
|
city: "",
|
||||||
area:"",
|
area: "",
|
||||||
address: "",
|
address: "",
|
||||||
phone: "",
|
phone: "",
|
||||||
mobile: "",
|
mobile: "",
|
||||||
@@ -585,7 +585,7 @@
|
|||||||
this.search_dialog.list = response.data.list
|
this.search_dialog.list = response.data.list
|
||||||
this.search_dialog.count = response.data.count
|
this.search_dialog.count = response.data.count
|
||||||
this.search_dialog.loading = false
|
this.search_dialog.loading = false
|
||||||
|
console.log(this.search_dialog.list)
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
@@ -1318,13 +1318,32 @@
|
|||||||
$('.tab-pane,.edit_Click').removeClass('pe-none'); // 移除 pe-none 類,允許編輯
|
$('.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>
|
</script>
|
||||||
</asp:Content>
|
</asp:Content>
|
||||||
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
|
<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">
|
<div class="scroll-nav nav nav-tabs mb-2 mb-sm-0 d-none d-sm-flex">
|
||||||
<template v-if="follower_id !='' "> {{titleword()}} </template>
|
<template v-if="follower_id !='' "> {{titleword()}} </template>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex align-items-center">
|
<div class="">
|
||||||
<div class="form-check me-3 d-none" id="editCheckboxContainer">
|
<div class="form-check me-3 d-none" id="editCheckboxContainer">
|
||||||
<input class="form-check-input" type="checkbox" id="editCheckbox">
|
<input class="form-check-input" type="checkbox" id="editCheckbox">
|
||||||
<label class="form-check-label" for="editCheckbox">
|
<label class="form-check-label" for="editCheckbox">
|
||||||
@@ -1332,8 +1351,8 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<asp:Button ID="add" runat="server" Text="送出" OnClick="add_Click" CssClass="btn btn-primary edit_Click noedit" />
|
<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="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="goback" runat="server" Text="取消" Visible="true" CausesValidation="false" OnClick="goback_Click" CssClass="btn btn-outline-secondary" />
|
||||||
</div>
|
</div>
|
||||||
</asp:Content>
|
</asp:Content>
|
||||||
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
|
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
|
||||||
@@ -1412,7 +1431,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<label class="col-sm-2 col-lg-1 col-form-label">手機號碼<asp:Literal ID="cellphoneReqStar" runat="server" Text=" *"></asp:Literal></label>
|
<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">
|
<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}$" />
|
<asp:RegularExpressionValidator ControlToValidate="cellphone" Display="Dynamic" ErrorMessage="格式有誤" ID="RegularExpressionValidator2" runat="server" SetFocusOnError="true" ValidationExpression="^09\d{2}-?\d{3}-?\d{3}$" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -2155,4 +2174,5 @@
|
|||||||
</template>
|
</template>
|
||||||
</v-snackbar>
|
</v-snackbar>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</asp:Content>
|
</asp:Content>
|
||||||
@@ -1,21 +1,26 @@
|
|||||||
using System;
|
using Model;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Configuration;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
|
using System.Data.Entity;
|
||||||
using System.Data.OleDb;
|
using System.Data.OleDb;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using System.Web.UI;
|
using System.Web.UI;
|
||||||
using System.Web.UI.WebControls;
|
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
|
public partial class admin_follower_reg : MyWeb.config
|
||||||
{
|
{
|
||||||
private Model.ezEntities _db = new Model.ezEntities();
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
public ArrayList _tmp = new ArrayList();
|
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)
|
protected void Page_Load(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
CallAjax();
|
CallAjax();
|
||||||
@@ -29,6 +34,11 @@ public partial class admin_follower_reg : MyWeb.config
|
|||||||
|
|
||||||
if (isStrNull(Request["num"]))
|
if (isStrNull(Request["num"]))
|
||||||
{
|
{
|
||||||
|
if (!isAutoNumbering)
|
||||||
|
{
|
||||||
|
f_number.ReadOnly = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isStrNull(Request["leader"]))
|
if (!isStrNull(Request["leader"]))
|
||||||
{
|
{
|
||||||
int _num = Val(Request["leader"]);
|
int _num = Val(Request["leader"]);
|
||||||
@@ -50,9 +60,14 @@ public partial class admin_follower_reg : MyWeb.config
|
|||||||
//預設國籍
|
//預設國籍
|
||||||
country.Value = "158";
|
country.Value = "158";
|
||||||
country_txt.Value = "中華民國(台灣)";
|
country_txt.Value = "中華民國(台灣)";
|
||||||
|
|
||||||
|
// 預設加入日期
|
||||||
|
join_date.Text = DateTime.Now.ToString("yyyy-MM-dd");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
f_number.ReadOnly = true;
|
||||||
|
|
||||||
int _num = Val(Request["num"]);
|
int _num = Val(Request["num"]);
|
||||||
var prod = qry.Where(q => q.num == _num).FirstOrDefault();
|
var prod = qry.Where(q => q.num == _num).FirstOrDefault();
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
@@ -206,8 +221,11 @@ public partial class admin_follower_reg : MyWeb.config
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 使用新的 generate_f_number 方法,已內建重號檢查和重試機制
|
if (isAutoNumbering)
|
||||||
followers.f_number = follower.generate_f_number(sex.SelectedValue);
|
{
|
||||||
|
// 使用新的 generate_f_number 方法,已內建重號檢查和重試機制
|
||||||
|
followers.f_number = follower.generate_f_number(sex.SelectedValue);
|
||||||
|
}
|
||||||
followers.identity_type = Val(identity_type.SelectedValue);
|
followers.identity_type = Val(identity_type.SelectedValue);
|
||||||
if(!isStrNull(leader.Value)) followers.leader = Val(leader.Value);
|
if(!isStrNull(leader.Value)) followers.leader = Val(leader.Value);
|
||||||
if (!isStrNull(country.Value)) followers.country = country.Value;
|
if (!isStrNull(country.Value)) followers.country = country.Value;
|
||||||
@@ -240,6 +258,8 @@ public partial class admin_follower_reg : MyWeb.config
|
|||||||
Model.admin_log admin_log = new Model.admin_log();
|
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);
|
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");
|
Response.Redirect("index.aspx");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -310,7 +330,7 @@ public partial class admin_follower_reg : MyWeb.config
|
|||||||
followers.sex = sex.SelectedValue;
|
followers.sex = sex.SelectedValue;
|
||||||
followers.blood = blood.SelectedValue;
|
followers.blood = blood.SelectedValue;
|
||||||
followers.tab = tab.Value.Trim(',');
|
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);
|
followers.follower_hash = encrypt.followerHash(followers.phone, followers.id_code);
|
||||||
|
|
||||||
// 如果啟用 search_keywords 功能,生成並更新 search_keywords
|
// 如果啟用 search_keywords 功能,生成並更新 search_keywords
|
||||||
@@ -319,13 +339,51 @@ public partial class admin_follower_reg : MyWeb.config
|
|||||||
followers.search_keywords = encrypt.GenerateSearchKeywords(followers);
|
followers.search_keywords = encrypt.GenerateSearchKeywords(followers);
|
||||||
}
|
}
|
||||||
|
|
||||||
_db.SaveChanges();
|
// 檢查是否有修改資料
|
||||||
|
var entry = _db.Entry(followers);
|
||||||
|
this.isDataChanged = entry.CurrentValues.PropertyNames.Any(name =>
|
||||||
|
{
|
||||||
|
if (name == "admin_log" || name == "follower_hash")
|
||||||
|
return false;
|
||||||
|
|
||||||
Model.admin_log admin_log = new Model.admin_log();
|
var originalVal = entry.OriginalValues[name]?.ToString();
|
||||||
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 currentVal = entry.CurrentValues[name]?.ToString();
|
||||||
|
|
||||||
Response.Redirect("index.aspx?page=" + Convert.ToString(Request["page"]));
|
// 針對加密欄位進行特殊處理
|
||||||
|
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)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -339,7 +397,7 @@ public partial class admin_follower_reg : MyWeb.config
|
|||||||
L_msg.Type = alert_type.danger;
|
L_msg.Type = alert_type.danger;
|
||||||
L_msg.Text = "查無資料";
|
L_msg.Text = "查無資料";
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
if (chk_pro_num(f_number.Text, Val(Request["num"])))
|
if (chk_pro_num(f_number.Text, Val(Request["num"])))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,7 +160,7 @@
|
|||||||
style="border-bottom: 1px solid #eee;"
|
style="border-bottom: 1px solid #eee;"
|
||||||
>
|
>
|
||||||
<div class="d-flex align-center">
|
<div class="d-flex align-center">
|
||||||
<span class="font-weight-bold">续住</span>
|
<span class="font-weight-bold">續住</span>
|
||||||
</div>
|
</div>
|
||||||
<v-btn icon @click="closeXuzhuGuestModalMethod">
|
<v-btn icon @click="closeXuzhuGuestModalMethod">
|
||||||
<v-icon>mdi-close</v-icon>
|
<v-icon>mdi-close</v-icon>
|
||||||
@@ -170,11 +170,11 @@
|
|||||||
<!-- 弹窗内容 -->
|
<!-- 弹窗内容 -->
|
||||||
<v-card-text class="flex-grow-1 py-6" style="overflow-y: auto;">
|
<v-card-text class="flex-grow-1 py-6" style="overflow-y: auto;">
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<span class="font-weight-medium">当前退房时间:</span>
|
<span class="font-weight-medium">當前退房時間:</span>
|
||||||
<span class="text-primary">{{ guadanguest.xuzhu.currentCheckoutDate }}</span>
|
<span class="text-primary">{{ guadanguest.xuzhu.currentCheckoutDate }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex align-center">
|
<div class="d-flex align-center">
|
||||||
<span class="font-weight-medium mr-2">续住后退房时间:</span>
|
<span class="font-weight-medium mr-2">續住後退房時間:</span>
|
||||||
<input
|
<input
|
||||||
type="date"
|
type="date"
|
||||||
id="newCheckoutDate"
|
id="newCheckoutDate"
|
||||||
@@ -187,7 +187,7 @@
|
|||||||
|
|
||||||
<!-- 弹窗操作按钮 -->
|
<!-- 弹窗操作按钮 -->
|
||||||
<v-card-actions class="justify-end pt-4" style="border-top: 1px solid #eee;">
|
<v-card-actions class="justify-end pt-4" style="border-top: 1px solid #eee;">
|
||||||
<v-btn color="primary" class="px-6" @click="xuzhuPost">续住</v-btn>
|
<v-btn color="primary" class="px-6" @click="xuzhuPost">續住</v-btn>
|
||||||
<v-btn text class="ml-2" @click="closeXuzhuGuestModalMethod">取消</v-btn>
|
<v-btn text class="ml-2" @click="closeXuzhuGuestModalMethod">取消</v-btn>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
@@ -1069,11 +1069,11 @@
|
|||||||
xuzhuPost() {
|
xuzhuPost() {
|
||||||
// 校验必填
|
// 校验必填
|
||||||
if (!this.guadanguest.xuzhu.guestUuid || !this.guadanguest.xuzhu.guestBedUuid) {
|
if (!this.guadanguest.xuzhu.guestUuid || !this.guadanguest.xuzhu.guestBedUuid) {
|
||||||
alert("GuestUuid 和 GuestBedUuid 不能为空");
|
alert("GuestUuid 和 GuestBedUuid 不能為空");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!this.guadanguest.xuzhu.newCheckoutDate || !this.guadanguest.xuzhu.currentCheckoutDate) {
|
if (!this.guadanguest.xuzhu.newCheckoutDate || !this.guadanguest.xuzhu.currentCheckoutDate) {
|
||||||
alert("续住时间不能为空");
|
alert("續住時間不能為空");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1087,8 +1087,8 @@
|
|||||||
axios.post(HTTP_HOST + 'api/guadanorderguest/xuzhu', payload)
|
axios.post(HTTP_HOST + 'api/guadanorderguest/xuzhu', payload)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.$refs.messageModal.open({
|
this.$refs.messageModal.open({
|
||||||
title: '续住成功',
|
title: '續住成功',
|
||||||
message: '客人续住已处理',
|
message: '續住以處理',
|
||||||
status: 'success',
|
status: 'success',
|
||||||
callback: () => {
|
callback: () => {
|
||||||
// 弹窗关闭后的回调
|
// 弹窗关闭后的回调
|
||||||
@@ -1096,7 +1096,7 @@
|
|||||||
this.getGuadanOrderGuestByOrderNo();
|
this.getGuadanOrderGuestByOrderNo();
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.error("发生错误:", error.message);
|
console.error("發生錯誤:", error.message);
|
||||||
} finally {
|
} finally {
|
||||||
this.closeXuzhuGuestModalMethod();
|
this.closeXuzhuGuestModalMethod();
|
||||||
}
|
}
|
||||||
@@ -1105,8 +1105,8 @@
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
this.$refs.messageModal.open({
|
this.$refs.messageModal.open({
|
||||||
title: '续住失败',
|
title: '續住失敗',
|
||||||
message: error.response?.data?.message || '系统异常,请稍后重试',
|
message: error.response?.data?.message || '系統異常,請稍後重試',
|
||||||
status: 'error'
|
status: 'error'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="p-3 bg-light text-center rounded shadow" style="min-height: 180px;">
|
<div class="p-3 bg-light text-center rounded shadow" style="min-height: 180px;">
|
||||||
<div class="fs-2">📝</div>
|
<div class="fs-2">📝</div>
|
||||||
<div class="text-muted small mt-1">总挂单次数</div>
|
<div class="text-muted small mt-1">總掛單次數</div>
|
||||||
<div class="fw-bold fs-5 mt-1">{{ guadanStatistics.guadanTotalCount }}</div>
|
<div class="fw-bold fs-5 mt-1">{{ guadanStatistics.guadanTotalCount }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="p-3 bg-light text-center rounded shadow" style="min-height: 180px;">
|
<div class="p-3 bg-light text-center rounded shadow" style="min-height: 180px;">
|
||||||
<div class="fs-2">📋</div>
|
<div class="fs-2">📋</div>
|
||||||
<div class="text-muted small mt-1">当前挂单数量</div>
|
<div class="text-muted small mt-1">當前掛單數</div>
|
||||||
<div class="fw-bold fs-5 mt-1">{{ guadanStatistics.guadanCurrentCount }}</div>
|
<div class="fw-bold fs-5 mt-1">{{ guadanStatistics.guadanCurrentCount }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="p-3 bg-light text-center rounded shadow" style="min-height: 180px;">
|
<div class="p-3 bg-light text-center rounded shadow" style="min-height: 180px;">
|
||||||
<div class="fs-2">👥</div>
|
<div class="fs-2">👥</div>
|
||||||
<div class="text-muted small mt-1">总挂单人数</div>
|
<div class="text-muted small mt-1">總掛單人數</div>
|
||||||
<div class="fw-bold fs-5 mt-1">
|
<div class="fw-bold fs-5 mt-1">
|
||||||
{{ guadanStatistics.guadanPeopleTotal }} (男:{{ guadanStatistics.guadanPeopleMale }},女:{{ guadanStatistics.guadanPeopleFemale }})
|
{{ guadanStatistics.guadanPeopleTotal }} (男:{{ guadanStatistics.guadanPeopleMale }},女:{{ guadanStatistics.guadanPeopleFemale }})
|
||||||
</div>
|
</div>
|
||||||
@@ -215,7 +215,7 @@
|
|||||||
{ text: '房间数量', value: 'roomcount' },
|
{ text: '房间数量', value: 'roomcount' },
|
||||||
{ text: '床位数量', value: 'bedcount' },
|
{ text: '床位数量', value: 'bedcount' },
|
||||||
{ text: '预约人数', value: 'todaytotalbookers' },
|
{ text: '预约人数', value: 'todaytotalbookers' },
|
||||||
{ text: '已入住人数', value: 'checkin'},
|
{ text: '已入住人數', value: 'checkin'},
|
||||||
{ text: '可用床位', value: 'availableBeds' },
|
{ text: '可用床位', value: 'availableBeds' },
|
||||||
{ text: '床位利用率', value: 'bedusagerate' }
|
{ text: '床位利用率', value: 'bedusagerate' }
|
||||||
],
|
],
|
||||||
@@ -303,7 +303,7 @@
|
|||||||
},
|
},
|
||||||
exportStatisticsToExcel() {
|
exportStatisticsToExcel() {
|
||||||
if (!this.items || !this.items.length) {
|
if (!this.items || !this.items.length) {
|
||||||
console.warn("没有数据可导出");
|
console.warn("沒有數據可匯出");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,7 +319,7 @@
|
|||||||
|
|
||||||
// 3. 创建 Workbook 并添加 Sheet
|
// 3. 创建 Workbook 并添加 Sheet
|
||||||
const wb = XLSX.utils.book_new();
|
const wb = XLSX.utils.book_new();
|
||||||
XLSX.utils.book_append_sheet(wb, ws, "统计数据");
|
XLSX.utils.book_append_sheet(wb, ws, "統計數據");
|
||||||
|
|
||||||
// 4. 写入 Excel 并下载
|
// 4. 写入 Excel 并下载
|
||||||
const wbout = XLSX.write(wb, { bookType: "xlsx", type: "array" });
|
const wbout = XLSX.write(wb, { bookType: "xlsx", type: "array" });
|
||||||
|
|||||||
@@ -105,5 +105,36 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- /.content_box -->
|
<!-- /.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>
|
</asp:Content>
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,104 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Services;
|
||||||
|
using System.Web.UI;
|
||||||
|
using System.Web.UI.WebControls;
|
||||||
|
|
||||||
|
// 定義與前端一致的元素結構
|
||||||
|
public class TabletElement
|
||||||
|
{
|
||||||
|
public string id { get; set; }
|
||||||
|
public string type { get; set; }
|
||||||
|
public string text { get; set; }
|
||||||
|
public double x { get; set; }
|
||||||
|
public double y { get; set; }
|
||||||
|
public double? width { get; set; }
|
||||||
|
public double? height { get; set; }
|
||||||
|
public ElementStyle style { get; set; }
|
||||||
|
public string hidden { get; set; }
|
||||||
|
public double? twoOffset { get; set; }
|
||||||
|
public double? threeOffset { get; set; }
|
||||||
|
public double? fourOffset { get; set; }
|
||||||
|
public int? breakLen { get; set; }
|
||||||
|
public string backendInp { get; set; }
|
||||||
|
public double? textWidth { get; set; }
|
||||||
|
public double? textHeight { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ElementStyle
|
||||||
|
{
|
||||||
|
public double fontSize { get; set; }
|
||||||
|
public string fontFamily { get; set; }
|
||||||
|
public bool isVertical { get; set; }
|
||||||
|
public double letterSpacing { get; set; }
|
||||||
|
public double lineHeight { get; set; }
|
||||||
|
public double? itemSpacing { get; set; }
|
||||||
|
public string visibility { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class admin_item_TabletDesigner :MyWeb.config
|
||||||
|
{
|
||||||
|
|
||||||
|
protected void Page_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
[WebMethod]
|
||||||
|
public static string SaveDesigner()
|
||||||
|
{
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
[WebMethod]
|
||||||
|
public static string GetConfig()
|
||||||
|
{
|
||||||
|
// 模擬原本的 GetConfig() 行為
|
||||||
|
var config = new
|
||||||
|
{
|
||||||
|
elements = new List<TabletElement> {
|
||||||
|
new TabletElement {
|
||||||
|
id = "address", type = "address", text = "台中市潭子區中山路", x = 60, y = 80,
|
||||||
|
style = new ElementStyle { fontSize = 24, fontFamily = "Kaiti", isVertical = true, letterSpacing = 5, lineHeight = 1.5,visibility="" }
|
||||||
|
},
|
||||||
|
new TabletElement {
|
||||||
|
id = "title1", type = "ancestor", text = "張一\n李二\n陳三\n吳四\n劉五\n趙六\n林七\n徐八", x = 50, y = 80,
|
||||||
|
width=136,height=600,textWidth=20,textHeight=90,
|
||||||
|
style = new ElementStyle { fontSize = 16, fontFamily = "Kaiti", isVertical = true, letterSpacing = 1, lineHeight = 1 ,visibility="" }
|
||||||
|
},
|
||||||
|
new TabletElement {
|
||||||
|
id = "lefttitle", type = "ancestor", text = "左正名", x = 10, y = 80,
|
||||||
|
style = new ElementStyle { fontSize = 24, fontFamily = "Kaiti", isVertical = true, letterSpacing = 5, lineHeight = 1.5 ,visibility="" }
|
||||||
|
},
|
||||||
|
new TabletElement {
|
||||||
|
id = "righttitle", type = "ancestor", text = "右正名", x = 50, y = 80,
|
||||||
|
style = new ElementStyle { fontSize = 24, fontFamily = "Kaiti", isVertical = true, letterSpacing = 5, lineHeight = 1.5 ,visibility="" }
|
||||||
|
},
|
||||||
|
new TabletElement {
|
||||||
|
id = "titletriangle", type = "roster", text = "張一\n李二\n陳三\n吳四\n劉五\n趙六\n林七\n徐八", x = 10, y = 80,
|
||||||
|
style = new ElementStyle { fontSize = 24, fontFamily = "Kaiti", isVertical = true, letterSpacing = 5, lineHeight = 1.5,visibility="" }
|
||||||
|
},
|
||||||
|
new TabletElement
|
||||||
|
{
|
||||||
|
id="tricombined",type="combined-center",text="林張吳\n氏歷代祖先", x = 10, y = 80,
|
||||||
|
style = new ElementStyle { fontSize = 24, fontFamily = "Kaiti", isVertical = true, letterSpacing = 5, lineHeight = 1.5 ,visibility="" }
|
||||||
|
},
|
||||||
|
new TabletElement
|
||||||
|
{
|
||||||
|
id="combined",type="combined-center",text="李王\n氏歷代祖先", x = 10, y = 80,
|
||||||
|
style = new ElementStyle { fontSize = 24, fontFamily = "Kaiti", isVertical = true, letterSpacing = 5, lineHeight = 1.5 ,visibility="" }
|
||||||
|
},
|
||||||
|
new TabletElement
|
||||||
|
{
|
||||||
|
id="alive",type="alive",text="陽上名字", x = 60, y = 200,
|
||||||
|
style = new ElementStyle { fontSize = 18, fontFamily = "Kaiti", isVertical = true, letterSpacing = 5, lineHeight = 1.5 ,visibility="" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
paper = new { width = 100, height = 272, name = "Yellow" }
|
||||||
|
};
|
||||||
|
return JsonConvert.SerializeObject(config);
|
||||||
|
}
|
||||||
|
}
|
||||||
+4085
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+4084
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+601
@@ -0,0 +1,601 @@
|
|||||||
|
/*!
|
||||||
|
* Bootstrap Reboot v5.3.8 (https://getbootstrap.com/)
|
||||||
|
* Copyright 2011-2025 The Bootstrap Authors
|
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||||
|
*/
|
||||||
|
:root,
|
||||||
|
[data-bs-theme=light] {
|
||||||
|
--bs-blue: #0d6efd;
|
||||||
|
--bs-indigo: #6610f2;
|
||||||
|
--bs-purple: #6f42c1;
|
||||||
|
--bs-pink: #d63384;
|
||||||
|
--bs-red: #dc3545;
|
||||||
|
--bs-orange: #fd7e14;
|
||||||
|
--bs-yellow: #ffc107;
|
||||||
|
--bs-green: #198754;
|
||||||
|
--bs-teal: #20c997;
|
||||||
|
--bs-cyan: #0dcaf0;
|
||||||
|
--bs-black: #000;
|
||||||
|
--bs-white: #fff;
|
||||||
|
--bs-gray: #6c757d;
|
||||||
|
--bs-gray-dark: #343a40;
|
||||||
|
--bs-gray-100: #f8f9fa;
|
||||||
|
--bs-gray-200: #e9ecef;
|
||||||
|
--bs-gray-300: #dee2e6;
|
||||||
|
--bs-gray-400: #ced4da;
|
||||||
|
--bs-gray-500: #adb5bd;
|
||||||
|
--bs-gray-600: #6c757d;
|
||||||
|
--bs-gray-700: #495057;
|
||||||
|
--bs-gray-800: #343a40;
|
||||||
|
--bs-gray-900: #212529;
|
||||||
|
--bs-primary: #0d6efd;
|
||||||
|
--bs-secondary: #6c757d;
|
||||||
|
--bs-success: #198754;
|
||||||
|
--bs-info: #0dcaf0;
|
||||||
|
--bs-warning: #ffc107;
|
||||||
|
--bs-danger: #dc3545;
|
||||||
|
--bs-light: #f8f9fa;
|
||||||
|
--bs-dark: #212529;
|
||||||
|
--bs-primary-rgb: 13, 110, 253;
|
||||||
|
--bs-secondary-rgb: 108, 117, 125;
|
||||||
|
--bs-success-rgb: 25, 135, 84;
|
||||||
|
--bs-info-rgb: 13, 202, 240;
|
||||||
|
--bs-warning-rgb: 255, 193, 7;
|
||||||
|
--bs-danger-rgb: 220, 53, 69;
|
||||||
|
--bs-light-rgb: 248, 249, 250;
|
||||||
|
--bs-dark-rgb: 33, 37, 41;
|
||||||
|
--bs-primary-text-emphasis: #052c65;
|
||||||
|
--bs-secondary-text-emphasis: #2b2f32;
|
||||||
|
--bs-success-text-emphasis: #0a3622;
|
||||||
|
--bs-info-text-emphasis: #055160;
|
||||||
|
--bs-warning-text-emphasis: #664d03;
|
||||||
|
--bs-danger-text-emphasis: #58151c;
|
||||||
|
--bs-light-text-emphasis: #495057;
|
||||||
|
--bs-dark-text-emphasis: #495057;
|
||||||
|
--bs-primary-bg-subtle: #cfe2ff;
|
||||||
|
--bs-secondary-bg-subtle: #e2e3e5;
|
||||||
|
--bs-success-bg-subtle: #d1e7dd;
|
||||||
|
--bs-info-bg-subtle: #cff4fc;
|
||||||
|
--bs-warning-bg-subtle: #fff3cd;
|
||||||
|
--bs-danger-bg-subtle: #f8d7da;
|
||||||
|
--bs-light-bg-subtle: #fcfcfd;
|
||||||
|
--bs-dark-bg-subtle: #ced4da;
|
||||||
|
--bs-primary-border-subtle: #9ec5fe;
|
||||||
|
--bs-secondary-border-subtle: #c4c8cb;
|
||||||
|
--bs-success-border-subtle: #a3cfbb;
|
||||||
|
--bs-info-border-subtle: #9eeaf9;
|
||||||
|
--bs-warning-border-subtle: #ffe69c;
|
||||||
|
--bs-danger-border-subtle: #f1aeb5;
|
||||||
|
--bs-light-border-subtle: #e9ecef;
|
||||||
|
--bs-dark-border-subtle: #adb5bd;
|
||||||
|
--bs-white-rgb: 255, 255, 255;
|
||||||
|
--bs-black-rgb: 0, 0, 0;
|
||||||
|
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||||
|
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||||
|
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
||||||
|
--bs-body-font-family: var(--bs-font-sans-serif);
|
||||||
|
--bs-body-font-size: 1rem;
|
||||||
|
--bs-body-font-weight: 400;
|
||||||
|
--bs-body-line-height: 1.5;
|
||||||
|
--bs-body-color: #212529;
|
||||||
|
--bs-body-color-rgb: 33, 37, 41;
|
||||||
|
--bs-body-bg: #fff;
|
||||||
|
--bs-body-bg-rgb: 255, 255, 255;
|
||||||
|
--bs-emphasis-color: #000;
|
||||||
|
--bs-emphasis-color-rgb: 0, 0, 0;
|
||||||
|
--bs-secondary-color: rgba(33, 37, 41, 0.75);
|
||||||
|
--bs-secondary-color-rgb: 33, 37, 41;
|
||||||
|
--bs-secondary-bg: #e9ecef;
|
||||||
|
--bs-secondary-bg-rgb: 233, 236, 239;
|
||||||
|
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
|
||||||
|
--bs-tertiary-color-rgb: 33, 37, 41;
|
||||||
|
--bs-tertiary-bg: #f8f9fa;
|
||||||
|
--bs-tertiary-bg-rgb: 248, 249, 250;
|
||||||
|
--bs-heading-color: inherit;
|
||||||
|
--bs-link-color: #0d6efd;
|
||||||
|
--bs-link-color-rgb: 13, 110, 253;
|
||||||
|
--bs-link-decoration: underline;
|
||||||
|
--bs-link-hover-color: #0a58ca;
|
||||||
|
--bs-link-hover-color-rgb: 10, 88, 202;
|
||||||
|
--bs-code-color: #d63384;
|
||||||
|
--bs-highlight-color: #212529;
|
||||||
|
--bs-highlight-bg: #fff3cd;
|
||||||
|
--bs-border-width: 1px;
|
||||||
|
--bs-border-style: solid;
|
||||||
|
--bs-border-color: #dee2e6;
|
||||||
|
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
|
||||||
|
--bs-border-radius: 0.375rem;
|
||||||
|
--bs-border-radius-sm: 0.25rem;
|
||||||
|
--bs-border-radius-lg: 0.5rem;
|
||||||
|
--bs-border-radius-xl: 1rem;
|
||||||
|
--bs-border-radius-xxl: 2rem;
|
||||||
|
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
|
||||||
|
--bs-border-radius-pill: 50rem;
|
||||||
|
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
||||||
|
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
||||||
|
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
|
||||||
|
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
|
||||||
|
--bs-focus-ring-width: 0.25rem;
|
||||||
|
--bs-focus-ring-opacity: 0.25;
|
||||||
|
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
|
||||||
|
--bs-form-valid-color: #198754;
|
||||||
|
--bs-form-valid-border-color: #198754;
|
||||||
|
--bs-form-invalid-color: #dc3545;
|
||||||
|
--bs-form-invalid-border-color: #dc3545;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-bs-theme=dark] {
|
||||||
|
color-scheme: dark;
|
||||||
|
--bs-body-color: #dee2e6;
|
||||||
|
--bs-body-color-rgb: 222, 226, 230;
|
||||||
|
--bs-body-bg: #212529;
|
||||||
|
--bs-body-bg-rgb: 33, 37, 41;
|
||||||
|
--bs-emphasis-color: #fff;
|
||||||
|
--bs-emphasis-color-rgb: 255, 255, 255;
|
||||||
|
--bs-secondary-color: rgba(222, 226, 230, 0.75);
|
||||||
|
--bs-secondary-color-rgb: 222, 226, 230;
|
||||||
|
--bs-secondary-bg: #343a40;
|
||||||
|
--bs-secondary-bg-rgb: 52, 58, 64;
|
||||||
|
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
|
||||||
|
--bs-tertiary-color-rgb: 222, 226, 230;
|
||||||
|
--bs-tertiary-bg: #2b3035;
|
||||||
|
--bs-tertiary-bg-rgb: 43, 48, 53;
|
||||||
|
--bs-primary-text-emphasis: #6ea8fe;
|
||||||
|
--bs-secondary-text-emphasis: #a7acb1;
|
||||||
|
--bs-success-text-emphasis: #75b798;
|
||||||
|
--bs-info-text-emphasis: #6edff6;
|
||||||
|
--bs-warning-text-emphasis: #ffda6a;
|
||||||
|
--bs-danger-text-emphasis: #ea868f;
|
||||||
|
--bs-light-text-emphasis: #f8f9fa;
|
||||||
|
--bs-dark-text-emphasis: #dee2e6;
|
||||||
|
--bs-primary-bg-subtle: #031633;
|
||||||
|
--bs-secondary-bg-subtle: #161719;
|
||||||
|
--bs-success-bg-subtle: #051b11;
|
||||||
|
--bs-info-bg-subtle: #032830;
|
||||||
|
--bs-warning-bg-subtle: #332701;
|
||||||
|
--bs-danger-bg-subtle: #2c0b0e;
|
||||||
|
--bs-light-bg-subtle: #343a40;
|
||||||
|
--bs-dark-bg-subtle: #1a1d20;
|
||||||
|
--bs-primary-border-subtle: #084298;
|
||||||
|
--bs-secondary-border-subtle: #41464b;
|
||||||
|
--bs-success-border-subtle: #0f5132;
|
||||||
|
--bs-info-border-subtle: #087990;
|
||||||
|
--bs-warning-border-subtle: #997404;
|
||||||
|
--bs-danger-border-subtle: #842029;
|
||||||
|
--bs-light-border-subtle: #495057;
|
||||||
|
--bs-dark-border-subtle: #343a40;
|
||||||
|
--bs-heading-color: inherit;
|
||||||
|
--bs-link-color: #6ea8fe;
|
||||||
|
--bs-link-hover-color: #8bb9fe;
|
||||||
|
--bs-link-color-rgb: 110, 168, 254;
|
||||||
|
--bs-link-hover-color-rgb: 139, 185, 254;
|
||||||
|
--bs-code-color: #e685b5;
|
||||||
|
--bs-highlight-color: #dee2e6;
|
||||||
|
--bs-highlight-bg: #664d03;
|
||||||
|
--bs-border-color: #495057;
|
||||||
|
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
|
||||||
|
--bs-form-valid-color: #75b798;
|
||||||
|
--bs-form-valid-border-color: #75b798;
|
||||||
|
--bs-form-invalid-color: #ea868f;
|
||||||
|
--bs-form-invalid-border-color: #ea868f;
|
||||||
|
}
|
||||||
|
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
:root {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: var(--bs-body-font-family);
|
||||||
|
font-size: var(--bs-body-font-size);
|
||||||
|
font-weight: var(--bs-body-font-weight);
|
||||||
|
line-height: var(--bs-body-line-height);
|
||||||
|
color: var(--bs-body-color);
|
||||||
|
text-align: var(--bs-body-text-align);
|
||||||
|
background-color: var(--bs-body-bg);
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
margin: 1rem 0;
|
||||||
|
color: inherit;
|
||||||
|
border: 0;
|
||||||
|
border-top: var(--bs-border-width) solid;
|
||||||
|
opacity: 0.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6, h5, h4, h3, h2, h1 {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.2;
|
||||||
|
color: var(--bs-heading-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: calc(1.375rem + 1.5vw);
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
h1 {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: calc(1.325rem + 0.9vw);
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
h2 {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: calc(1.3rem + 0.6vw);
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
h3 {
|
||||||
|
font-size: 1.75rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: calc(1.275rem + 0.3vw);
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
h4 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
abbr[title] {
|
||||||
|
-webkit-text-decoration: underline dotted;
|
||||||
|
text-decoration: underline dotted;
|
||||||
|
cursor: help;
|
||||||
|
-webkit-text-decoration-skip-ink: none;
|
||||||
|
text-decoration-skip-ink: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
address {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
font-style: normal;
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol,
|
||||||
|
ul {
|
||||||
|
padding-left: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol,
|
||||||
|
ul,
|
||||||
|
dl {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol ol,
|
||||||
|
ul ul,
|
||||||
|
ol ul,
|
||||||
|
ul ol {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dt {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
dd {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
margin: 0 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
b,
|
||||||
|
strong {
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size: 0.875em;
|
||||||
|
}
|
||||||
|
|
||||||
|
mark {
|
||||||
|
padding: 0.1875em;
|
||||||
|
color: var(--bs-highlight-color);
|
||||||
|
background-color: var(--bs-highlight-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub,
|
||||||
|
sup {
|
||||||
|
position: relative;
|
||||||
|
font-size: 0.75em;
|
||||||
|
line-height: 0;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub {
|
||||||
|
bottom: -0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
sup {
|
||||||
|
top: -0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre,
|
||||||
|
code,
|
||||||
|
kbd,
|
||||||
|
samp {
|
||||||
|
font-family: var(--bs-font-monospace);
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
display: block;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
overflow: auto;
|
||||||
|
font-size: 0.875em;
|
||||||
|
}
|
||||||
|
pre code {
|
||||||
|
font-size: inherit;
|
||||||
|
color: inherit;
|
||||||
|
word-break: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-size: 0.875em;
|
||||||
|
color: var(--bs-code-color);
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
a > code {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
kbd {
|
||||||
|
padding: 0.1875rem 0.375rem;
|
||||||
|
font-size: 0.875em;
|
||||||
|
color: var(--bs-body-bg);
|
||||||
|
background-color: var(--bs-body-color);
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
}
|
||||||
|
kbd kbd {
|
||||||
|
padding: 0;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
figure {
|
||||||
|
margin: 0 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
img,
|
||||||
|
svg {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
caption-side: bottom;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
caption {
|
||||||
|
padding-top: 0.5rem;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
color: var(--bs-secondary-color);
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
text-align: inherit;
|
||||||
|
text-align: -webkit-match-parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead,
|
||||||
|
tbody,
|
||||||
|
tfoot,
|
||||||
|
tr,
|
||||||
|
td,
|
||||||
|
th {
|
||||||
|
border-color: inherit;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:focus:not(:focus-visible) {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
button,
|
||||||
|
select,
|
||||||
|
optgroup,
|
||||||
|
textarea {
|
||||||
|
margin: 0;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
select {
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
[role=button] {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
word-wrap: normal;
|
||||||
|
}
|
||||||
|
select:disabled {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
[type=button],
|
||||||
|
[type=reset],
|
||||||
|
[type=submit] {
|
||||||
|
-webkit-appearance: button;
|
||||||
|
}
|
||||||
|
button:not(:disabled),
|
||||||
|
[type=button]:not(:disabled),
|
||||||
|
[type=reset]:not(:disabled),
|
||||||
|
[type=submit]:not(:disabled) {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-moz-focus-inner {
|
||||||
|
padding: 0;
|
||||||
|
border-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
min-width: 0;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
legend {
|
||||||
|
float: left;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
line-height: inherit;
|
||||||
|
font-size: calc(1.275rem + 0.3vw);
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
legend {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
legend + * {
|
||||||
|
clear: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-datetime-edit-fields-wrapper,
|
||||||
|
::-webkit-datetime-edit-text,
|
||||||
|
::-webkit-datetime-edit-minute,
|
||||||
|
::-webkit-datetime-edit-hour-field,
|
||||||
|
::-webkit-datetime-edit-day-field,
|
||||||
|
::-webkit-datetime-edit-month-field,
|
||||||
|
::-webkit-datetime-edit-year-field {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-inner-spin-button {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
[type=search] {
|
||||||
|
-webkit-appearance: textfield;
|
||||||
|
outline-offset: -2px;
|
||||||
|
}
|
||||||
|
[type=search]::-webkit-search-cancel-button {
|
||||||
|
cursor: pointer;
|
||||||
|
filter: grayscale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* rtl:raw:
|
||||||
|
[type="tel"],
|
||||||
|
[type="url"],
|
||||||
|
[type="email"],
|
||||||
|
[type="number"] {
|
||||||
|
direction: ltr;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
::-webkit-search-decoration {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-color-swatch-wrapper {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-file-upload-button {
|
||||||
|
font: inherit;
|
||||||
|
-webkit-appearance: button;
|
||||||
|
}
|
||||||
|
|
||||||
|
::file-selector-button {
|
||||||
|
font: inherit;
|
||||||
|
-webkit-appearance: button;
|
||||||
|
}
|
||||||
|
|
||||||
|
output {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
iframe {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
summary {
|
||||||
|
display: list-item;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress {
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
[hidden] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*# sourceMappingURL=bootstrap-reboot.css.map */
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,598 @@
|
|||||||
|
/*!
|
||||||
|
* Bootstrap Reboot v5.3.8 (https://getbootstrap.com/)
|
||||||
|
* Copyright 2011-2025 The Bootstrap Authors
|
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||||
|
*/
|
||||||
|
:root,
|
||||||
|
[data-bs-theme=light] {
|
||||||
|
--bs-blue: #0d6efd;
|
||||||
|
--bs-indigo: #6610f2;
|
||||||
|
--bs-purple: #6f42c1;
|
||||||
|
--bs-pink: #d63384;
|
||||||
|
--bs-red: #dc3545;
|
||||||
|
--bs-orange: #fd7e14;
|
||||||
|
--bs-yellow: #ffc107;
|
||||||
|
--bs-green: #198754;
|
||||||
|
--bs-teal: #20c997;
|
||||||
|
--bs-cyan: #0dcaf0;
|
||||||
|
--bs-black: #000;
|
||||||
|
--bs-white: #fff;
|
||||||
|
--bs-gray: #6c757d;
|
||||||
|
--bs-gray-dark: #343a40;
|
||||||
|
--bs-gray-100: #f8f9fa;
|
||||||
|
--bs-gray-200: #e9ecef;
|
||||||
|
--bs-gray-300: #dee2e6;
|
||||||
|
--bs-gray-400: #ced4da;
|
||||||
|
--bs-gray-500: #adb5bd;
|
||||||
|
--bs-gray-600: #6c757d;
|
||||||
|
--bs-gray-700: #495057;
|
||||||
|
--bs-gray-800: #343a40;
|
||||||
|
--bs-gray-900: #212529;
|
||||||
|
--bs-primary: #0d6efd;
|
||||||
|
--bs-secondary: #6c757d;
|
||||||
|
--bs-success: #198754;
|
||||||
|
--bs-info: #0dcaf0;
|
||||||
|
--bs-warning: #ffc107;
|
||||||
|
--bs-danger: #dc3545;
|
||||||
|
--bs-light: #f8f9fa;
|
||||||
|
--bs-dark: #212529;
|
||||||
|
--bs-primary-rgb: 13, 110, 253;
|
||||||
|
--bs-secondary-rgb: 108, 117, 125;
|
||||||
|
--bs-success-rgb: 25, 135, 84;
|
||||||
|
--bs-info-rgb: 13, 202, 240;
|
||||||
|
--bs-warning-rgb: 255, 193, 7;
|
||||||
|
--bs-danger-rgb: 220, 53, 69;
|
||||||
|
--bs-light-rgb: 248, 249, 250;
|
||||||
|
--bs-dark-rgb: 33, 37, 41;
|
||||||
|
--bs-primary-text-emphasis: #052c65;
|
||||||
|
--bs-secondary-text-emphasis: #2b2f32;
|
||||||
|
--bs-success-text-emphasis: #0a3622;
|
||||||
|
--bs-info-text-emphasis: #055160;
|
||||||
|
--bs-warning-text-emphasis: #664d03;
|
||||||
|
--bs-danger-text-emphasis: #58151c;
|
||||||
|
--bs-light-text-emphasis: #495057;
|
||||||
|
--bs-dark-text-emphasis: #495057;
|
||||||
|
--bs-primary-bg-subtle: #cfe2ff;
|
||||||
|
--bs-secondary-bg-subtle: #e2e3e5;
|
||||||
|
--bs-success-bg-subtle: #d1e7dd;
|
||||||
|
--bs-info-bg-subtle: #cff4fc;
|
||||||
|
--bs-warning-bg-subtle: #fff3cd;
|
||||||
|
--bs-danger-bg-subtle: #f8d7da;
|
||||||
|
--bs-light-bg-subtle: #fcfcfd;
|
||||||
|
--bs-dark-bg-subtle: #ced4da;
|
||||||
|
--bs-primary-border-subtle: #9ec5fe;
|
||||||
|
--bs-secondary-border-subtle: #c4c8cb;
|
||||||
|
--bs-success-border-subtle: #a3cfbb;
|
||||||
|
--bs-info-border-subtle: #9eeaf9;
|
||||||
|
--bs-warning-border-subtle: #ffe69c;
|
||||||
|
--bs-danger-border-subtle: #f1aeb5;
|
||||||
|
--bs-light-border-subtle: #e9ecef;
|
||||||
|
--bs-dark-border-subtle: #adb5bd;
|
||||||
|
--bs-white-rgb: 255, 255, 255;
|
||||||
|
--bs-black-rgb: 0, 0, 0;
|
||||||
|
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||||
|
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||||
|
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
||||||
|
--bs-body-font-family: var(--bs-font-sans-serif);
|
||||||
|
--bs-body-font-size: 1rem;
|
||||||
|
--bs-body-font-weight: 400;
|
||||||
|
--bs-body-line-height: 1.5;
|
||||||
|
--bs-body-color: #212529;
|
||||||
|
--bs-body-color-rgb: 33, 37, 41;
|
||||||
|
--bs-body-bg: #fff;
|
||||||
|
--bs-body-bg-rgb: 255, 255, 255;
|
||||||
|
--bs-emphasis-color: #000;
|
||||||
|
--bs-emphasis-color-rgb: 0, 0, 0;
|
||||||
|
--bs-secondary-color: rgba(33, 37, 41, 0.75);
|
||||||
|
--bs-secondary-color-rgb: 33, 37, 41;
|
||||||
|
--bs-secondary-bg: #e9ecef;
|
||||||
|
--bs-secondary-bg-rgb: 233, 236, 239;
|
||||||
|
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
|
||||||
|
--bs-tertiary-color-rgb: 33, 37, 41;
|
||||||
|
--bs-tertiary-bg: #f8f9fa;
|
||||||
|
--bs-tertiary-bg-rgb: 248, 249, 250;
|
||||||
|
--bs-heading-color: inherit;
|
||||||
|
--bs-link-color: #0d6efd;
|
||||||
|
--bs-link-color-rgb: 13, 110, 253;
|
||||||
|
--bs-link-decoration: underline;
|
||||||
|
--bs-link-hover-color: #0a58ca;
|
||||||
|
--bs-link-hover-color-rgb: 10, 88, 202;
|
||||||
|
--bs-code-color: #d63384;
|
||||||
|
--bs-highlight-color: #212529;
|
||||||
|
--bs-highlight-bg: #fff3cd;
|
||||||
|
--bs-border-width: 1px;
|
||||||
|
--bs-border-style: solid;
|
||||||
|
--bs-border-color: #dee2e6;
|
||||||
|
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
|
||||||
|
--bs-border-radius: 0.375rem;
|
||||||
|
--bs-border-radius-sm: 0.25rem;
|
||||||
|
--bs-border-radius-lg: 0.5rem;
|
||||||
|
--bs-border-radius-xl: 1rem;
|
||||||
|
--bs-border-radius-xxl: 2rem;
|
||||||
|
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
|
||||||
|
--bs-border-radius-pill: 50rem;
|
||||||
|
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
||||||
|
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
||||||
|
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
|
||||||
|
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
|
||||||
|
--bs-focus-ring-width: 0.25rem;
|
||||||
|
--bs-focus-ring-opacity: 0.25;
|
||||||
|
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
|
||||||
|
--bs-form-valid-color: #198754;
|
||||||
|
--bs-form-valid-border-color: #198754;
|
||||||
|
--bs-form-invalid-color: #dc3545;
|
||||||
|
--bs-form-invalid-border-color: #dc3545;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-bs-theme=dark] {
|
||||||
|
color-scheme: dark;
|
||||||
|
--bs-body-color: #dee2e6;
|
||||||
|
--bs-body-color-rgb: 222, 226, 230;
|
||||||
|
--bs-body-bg: #212529;
|
||||||
|
--bs-body-bg-rgb: 33, 37, 41;
|
||||||
|
--bs-emphasis-color: #fff;
|
||||||
|
--bs-emphasis-color-rgb: 255, 255, 255;
|
||||||
|
--bs-secondary-color: rgba(222, 226, 230, 0.75);
|
||||||
|
--bs-secondary-color-rgb: 222, 226, 230;
|
||||||
|
--bs-secondary-bg: #343a40;
|
||||||
|
--bs-secondary-bg-rgb: 52, 58, 64;
|
||||||
|
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
|
||||||
|
--bs-tertiary-color-rgb: 222, 226, 230;
|
||||||
|
--bs-tertiary-bg: #2b3035;
|
||||||
|
--bs-tertiary-bg-rgb: 43, 48, 53;
|
||||||
|
--bs-primary-text-emphasis: #6ea8fe;
|
||||||
|
--bs-secondary-text-emphasis: #a7acb1;
|
||||||
|
--bs-success-text-emphasis: #75b798;
|
||||||
|
--bs-info-text-emphasis: #6edff6;
|
||||||
|
--bs-warning-text-emphasis: #ffda6a;
|
||||||
|
--bs-danger-text-emphasis: #ea868f;
|
||||||
|
--bs-light-text-emphasis: #f8f9fa;
|
||||||
|
--bs-dark-text-emphasis: #dee2e6;
|
||||||
|
--bs-primary-bg-subtle: #031633;
|
||||||
|
--bs-secondary-bg-subtle: #161719;
|
||||||
|
--bs-success-bg-subtle: #051b11;
|
||||||
|
--bs-info-bg-subtle: #032830;
|
||||||
|
--bs-warning-bg-subtle: #332701;
|
||||||
|
--bs-danger-bg-subtle: #2c0b0e;
|
||||||
|
--bs-light-bg-subtle: #343a40;
|
||||||
|
--bs-dark-bg-subtle: #1a1d20;
|
||||||
|
--bs-primary-border-subtle: #084298;
|
||||||
|
--bs-secondary-border-subtle: #41464b;
|
||||||
|
--bs-success-border-subtle: #0f5132;
|
||||||
|
--bs-info-border-subtle: #087990;
|
||||||
|
--bs-warning-border-subtle: #997404;
|
||||||
|
--bs-danger-border-subtle: #842029;
|
||||||
|
--bs-light-border-subtle: #495057;
|
||||||
|
--bs-dark-border-subtle: #343a40;
|
||||||
|
--bs-heading-color: inherit;
|
||||||
|
--bs-link-color: #6ea8fe;
|
||||||
|
--bs-link-hover-color: #8bb9fe;
|
||||||
|
--bs-link-color-rgb: 110, 168, 254;
|
||||||
|
--bs-link-hover-color-rgb: 139, 185, 254;
|
||||||
|
--bs-code-color: #e685b5;
|
||||||
|
--bs-highlight-color: #dee2e6;
|
||||||
|
--bs-highlight-bg: #664d03;
|
||||||
|
--bs-border-color: #495057;
|
||||||
|
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
|
||||||
|
--bs-form-valid-color: #75b798;
|
||||||
|
--bs-form-valid-border-color: #75b798;
|
||||||
|
--bs-form-invalid-color: #ea868f;
|
||||||
|
--bs-form-invalid-border-color: #ea868f;
|
||||||
|
}
|
||||||
|
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
:root {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: var(--bs-body-font-family);
|
||||||
|
font-size: var(--bs-body-font-size);
|
||||||
|
font-weight: var(--bs-body-font-weight);
|
||||||
|
line-height: var(--bs-body-line-height);
|
||||||
|
color: var(--bs-body-color);
|
||||||
|
text-align: var(--bs-body-text-align);
|
||||||
|
background-color: var(--bs-body-bg);
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
margin: 1rem 0;
|
||||||
|
color: inherit;
|
||||||
|
border: 0;
|
||||||
|
border-top: var(--bs-border-width) solid;
|
||||||
|
opacity: 0.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6, h5, h4, h3, h2, h1 {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.2;
|
||||||
|
color: var(--bs-heading-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: calc(1.375rem + 1.5vw);
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
h1 {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: calc(1.325rem + 0.9vw);
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
h2 {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: calc(1.3rem + 0.6vw);
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
h3 {
|
||||||
|
font-size: 1.75rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: calc(1.275rem + 0.3vw);
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
h4 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
abbr[title] {
|
||||||
|
-webkit-text-decoration: underline dotted;
|
||||||
|
text-decoration: underline dotted;
|
||||||
|
cursor: help;
|
||||||
|
-webkit-text-decoration-skip-ink: none;
|
||||||
|
text-decoration-skip-ink: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
address {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
font-style: normal;
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol,
|
||||||
|
ul {
|
||||||
|
padding-right: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol,
|
||||||
|
ul,
|
||||||
|
dl {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol ol,
|
||||||
|
ul ul,
|
||||||
|
ol ul,
|
||||||
|
ul ol {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dt {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
dd {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
margin: 0 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
b,
|
||||||
|
strong {
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size: 0.875em;
|
||||||
|
}
|
||||||
|
|
||||||
|
mark {
|
||||||
|
padding: 0.1875em;
|
||||||
|
color: var(--bs-highlight-color);
|
||||||
|
background-color: var(--bs-highlight-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub,
|
||||||
|
sup {
|
||||||
|
position: relative;
|
||||||
|
font-size: 0.75em;
|
||||||
|
line-height: 0;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub {
|
||||||
|
bottom: -0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
sup {
|
||||||
|
top: -0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre,
|
||||||
|
code,
|
||||||
|
kbd,
|
||||||
|
samp {
|
||||||
|
font-family: var(--bs-font-monospace);
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
display: block;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
overflow: auto;
|
||||||
|
font-size: 0.875em;
|
||||||
|
}
|
||||||
|
pre code {
|
||||||
|
font-size: inherit;
|
||||||
|
color: inherit;
|
||||||
|
word-break: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-size: 0.875em;
|
||||||
|
color: var(--bs-code-color);
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
a > code {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
kbd {
|
||||||
|
padding: 0.1875rem 0.375rem;
|
||||||
|
font-size: 0.875em;
|
||||||
|
color: var(--bs-body-bg);
|
||||||
|
background-color: var(--bs-body-color);
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
}
|
||||||
|
kbd kbd {
|
||||||
|
padding: 0;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
figure {
|
||||||
|
margin: 0 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
img,
|
||||||
|
svg {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
caption-side: bottom;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
caption {
|
||||||
|
padding-top: 0.5rem;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
color: var(--bs-secondary-color);
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
text-align: inherit;
|
||||||
|
text-align: -webkit-match-parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead,
|
||||||
|
tbody,
|
||||||
|
tfoot,
|
||||||
|
tr,
|
||||||
|
td,
|
||||||
|
th {
|
||||||
|
border-color: inherit;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:focus:not(:focus-visible) {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
button,
|
||||||
|
select,
|
||||||
|
optgroup,
|
||||||
|
textarea {
|
||||||
|
margin: 0;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
select {
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
[role=button] {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
word-wrap: normal;
|
||||||
|
}
|
||||||
|
select:disabled {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
[type=button],
|
||||||
|
[type=reset],
|
||||||
|
[type=submit] {
|
||||||
|
-webkit-appearance: button;
|
||||||
|
}
|
||||||
|
button:not(:disabled),
|
||||||
|
[type=button]:not(:disabled),
|
||||||
|
[type=reset]:not(:disabled),
|
||||||
|
[type=submit]:not(:disabled) {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-moz-focus-inner {
|
||||||
|
padding: 0;
|
||||||
|
border-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
min-width: 0;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
legend {
|
||||||
|
float: right;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
line-height: inherit;
|
||||||
|
font-size: calc(1.275rem + 0.3vw);
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
legend {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
legend + * {
|
||||||
|
clear: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-datetime-edit-fields-wrapper,
|
||||||
|
::-webkit-datetime-edit-text,
|
||||||
|
::-webkit-datetime-edit-minute,
|
||||||
|
::-webkit-datetime-edit-hour-field,
|
||||||
|
::-webkit-datetime-edit-day-field,
|
||||||
|
::-webkit-datetime-edit-month-field,
|
||||||
|
::-webkit-datetime-edit-year-field {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-inner-spin-button {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
[type=search] {
|
||||||
|
-webkit-appearance: textfield;
|
||||||
|
outline-offset: -2px;
|
||||||
|
}
|
||||||
|
[type=search]::-webkit-search-cancel-button {
|
||||||
|
cursor: pointer;
|
||||||
|
filter: grayscale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[type="tel"],
|
||||||
|
[type="url"],
|
||||||
|
[type="email"],
|
||||||
|
[type="number"] {
|
||||||
|
direction: ltr;
|
||||||
|
}
|
||||||
|
::-webkit-search-decoration {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-color-swatch-wrapper {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-file-upload-button {
|
||||||
|
font: inherit;
|
||||||
|
-webkit-appearance: button;
|
||||||
|
}
|
||||||
|
|
||||||
|
::file-selector-button {
|
||||||
|
font: inherit;
|
||||||
|
-webkit-appearance: button;
|
||||||
|
}
|
||||||
|
|
||||||
|
output {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
iframe {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
summary {
|
||||||
|
display: list-item;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress {
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
[hidden] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
/*# sourceMappingURL=bootstrap-reboot.rtl.css.map */
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+5406
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+12048
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+12021
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+6312
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+4447
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+4494
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,6 @@
|
|||||||
|
.floating-box{
|
||||||
|
position:fixed;
|
||||||
|
width:260px;
|
||||||
|
z-index:9999;
|
||||||
|
max-height:calc(100vh-100px);
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/* You can add global styles to this file, and also import other style files */
|
||||||
|
|
||||||
|
/*@import "bootstrap/scss/bootstrap";
|
||||||
|
@import "bootstrap-icons/font/bootstrap-icons";*/
|
||||||
|
|
||||||
|
// 3. 自定義全域樣式 (讓 Sidebar 滿版)
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
// 修正捲軸在 Dark mode 的顏色
|
||||||
|
&[data-bs-theme="dark"] {
|
||||||
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sidebar 固定寬度設定 (可依需求調整)
|
||||||
|
.sidebar {
|
||||||
|
width: 250px;
|
||||||
|
min-height: 100vh;
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
@include media-breakpoint-down(md) {
|
||||||
|
width: 100%; // 手機版變成全寬或隱藏
|
||||||
|
min-height: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
overflow-y: auto; // 內容區域獨立捲動
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="checkbox"]{
|
||||||
|
|
||||||
|
/* 1. Remove native styles */
|
||||||
|
-webkit-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
|
||||||
|
width: 25px !important;
|
||||||
|
height: 25px !important;
|
||||||
|
|
||||||
|
border: 2px solid #555; /* Your custom border */
|
||||||
|
border-radius: 4px; /* Optional: rounded corners */
|
||||||
|
outline: none;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
/* Layout for the checkmark */
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 8px;
|
||||||
|
vertical-align: middle;
|
||||||
|
background-color: white;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
$toast-max-width: 500px;
|
||||||
|
$toast-font-size: 1.5rem;
|
||||||
|
|
||||||
@@ -0,0 +1,250 @@
|
|||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
--canvas-bg: #f8f9fa;
|
||||||
|
--canvas-grid: #dee2e6;
|
||||||
|
--paper-bg: #fffbf0;
|
||||||
|
--paper-shadow: rgba(0,0,0,0.1);
|
||||||
|
--selection-color: #0d6efd;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host-context([data-bs-theme="dark"]) {
|
||||||
|
--canvas-bg: #0f1114;
|
||||||
|
--canvas-grid: #2b3035;
|
||||||
|
--paper-shadow: rgba(0,0,0,0.8);
|
||||||
|
/* 紙張保持米黃,因為它是實物模擬 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*.yangshang-wrapper {
|
||||||
|
display: flex !important;
|
||||||
|
flex-direction: row !important;*/ /* 垂直堆疊 */
|
||||||
|
/*justify-content: space-between !important;*/ /* 陽上與拜薦各據頂底 */
|
||||||
|
/*align-items: center !important;*/ /* 水平方向置中 */
|
||||||
|
/*height: 100% !important;
|
||||||
|
width: 100% !important;
|
||||||
|
writing-mode: vertical-rl !important;*/ /* 確保內部文字均為垂直書寫 */
|
||||||
|
/*text-orientation: upright !important;*/ /* 確保文字方向轉正 */
|
||||||
|
/*gap: 1px;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
.designer-root {
|
||||||
|
/* 防止瀏覽器預設捲動影響畫布 */
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.canvas-area {
|
||||||
|
background-color: var(--canvas-bg);
|
||||||
|
background-image: linear-gradient(45deg, var(--canvas-grid) 25%, transparent 25%), linear-gradient(-45deg, var(--canvas-grid) 25%, transparent 25%), linear-gradient(45deg, transparent 75%, var(--canvas-grid) 75%), linear-gradient(-45deg, transparent 75%, var(--canvas-grid) 75%);
|
||||||
|
background-size: 20px 20px;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
/* min-height: 100vw;*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.tablet-paper {
|
||||||
|
background-color: var(--paper-bg);
|
||||||
|
box-shadow: 0 10px 30px var(--paper-shadow);
|
||||||
|
transition: all 0.3s;
|
||||||
|
overflow: hidden;
|
||||||
|
/* 確保在列印時被視為一個分頁單元 */
|
||||||
|
page-break-inside: avoid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tablet-element {
|
||||||
|
cursor: move;
|
||||||
|
padding: 4px;
|
||||||
|
color: black !important; /* 強制墨水為黑色 */
|
||||||
|
border: 1px solid transparent;
|
||||||
|
transition: writing-mode 0.3s, transform 0.2s;
|
||||||
|
}
|
||||||
|
.tablet-element:hover { border-color: rgba(13, 110, 253, 0.3); }
|
||||||
|
|
||||||
|
|
||||||
|
/* 直書模式核心 */
|
||||||
|
.vertical-text {
|
||||||
|
writing-mode: vertical-rl;
|
||||||
|
text-orientation: mixed; /* 這是關鍵:中文直立,英文轉90度 */
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 縱中橫 (讓直書中的數字變成橫向) */
|
||||||
|
.tate-chu-yoko {
|
||||||
|
text-combine-upright: all; /* 擠在一起 */
|
||||||
|
/* 或者使用 digits 4 (但在某些瀏覽器支援度不一,all 比較保險) */
|
||||||
|
display: inline-block;
|
||||||
|
letter-spacing: 0; /* 數字之間不要有間距 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 名單金字塔佈局容器 */
|
||||||
|
.roster-container {
|
||||||
|
width: 100%; height: 600px;
|
||||||
|
writing-mode: vertical-rl; /* 直書 */
|
||||||
|
display: flex;
|
||||||
|
/*flex-direction: column;*/ /* 雖然是直書,但物理上我們是將「上層區」和「下層區」垂直堆疊 */
|
||||||
|
flex-direction: row; /* 上下分層 (Top / Bottom) */
|
||||||
|
align-items: center; /* 左右置中對齊 */
|
||||||
|
justify-content: center;
|
||||||
|
gap: 20px; /* 這是「上層」跟「下層」之間的距離,可以設大一點 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.roster-row {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row-reverse; /* 直書由右至左,所以 Row 要反向或依需求調整 */
|
||||||
|
justify-content: center;
|
||||||
|
gap: 8px; /* 名字之間的間距 */
|
||||||
|
margin-left: 10px; /* 上下排之間的間距 (因為是直書,margin-left 是物理上的左邊/下方) */
|
||||||
|
}
|
||||||
|
|
||||||
|
.name-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column; /* ★★★ 關鍵:這讓名字左右並排 ★★★ */
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
/* gap 由 HTML 動態綁定 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.roster-name {
|
||||||
|
text-orientation: upright;
|
||||||
|
/*font-weight: bold;*/
|
||||||
|
white-space: nowrap;
|
||||||
|
line-height: 1.2;
|
||||||
|
font-family: 'Kaiti', serif;
|
||||||
|
/* 確保名字本身不會佔據過多寬度導致間距看起來很大 */
|
||||||
|
width: fit-content;
|
||||||
|
height:200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 選取框 */
|
||||||
|
.selection-border {
|
||||||
|
position: absolute; top: -4px; left: -4px; right: -4px; bottom: -4px;
|
||||||
|
border: 2px solid var(--selection-color); pointer-events: none; z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resize-handle {
|
||||||
|
position: absolute; width: 10px; height: 10px; background: white;
|
||||||
|
border: 2px solid var(--selection-color); border-radius: 50%;
|
||||||
|
}
|
||||||
|
.top-left { top: -6px; left: -6px; } .top-right { top: -6px; right: -6px; }
|
||||||
|
.bottom-left { bottom: -6px; left: -6px; } .bottom-right { bottom: -6px; right: -6px; }
|
||||||
|
|
||||||
|
.x-small { font-size: 0.7rem; } .ls-1 { letter-spacing: 1px; }
|
||||||
|
.bg-gradient-primary { background: linear-gradient(135deg, #0d6efd 0%, #0043a8 100%); }
|
||||||
|
.bg-gradient-dark { background: linear-gradient(135deg, #212529 0%, #000000 100%); }
|
||||||
|
|
||||||
|
.page-info-badge {
|
||||||
|
background: rgba(255,255,255,0.9); padding: 5px 15px; border-radius: 20px; font-weight: bold; color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print Mode */
|
||||||
|
@media print {
|
||||||
|
app-floating-widget, .canvas-area, .page-info-badge { display: none !important; }
|
||||||
|
:host { display: block; background: white; }
|
||||||
|
|
||||||
|
.tablet-paper {
|
||||||
|
position: relative !important;
|
||||||
|
margin: 0;
|
||||||
|
page-break-after: always; /* 強制分頁 */
|
||||||
|
box-shadow: none !important; background: transparent !important;
|
||||||
|
width: 100% !important; height: 100% !important;
|
||||||
|
-webkit-print-color-adjust: exact; print-color-adjust: exact;
|
||||||
|
}
|
||||||
|
.tablet-paper:last-child { page-break-after: auto; }
|
||||||
|
|
||||||
|
.paper-size-label, .selection-border { display: none; }
|
||||||
|
|
||||||
|
/* 確保背景圖列印 */
|
||||||
|
img.bg-image-layer {
|
||||||
|
-webkit-print-color-adjust: exact; print-color-adjust: exact;
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.resizable-box {
|
||||||
|
width: 300px;
|
||||||
|
height: 200px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
|
||||||
|
/* 關鍵屬性 */
|
||||||
|
resize: both; /* 允許水平和垂直調整 (或是 horizontal, vertical) */
|
||||||
|
overflow: auto; /* 必須設定 overflow (非 visible) resize 才會生效 */
|
||||||
|
|
||||||
|
/* 選用:限制最小最大尺寸 */
|
||||||
|
min-width: 100px;
|
||||||
|
min-height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.combined-vertical-mode {
|
||||||
|
writing-mode: vertical-rl; /* 設定為直排 */
|
||||||
|
font-family: "KaiTi", "BiauKai", serif;
|
||||||
|
font-size: 48px;
|
||||||
|
font-weight: bold;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
/* 為了讓排版置中好看,可以加這行 */
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.combined {
|
||||||
|
/* --- 關鍵修改 --- */
|
||||||
|
|
||||||
|
/* 1. 取消原本的擠壓設定 */
|
||||||
|
text-combine-upright: none;
|
||||||
|
|
||||||
|
/* 2. 將這三個字改回「橫向排版」 */
|
||||||
|
writing-mode: horizontal-tb;
|
||||||
|
|
||||||
|
/* 3. 讓它變成一個區塊,這樣字體才會撐開空間,不會擠在一起 */
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
/* 4. (選用) 調整它跟下方直書文字的對齊方式 */
|
||||||
|
vertical-align: middle;
|
||||||
|
|
||||||
|
/* 5. (選用) 如果希望字與字之間稍微寬鬆一點 */
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.combined-small {
|
||||||
|
font-size: 32px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auto-wrap-text {
|
||||||
|
/* 1. 設定為直書模式 */
|
||||||
|
writing-mode: vertical-rl;
|
||||||
|
text-orientation: upright; /* 讓文字直立 */
|
||||||
|
|
||||||
|
/* 2. 關鍵:限制最大高度 */
|
||||||
|
/* 設定為 8em 代表大約 8 個字的高度,超過就會自動換行 */
|
||||||
|
max-height: 8em;
|
||||||
|
|
||||||
|
/* 3. 關鍵:允許換行 */
|
||||||
|
white-space: normal; /* 或 pre-wrap */
|
||||||
|
|
||||||
|
/* 4. 調整換行的方向與對齊 (選用) */
|
||||||
|
display: inline-block; /* 讓容器隨內容撐開 */
|
||||||
|
word-break: break-all; /* 確保長單字或連續文字也能強制切斷換行 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.ancestor-wrapper {
|
||||||
|
/* 重置為橫向流,這樣 column 才會是真正的上下堆疊 */
|
||||||
|
writing-mode: horizontal-tb;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center; /* 水平置中 */
|
||||||
|
justify-content: flex-start;
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-name {
|
||||||
|
line-height: 1.2;
|
||||||
|
/* 保持大字 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-text {
|
||||||
|
font-size: 0.6em; /* 縮小字體 */
|
||||||
|
line-height: 1.2;
|
||||||
|
margin-top: 4px; /* 與上方林張的間距 */
|
||||||
|
white-space: nowrap; /* 避免自動換行 */
|
||||||
|
writing-mode:vertical-rl
|
||||||
|
}
|
||||||
@@ -0,0 +1,384 @@
|
|||||||
|
Authors ordered by first contribution
|
||||||
|
A list of current team members is available at https://jqueryui.com/about
|
||||||
|
|
||||||
|
Paul Bakaus <paul.bakaus@gmail.com>
|
||||||
|
Richard Worth <rdworth@gmail.com>
|
||||||
|
Yehuda Katz <wycats@gmail.com>
|
||||||
|
Sean Catchpole <sean@sunsean.com>
|
||||||
|
John Resig <jeresig@gmail.com>
|
||||||
|
Tane Piper <piper.tane@gmail.com>
|
||||||
|
Dmitri Gaskin <dmitrig01@gmail.com>
|
||||||
|
Klaus Hartl <klaus.hartl@gmail.com>
|
||||||
|
Stefan Petre <stefan.petre@gmail.com>
|
||||||
|
Gilles van den Hoven <gilles@webunity.nl>
|
||||||
|
Micheil Bryan Smith <micheil@brandedcode.com>
|
||||||
|
Jörn Zaefferer <joern.zaefferer@gmail.com>
|
||||||
|
Marc Grabanski <m@marcgrabanski.com>
|
||||||
|
Keith Wood <kbwood@iinet.com.au>
|
||||||
|
Brandon Aaron <brandon.aaron@gmail.com>
|
||||||
|
Scott González <scott.gonzalez@gmail.com>
|
||||||
|
Eduardo Lundgren <eduardolundgren@gmail.com>
|
||||||
|
Aaron Eisenberger <aaronchi@gmail.com>
|
||||||
|
Joan Piedra <theneojp@gmail.com>
|
||||||
|
Bruno Basto <b.basto@gmail.com>
|
||||||
|
Remy Sharp <remy@leftlogic.com>
|
||||||
|
Bohdan Ganicky <bohdan.ganicky@gmail.com>
|
||||||
|
David Bolter <david.bolter@gmail.com>
|
||||||
|
Chi Cheng <cloudream@gmail.com>
|
||||||
|
Ca-Phun Ung <pazu2k@gmail.com>
|
||||||
|
Ariel Flesler <aflesler@gmail.com>
|
||||||
|
Maggie Wachs <maggie@filamentgroup.com>
|
||||||
|
Scott Jehl <scottjehl@gmail.com>
|
||||||
|
Todd Parker <todd@filamentgroup.com>
|
||||||
|
Andrew Powell <andrew@shellscape.org>
|
||||||
|
Brant Burnett <btburnett3@gmail.com>
|
||||||
|
Douglas Neiner <doug@dougneiner.com>
|
||||||
|
Paul Irish <paul.irish@gmail.com>
|
||||||
|
Ralph Whitbeck <ralph.whitbeck@gmail.com>
|
||||||
|
Thibault Duplessis <thibault.duplessis@gmail.com>
|
||||||
|
Dominique Vincent <dominique.vincent@toitl.com>
|
||||||
|
Jack Hsu <jack.hsu@gmail.com>
|
||||||
|
Adam Sontag <ajpiano@ajpiano.com>
|
||||||
|
Carl Fürstenberg <carl@excito.com>
|
||||||
|
Kevin Dalman <development@allpro.net>
|
||||||
|
Alberto Fernández Capel <afcapel@gmail.com>
|
||||||
|
Jacek Jędrzejewski (https://jacek.jedrzejewski.name)
|
||||||
|
Ting Kuei <ting@kuei.com>
|
||||||
|
Samuel Cormier-Iijima <sam@chide.it>
|
||||||
|
Jon Palmer <jonspalmer@gmail.com>
|
||||||
|
Ben Hollis <bhollis@amazon.com>
|
||||||
|
Justin MacCarthy <Justin@Rubystars.biz>
|
||||||
|
Eyal Kobrigo <kobrigo@hotmail.com>
|
||||||
|
Tiago Freire <tiago.freire@gmail.com>
|
||||||
|
Diego Tres <diegotres@gmail.com>
|
||||||
|
Holger Rüprich <holger@rueprich.de>
|
||||||
|
Ziling Zhao <zilingzhao@gmail.com>
|
||||||
|
Mike Alsup <malsup@gmail.com>
|
||||||
|
Robson Braga Araujo <robsonbraga@gmail.com>
|
||||||
|
Pierre-Henri Ausseil <ph.ausseil@gmail.com>
|
||||||
|
Christopher McCulloh <cmcculloh@gmail.com>
|
||||||
|
Andrew Newcomb <ext.github@preceptsoftware.co.uk>
|
||||||
|
Lim Chee Aun <cheeaun@gmail.com>
|
||||||
|
Jorge Barreiro <yortx.barry@gmail.com>
|
||||||
|
Daniel Steigerwald <daniel@steigerwald.cz>
|
||||||
|
John Firebaugh <john_firebaugh@bigfix.com>
|
||||||
|
John Enters <github@darkdark.net>
|
||||||
|
Andrey Kapitcyn <ru.m157y@gmail.com>
|
||||||
|
Dmitry Petrov <dpetroff@gmail.com>
|
||||||
|
Eric Hynds <eric@hynds.net>
|
||||||
|
Chairat Sunthornwiphat <pipo@sixhead.com>
|
||||||
|
Josh Varner <josh.varner@gmail.com>
|
||||||
|
Stéphane Raimbault <stephane.raimbault@gmail.com>
|
||||||
|
Jay Merrifield <fracmak@gmail.com>
|
||||||
|
J. Ryan Stinnett <jryans@gmail.com>
|
||||||
|
Peter Heiberg <peter@heiberg.se>
|
||||||
|
Alex Dovenmuehle <adovenmuehle@gmail.com>
|
||||||
|
Jamie Gegerson <git@jamiegegerson.com>
|
||||||
|
Raymond Schwartz <skeetergraphics@gmail.com>
|
||||||
|
Phillip Barnes <philbar@gmail.com>
|
||||||
|
Kyle Wilkinson <kai@wikyd.org>
|
||||||
|
Khaled AlHourani <me@khaledalhourani.com>
|
||||||
|
Marian Rudzynski <mr@impaled.org>
|
||||||
|
Jean-Francois Remy <jeff@melix.org>
|
||||||
|
Doug Blood <dougblood@gmail.com>
|
||||||
|
Filippo Cavallarin <filippo.cavallarin@codseq.it>
|
||||||
|
Heiko Henning <heiko@thehennings.ch>
|
||||||
|
Aliaksandr Rahalevich <saksmlz@gmail.com>
|
||||||
|
Mario Visic <mario@mariovisic.com>
|
||||||
|
Xavi Ramirez <xavi.rmz@gmail.com>
|
||||||
|
Max Schnur <max.schnur@gmail.com>
|
||||||
|
Saji Nediyanchath <saji89@gmail.com>
|
||||||
|
Corey Frang <gnarf37@gmail.com>
|
||||||
|
Aaron Peterson <aaronp123@yahoo.com>
|
||||||
|
Ivan Peters <ivan@ivanpeters.com>
|
||||||
|
Mohamed Cherif Bouchelaghem <cherifbouchelaghem@yahoo.fr>
|
||||||
|
Marcos Sousa <falecomigo@marcossousa.com>
|
||||||
|
Michael DellaNoce <mdellanoce@mailtrust.com>
|
||||||
|
George Marshall <echosx@gmail.com>
|
||||||
|
Tobias Brunner <tobias@strongswan.org>
|
||||||
|
Martin Solli <msolli@gmail.com>
|
||||||
|
David Petersen <public@petersendidit.com>
|
||||||
|
Dan Heberden <danheberden@gmail.com>
|
||||||
|
William Kevin Manire <williamkmanire@gmail.com>
|
||||||
|
Gilmore Davidson <gilmoreorless@gmail.com>
|
||||||
|
Michael Wu <michaelmwu@gmail.com>
|
||||||
|
Adam Parod <mystic414@gmail.com>
|
||||||
|
Guillaume Gautreau <guillaume+github@ghusse.com>
|
||||||
|
Marcel Toele <EleotleCram@gmail.com>
|
||||||
|
Dan Streetman <ddstreet@ieee.org>
|
||||||
|
Matt Hoskins <matt@nipltd.com>
|
||||||
|
Giovanni Giacobbi <giovanni@giacobbi.net>
|
||||||
|
Kyle Florence <kyle.florence@gmail.com>
|
||||||
|
Pavol Hluchý <lopo@losys.sk>
|
||||||
|
Hans Hillen <hans.hillen@gmail.com>
|
||||||
|
Mark Johnson <virgofx@live.com>
|
||||||
|
Trey Hunner <treyhunner@gmail.com>
|
||||||
|
Shane Whittet <whittet@gmail.com>
|
||||||
|
Edward A Faulkner <ef@alum.mit.edu>
|
||||||
|
Adam Baratz <adam@adambaratz.com>
|
||||||
|
Kato Kazuyoshi <kato.kazuyoshi@gmail.com>
|
||||||
|
Eike Send <eike.send@gmail.com>
|
||||||
|
Kris Borchers <kris.borchers@gmail.com>
|
||||||
|
Eddie Monge <eddie@eddiemonge.com>
|
||||||
|
Israel Tsadok <itsadok@gmail.com>
|
||||||
|
Carson McDonald <carson@ioncannon.net>
|
||||||
|
Jason Davies <jason@jasondavies.com>
|
||||||
|
Garrison Locke <gplocke@gmail.com>
|
||||||
|
David Murdoch <david@davidmurdoch.com>
|
||||||
|
Benjamin Scott Boyle <benjamins.boyle@gmail.com>
|
||||||
|
Jesse Baird <jebaird@gmail.com>
|
||||||
|
Jonathan Vingiano <jvingiano@gmail.com>
|
||||||
|
Dylan Just <dev@ephox.com>
|
||||||
|
Hiroshi Tomita <tomykaira@gmail.com>
|
||||||
|
Glenn Goodrich <glenn.goodrich@gmail.com>
|
||||||
|
Tarafder Ashek-E-Elahi <mail.ashek@gmail.com>
|
||||||
|
Ryan Neufeld <ryan@neufeldmail.com>
|
||||||
|
Marc Neuwirth <marc.neuwirth@gmail.com>
|
||||||
|
Philip Graham <philip.robert.graham@gmail.com>
|
||||||
|
Benjamin Sterling <benjamin.sterling@kenzomedia.com>
|
||||||
|
Wesley Walser <waw325@gmail.com>
|
||||||
|
Kouhei Sutou <kou@clear-code.com>
|
||||||
|
Karl Kirch <karlkrch@gmail.com>
|
||||||
|
Chris Kelly <ckdake@ckdake.com>
|
||||||
|
Jason Oster <jay@kodewerx.org>
|
||||||
|
Felix Nagel <info@felixnagel.com>
|
||||||
|
Alexander Polomoshnov <alex.polomoshnov@gmail.com>
|
||||||
|
David Leal <dgleal@gmail.com>
|
||||||
|
Igor Milla <igor.fsp.milla@gmail.com>
|
||||||
|
Dave Methvin <dave.methvin@gmail.com>
|
||||||
|
Florian Gutmann <f.gutmann@chronimo.com>
|
||||||
|
Marwan Al Jubeh <marwan.aljubeh@gmail.com>
|
||||||
|
Milan Broum <midlis@googlemail.com>
|
||||||
|
Sebastian Sauer <info@dynpages.de>
|
||||||
|
Gaëtan Muller <m.gaetan89@gmail.com>
|
||||||
|
Michel Weimerskirch <michel@weimerskirch.net>
|
||||||
|
William Griffiths <william@ycymro.com>
|
||||||
|
Stojce Slavkovski <stojce@gmail.com>
|
||||||
|
David Soms <david.soms@gmail.com>
|
||||||
|
David De Sloovere <david.desloovere@outlook.com>
|
||||||
|
Michael P. Jung <michael.jung@terreon.de>
|
||||||
|
Shannon Pekary <spekary@gmail.com>
|
||||||
|
Dan Wellman <danwellman@hotmail.com>
|
||||||
|
Matthew Edward Hutton <meh@corefiling.co.uk>
|
||||||
|
James Khoury <james@jameskhoury.com>
|
||||||
|
Rob Loach <robloach@gmail.com>
|
||||||
|
Alberto Monteiro <betimbrasil@gmail.com>
|
||||||
|
Alex Rhea <alex.rhea@gmail.com>
|
||||||
|
Krzysztof Rosiński <rozwell69@gmail.com>
|
||||||
|
Ryan Olton <oltonr@gmail.com>
|
||||||
|
Genie <386@mail.com>
|
||||||
|
Rick Waldron <waldron.rick@gmail.com>
|
||||||
|
Ian Simpson <spoonlikesham@gmail.com>
|
||||||
|
Lev Kitsis <spam4lev@gmail.com>
|
||||||
|
TJ VanToll <tj.vantoll@gmail.com>
|
||||||
|
Justin Domnitz <jdomnitz@gmail.com>
|
||||||
|
Douglas Cerna <douglascerna@yahoo.com>
|
||||||
|
Bert ter Heide <bertjh@hotmail.com>
|
||||||
|
Jasvir Nagra <jasvir@gmail.com>
|
||||||
|
Yuriy Khabarov <13real008@gmail.com>
|
||||||
|
Harri Kilpiö <harri.kilpio@gmail.com>
|
||||||
|
Lado Lomidze <lado.lomidze@gmail.com>
|
||||||
|
Amir E. Aharoni <amir.aharoni@mail.huji.ac.il>
|
||||||
|
Simon Sattes <simon.sattes@gmail.com>
|
||||||
|
Jo Liss <joliss42@gmail.com>
|
||||||
|
Guntupalli Karunakar <karunakarg@yahoo.com>
|
||||||
|
Shahyar Ghobadpour <shahyar@gmail.com>
|
||||||
|
Lukasz Lipinski <uzza17@gmail.com>
|
||||||
|
Timo Tijhof <krinklemail@gmail.com>
|
||||||
|
Jason Moon <jmoon@socialcast.com>
|
||||||
|
Martin Frost <martinf55@hotmail.com>
|
||||||
|
Eneko Illarramendi <eneko@illarra.com>
|
||||||
|
EungJun Yi <semtlenori@gmail.com>
|
||||||
|
Courtland Allen <courtlandallen@gmail.com>
|
||||||
|
Viktar Varvanovich <non4eg@gmail.com>
|
||||||
|
Danny Trunk <dtrunk90@gmail.com>
|
||||||
|
Pavel Stetina <pavel.stetina@nangu.tv>
|
||||||
|
Michael Stay <metaweta@gmail.com>
|
||||||
|
Steven Roussey <sroussey@gmail.com>
|
||||||
|
Michael Hollis <hollis21@gmail.com>
|
||||||
|
Lee Rowlands <lee.rowlands@previousnext.com.au>
|
||||||
|
Timmy Willison <timmywillisn@gmail.com>
|
||||||
|
Karl Swedberg <kswedberg@gmail.com>
|
||||||
|
Baoju Yuan <the_guy_1987@hotmail.com>
|
||||||
|
Maciej Mroziński <maciej.k.mrozinski@gmail.com>
|
||||||
|
Luis Dalmolin <luis.nh@gmail.com>
|
||||||
|
Mark Aaron Shirley <maspwr@gmail.com>
|
||||||
|
Martin Hoch <martin@fidion.de>
|
||||||
|
Jiayi Yang <tr870829@gmail.com>
|
||||||
|
Philipp Benjamin Köppchen <xgxtpbk@gws.ms>
|
||||||
|
Sindre Sorhus <sindresorhus@gmail.com>
|
||||||
|
Bernhard Sirlinger <bernhard.sirlinger@tele2.de>
|
||||||
|
Jared A. Scheel <jared@jaredscheel.com>
|
||||||
|
Rafael Xavier de Souza <rxaviers@gmail.com>
|
||||||
|
John Chen <zhang.z.chen@intel.com>
|
||||||
|
Robert Beuligmann <robertbeuligmann@gmail.com>
|
||||||
|
Dale Kocian <dale.kocian@gmail.com>
|
||||||
|
Mike Sherov <mike.sherov@gmail.com>
|
||||||
|
Andrew Couch <andy@couchand.com>
|
||||||
|
Marc-Andre Lafortune <github@marc-andre.ca>
|
||||||
|
Nate Eagle <nate.eagle@teamaol.com>
|
||||||
|
David Souther <davidsouther@gmail.com>
|
||||||
|
Mathias Stenbom <mathias@stenbom.com>
|
||||||
|
Sergey Kartashov <ebishkek@yandex.ru>
|
||||||
|
Avinash R <nashpapa@gmail.com>
|
||||||
|
Ethan Romba <ethanromba@gmail.com>
|
||||||
|
Cory Gackenheimer <cory.gack@gmail.com>
|
||||||
|
Juan Pablo Kaniefsky <jpkaniefsky@gmail.com>
|
||||||
|
Roman Salnikov <bardt.dz@gmail.com>
|
||||||
|
Anika Henke <anika@selfthinker.org>
|
||||||
|
Samuel Bovée <samycookie2000@yahoo.fr>
|
||||||
|
Fabrício Matté <ult_combo@hotmail.com>
|
||||||
|
Viktor Kojouharov <vkojouharov@gmail.com>
|
||||||
|
Pawel Maruszczyk (http://hrabstwo.net)
|
||||||
|
Pavel Selitskas <p.selitskas@gmail.com>
|
||||||
|
Bjørn Johansen <post@bjornjohansen.no>
|
||||||
|
Matthieu Penant <thieum22@hotmail.com>
|
||||||
|
Dominic Barnes <dominic@dbarnes.info>
|
||||||
|
David Sullivan <david.sullivan@gmail.com>
|
||||||
|
Thomas Jaggi <thomas@responsive.ch>
|
||||||
|
Vahid Sohrabloo <vahid4134@gmail.com>
|
||||||
|
Travis Carden <travis.carden@gmail.com>
|
||||||
|
Bruno M. Custódio <bruno@brunomcustodio.com>
|
||||||
|
Nathanael Silverman <nathanael.silverman@gmail.com>
|
||||||
|
Christian Wenz <christian@wenz.org>
|
||||||
|
Steve Urmston <steve@urm.st>
|
||||||
|
Zaven Muradyan <megalivoithos@gmail.com>
|
||||||
|
Woody Gilk <shadowhand@deviantart.com>
|
||||||
|
Zbigniew Motyka <zbigniew.motyka@gmail.com>
|
||||||
|
Suhail Alkowaileet <xsoh.k7@gmail.com>
|
||||||
|
Toshi MARUYAMA <marutosijp2@yahoo.co.jp>
|
||||||
|
David Hansen <hansede@gmail.com>
|
||||||
|
Brian Grinstead <briangrinstead@gmail.com>
|
||||||
|
Christian Klammer <christian314159@gmail.com>
|
||||||
|
Steven Luscher <jquerycla@steveluscher.com>
|
||||||
|
Gan Eng Chin <engchin.gan@gmail.com>
|
||||||
|
Gabriel Schulhof <gabriel.schulhof@intel.com>
|
||||||
|
Alexander Schmitz <arschmitz@gmail.com>
|
||||||
|
Vilhjálmur Skúlason <vis@dmm.is>
|
||||||
|
Siebrand Mazeland <siebrand@kitano.nl>
|
||||||
|
Mohsen Ekhtiari <mohsenekhtiari@yahoo.com>
|
||||||
|
Pere Orga <gotrunks@gmail.com>
|
||||||
|
Jasper de Groot <mail@ugomobi.com>
|
||||||
|
Stephane Deschamps <stephane.deschamps@gmail.com>
|
||||||
|
Jyoti Deka <dekajp@gmail.com>
|
||||||
|
Andrei Picus <office.nightcrawler@gmail.com>
|
||||||
|
Ondrej Novy <novy@ondrej.org>
|
||||||
|
Jacob McCutcheon <jacob.mccutcheon@gmail.com>
|
||||||
|
Monika Piotrowicz <monika.piotrowicz@gmail.com>
|
||||||
|
Imants Horsts <imants.horsts@inbox.lv>
|
||||||
|
Eric Dahl <eric.c.dahl@gmail.com>
|
||||||
|
Dave Stein <dave@behance.com>
|
||||||
|
Dylan Barrell <dylan@barrell.com>
|
||||||
|
Daniel DeGroff <djdegroff@gmail.com>
|
||||||
|
Michael Wiencek <mwtuea@gmail.com>
|
||||||
|
Thomas Meyer <meyertee@gmail.com>
|
||||||
|
Ruslan Yakhyaev <ruslan@ruslan.io>
|
||||||
|
Brian J. Dowling <bjd-dev@simplicity.net>
|
||||||
|
Ben Higgins <ben@extrahop.com>
|
||||||
|
Yermo Lamers <yml@yml.com>
|
||||||
|
Patrick Stapleton <github@gdi2290.com>
|
||||||
|
Trisha Crowley <trisha.crowley@gmail.com>
|
||||||
|
Usman Akeju <akeju00+github@gmail.com>
|
||||||
|
Rodrigo Menezes <rod333@gmail.com>
|
||||||
|
Jacques Perrault <jacques_perrault@us.ibm.com>
|
||||||
|
Frederik Elvhage <frederik.elvhage@googlemail.com>
|
||||||
|
Will Holley <willholley@gmail.com>
|
||||||
|
Uri Gilad <antishok@gmail.com>
|
||||||
|
Richard Gibson <richard.gibson@gmail.com>
|
||||||
|
Simen Bekkhus <sbekkhus91@gmail.com>
|
||||||
|
Chen Eshchar <eshcharc@gmail.com>
|
||||||
|
Bruno Pérel <brunoperel@gmail.com>
|
||||||
|
Mohammed Alshehri <m@dralshehri.com>
|
||||||
|
Lisa Seacat DeLuca <ldeluca@us.ibm.com>
|
||||||
|
Anne-Gaelle Colom <coloma@westminster.ac.uk>
|
||||||
|
Adam Foster <slimfoster@gmail.com>
|
||||||
|
Luke Page <luke.a.page@gmail.com>
|
||||||
|
Daniel Owens <daniel@matchstickmixup.com>
|
||||||
|
Michael Orchard <morchard@scottlogic.co.uk>
|
||||||
|
Marcus Warren <marcus@envoke.com>
|
||||||
|
Nils Heuermann <nils@world-of-scripts.de>
|
||||||
|
Marco Ziech <marco@ziech.net>
|
||||||
|
Patricia Juarez <patrixd@gmail.com>
|
||||||
|
Ben Mosher <me@benmosher.com>
|
||||||
|
Ablay Keldibek <atomio.ak@gmail.com>
|
||||||
|
Thomas Applencourt <thomas.applencourt@irsamc.ups-tlse.fr>
|
||||||
|
Jiabao Wu <jiabao.foss@gmail.com>
|
||||||
|
Eric Lee Carraway <github@ericcarraway.com>
|
||||||
|
Victor Homyakov <vkhomyackov@gmail.com>
|
||||||
|
Myeongjin Lee <aranet100@gmail.com>
|
||||||
|
Liran Sharir <lsharir@gmail.com>
|
||||||
|
Weston Ruter <weston@xwp.co>
|
||||||
|
Mani Mishra <manimishra902@gmail.com>
|
||||||
|
Hannah Methvin <hannahmethvin@gmail.com>
|
||||||
|
Leonardo Balter <leonardo.balter@gmail.com>
|
||||||
|
Benjamin Albert <benjamin_a5@yahoo.com>
|
||||||
|
Michał Gołębiowski-Owczarek <m.goleb@gmail.com>
|
||||||
|
Alyosha Pushak <alyosha.pushak@gmail.com>
|
||||||
|
Fahad Ahmad <fahadahmad41@hotmail.com>
|
||||||
|
Matt Brundage <github@mattbrundage.com>
|
||||||
|
Francesc Baeta <francesc.baeta@gmail.com>
|
||||||
|
Piotr Baran <piotros@wp.pl>
|
||||||
|
Mukul Hase <mukulhase@gmail.com>
|
||||||
|
Konstantin Dinev <kdinev@mail.bw.edu>
|
||||||
|
Rand Scullard <rand@randscullard.com>
|
||||||
|
Dan Strohl <dan@wjcg.net>
|
||||||
|
Maksim Ryzhikov <rv.maksim@gmail.com>
|
||||||
|
Amine HADDAD <haddad@allegorie.tv>
|
||||||
|
Amanpreet Singh <apsdehal@gmail.com>
|
||||||
|
Alexey Balchunas <bleshik@gmail.com>
|
||||||
|
Peter Kehl <peter.kehl@gmail.com>
|
||||||
|
Peter Dave Hello <hsu@peterdavehello.org>
|
||||||
|
Johannes Schäfer <johnschaefer@gmx.de>
|
||||||
|
Ville Skyttä <ville.skytta@iki.fi>
|
||||||
|
Ryan Oriecuia <ryan.oriecuia@visioncritical.com>
|
||||||
|
Sergei Ratnikov <sergeir82@gmail.com>
|
||||||
|
milk54 <milk851@gmail.com>
|
||||||
|
Evelyn Masso <evoutofambit@gmail.com>
|
||||||
|
Robin <mail@robin-fowler.com>
|
||||||
|
Simon Asika <asika32764@gmail.com>
|
||||||
|
Kevin Cupp <kevin.cupp@gmail.com>
|
||||||
|
Jeremy Mickelson <Jeremy.Mickelson@gmail.com>
|
||||||
|
Kyle Rosenberg <kyle.rosenberg@gmail.com>
|
||||||
|
Petri Partio <petri.partio@gmail.com>
|
||||||
|
pallxk <github@pallxk.com>
|
||||||
|
Luke Brookhart <luke@onjax.com>
|
||||||
|
claudi <hirt-claudia@gmx.de>
|
||||||
|
Eirik Sletteberg <eiriksletteberg@gmail.com>
|
||||||
|
Albert Johansson <albert@intervaro.se>
|
||||||
|
A. Wells <borgboyone@users.noreply.github.com>
|
||||||
|
Robert Brignull <robertbrignull@gmail.com>
|
||||||
|
Horus68 <pauloizidoro@gmail.com>
|
||||||
|
Maksymenkov Eugene <foatei@gmail.com>
|
||||||
|
OskarNS <soerensen.oskar@gmail.com>
|
||||||
|
Gez Quinn <holla@gezquinn.design>
|
||||||
|
jigar gala <jigar.gala140291@gmail.com>
|
||||||
|
Florian Wegscheider <flo.wegscheider@gmail.com>
|
||||||
|
Fatér Zsolt <fater.zsolt@gmail.com>
|
||||||
|
Szabolcs Szabolcsi-Toth <nec@shell8.net>
|
||||||
|
Jérémy Munsch <github@jeremydev.ovh>
|
||||||
|
Hrvoje Novosel <hrvoje.novosel@gmail.com>
|
||||||
|
Paul Capron <PaulCapron@users.noreply.github.com>
|
||||||
|
Micah Miller <mikhey@runbox.com>
|
||||||
|
sakshi87 <53863764+sakshi87@users.noreply.github.com>
|
||||||
|
Mikolaj Wolicki <wolicki.mikolaj@gmail.com>
|
||||||
|
Patrick McKay <patrick.mckay@vumc.org>
|
||||||
|
c-lambert <58025159+c-lambert@users.noreply.github.com>
|
||||||
|
Josep Sanz <josepsanzcamp@gmail.com>
|
||||||
|
Ben Mullins <benm@umich.edu>
|
||||||
|
Christian Oliff <christianoliff@pm.me>
|
||||||
|
dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
|
||||||
|
Adam Lidén Hällgren <adamlh92@gmail.com>
|
||||||
|
James Hinderks <hinderks@gmail.com>
|
||||||
|
Denny Septian Panggabean <97607754+ddevsr@users.noreply.github.com>
|
||||||
|
Matías Cánepa <matias.canepa@gmail.com>
|
||||||
|
Ashish Kurmi <100655670+boahc077@users.noreply.github.com>
|
||||||
|
DeerBear <andrea.raimondi@gmail.com>
|
||||||
|
Дилян Палаузов <dpa-github@aegee.org>
|
||||||
|
Kenneth DeBacker <kcdebacker@gmail.com>
|
||||||
|
Timo Tijhof <krinkle@fastmail.com>
|
||||||
|
Timmy Willison <timmywil@users.noreply.github.com>
|
||||||
|
divdeploy <166095818+divdeploy@users.noreply.github.com>
|
||||||
|
mark van tilburg <markvantilburg@gmail.com>
|
||||||
|
Ralf Koller <1665422+rpkoller@users.noreply.github.com>
|
||||||
|
Porter Clevidence <116387727+porterclev@users.noreply.github.com>
|
||||||
|
Daniel García <93217193+Daniel-Garmig@users.noreply.github.com>
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
Copyright OpenJS Foundation and other contributors, https://openjsf.org/
|
||||||
|
|
||||||
|
This software consists of voluntary contributions made by many
|
||||||
|
individuals. For exact contribution history, see the revision history
|
||||||
|
available at https://github.com/jquery/jquery-ui
|
||||||
|
|
||||||
|
The following license applies to all parts of this software except as
|
||||||
|
documented below:
|
||||||
|
|
||||||
|
====
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
====
|
||||||
|
|
||||||
|
Copyright and related rights for sample code are waived via CC0. Sample
|
||||||
|
code is defined as all source code contained within the demos directory.
|
||||||
|
|
||||||
|
CC0: http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
|
||||||
|
====
|
||||||
|
|
||||||
|
All files located in the node_modules and external directories are
|
||||||
|
externally maintained libraries used by this software which have their
|
||||||
|
own licenses; we recommend you read them, as their terms may differ from
|
||||||
|
the terms above.
|
||||||
+10716
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 6.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.5 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user