275 lines
10 KiB
C#
275 lines
10 KiB
C#
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Reflection.Emit;
|
|
using System.Runtime.Serialization;
|
|
using System.Web;
|
|
using System.Web.Http;
|
|
using tyme.solar;
|
|
|
|
|
|
namespace Model
|
|
{
|
|
// 為對應資料表MODEL宣告額外參數類別(Metadata)
|
|
// [JsonIgnore] 避免WEBAPI自動抓關聯資料
|
|
[MetadataType(typeof(followerMetadata))]
|
|
public partial class follower
|
|
{
|
|
private class followerMetadata
|
|
{
|
|
|
|
[JsonIgnore]
|
|
public virtual ICollection<follower> followers1 { get; set; }
|
|
[JsonIgnore]
|
|
public virtual follower follower1 { get; set; }
|
|
[JsonIgnore]
|
|
public virtual ICollection<activity_check> activity_check { get; set; }
|
|
[JsonIgnore]
|
|
public virtual country country1 { get; set; }
|
|
[JsonIgnore]
|
|
public virtual ICollection<member> members { get; set; }
|
|
[JsonIgnore]
|
|
public virtual ICollection<pro_order_detail> pro_order_detail { get; set; }
|
|
[JsonIgnore]
|
|
public virtual ICollection<pro_order_detail> pro_order_detail1 { get; set; }
|
|
[JsonIgnore]
|
|
public virtual ICollection<pro_order> pro_order { get; set; }
|
|
[JsonIgnore]
|
|
public virtual ICollection<pro_order> pro_order1 { get; set; }
|
|
[JsonIgnore]
|
|
public virtual ICollection<followers_tablet> followers_tablet { get; set; }
|
|
[JsonIgnore]
|
|
public virtual appellation appellation { get; set; }
|
|
|
|
|
|
}
|
|
public enum type : int
|
|
{
|
|
[Description("出家眾")]
|
|
Monk = 1,// 4,
|
|
[Description("個人")]
|
|
Personal = 2, //1,
|
|
[Description("法人")]
|
|
Legal = 3, //2,
|
|
[Description("往生菩薩")]
|
|
Bodhisattva = 4, //3,
|
|
[Description("蓮友")]
|
|
Seeker = 10,
|
|
}
|
|
|
|
public static IEnumerable<Model.follower> allFaollowers = new Model.ezEntities().followers.AsEnumerable();
|
|
|
|
//public static string identity_type_list()
|
|
|
|
#region 農曆生日&生肖
|
|
|
|
public enum chinese
|
|
{
|
|
鼠 = 1, 牛 = 2, 虎 = 3, 兔 = 4, 龍 = 5, 蛇 = 6,
|
|
馬 = 7, 羊 = 8, 猴 = 9, 雞 = 10, 狗 = 11, 豬 = 12
|
|
}
|
|
public enum heavenlyStems
|
|
{
|
|
甲 = 1, 乙, 丙, 丁, 戊, 己, 庚, 辛, 壬, 癸
|
|
}
|
|
|
|
public enum earthlyBranches
|
|
{
|
|
子 = 1, 丑, 寅, 卯, 辰, 巳, 午, 未, 申, 酉, 戌, 亥
|
|
}
|
|
|
|
|
|
public static string chagenSign(DateTime? date)
|
|
{ //可改公用
|
|
//生肖
|
|
if (date == null) return null;
|
|
|
|
DateTime d = date.Value;
|
|
|
|
// 使用 tyme4net 方法
|
|
try
|
|
{
|
|
var solarDay = SolarDay.FromYmd(d.Year, d.Month, d.Day);
|
|
var lunarDay = solarDay.GetLunarDay();
|
|
|
|
// 使用正確的 tyme4net API
|
|
var lunarYear = tyme.lunar.LunarYear.FromYear(lunarDay.Year);
|
|
return lunarYear.SixtyCycle.EarthBranch.GetZodiac().GetName();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return $"生肖計算錯誤: {ex.Message}";
|
|
}
|
|
}
|
|
public static string sexagenary(DateTime? date)
|
|
{
|
|
try
|
|
{
|
|
if (date != null)
|
|
{
|
|
DateTime d = date ?? DateTime.Now;
|
|
|
|
//依農曆年計算,故同一年的1月跟6月會得不同結果
|
|
//ChineseLunisolarCalendar chineseDate = new ChineseLunisolarCalendar();
|
|
//int y = chineseDate.GetYear(d);// 農曆年分
|
|
//int a = chineseDate.GetSexagenaryYear(d); // 獲取干支纪年值
|
|
|
|
//heavenlyStems tg = (heavenlyStems)chineseDate.GetCelestialStem(a);
|
|
//earthlyBranches dz = (earthlyBranches)chineseDate.GetTerrestrialBranch(a);
|
|
//return $"{tg}{dz}";
|
|
|
|
|
|
int year = d.Year;
|
|
if (year > 3)
|
|
{
|
|
int tgIndex = (year - 4) % 10;
|
|
int dzIndex = (year - 4) % 12;
|
|
|
|
return $"{(heavenlyStems)(tgIndex + 1)}{(earthlyBranches)(dzIndex + 1)}";
|
|
}
|
|
//throw new ArgumentOutOfRangeException("無效的年份!");
|
|
return null;
|
|
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
//return null;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static string ChkNewFollower(Model.follower newFollower)
|
|
{
|
|
Model.ezEntities _db = new Model.ezEntities();
|
|
if (string.IsNullOrWhiteSpace(newFollower.u_name))
|
|
{
|
|
return "姓名不應為空白";
|
|
}
|
|
|
|
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
|
|
|
// 解密並只保留數字
|
|
string decryptedNewPhone = !string.IsNullOrWhiteSpace(newFollower.phone)
|
|
? new string(encrypt.DecryptAutoKey(newFollower.phone).Where(char.IsDigit).ToArray()) : "";
|
|
string decryptedNewCellphone = !string.IsNullOrWhiteSpace(newFollower.cellphone)
|
|
? new string(encrypt.DecryptAutoKey(newFollower.cellphone).Where(char.IsDigit).ToArray()) : "";
|
|
|
|
var existingFollowers = _db.followers.Where(f => f.u_name == newFollower.u_name).ToList();
|
|
|
|
if (!existingFollowers.Any())
|
|
{
|
|
return "";
|
|
}
|
|
|
|
foreach (var follower in existingFollowers)
|
|
{
|
|
string decryptedPhone = !string.IsNullOrWhiteSpace(follower.phone)
|
|
? new string(encrypt.DecryptAutoKey(follower.phone).Where(char.IsDigit).ToArray()) : "";
|
|
string decryptedCellphone = !string.IsNullOrWhiteSpace(follower.cellphone)
|
|
? new string(encrypt.DecryptAutoKey(follower.cellphone).Where(char.IsDigit).ToArray()) : "";
|
|
|
|
if ((!string.IsNullOrWhiteSpace(decryptedNewPhone) && decryptedNewPhone == decryptedPhone) ||
|
|
(!string.IsNullOrWhiteSpace(decryptedNewCellphone) && decryptedNewCellphone == decryptedCellphone))
|
|
{
|
|
return "姓名重複 + 電話或手機重複";
|
|
}
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
#endregion
|
|
public static string generate_f_number(string sex = "男眾")
|
|
{
|
|
string selectedSex = sex;
|
|
var datePart = DateTime.Now.ToString("yyyyMMdd");
|
|
|
|
// 使用重試機制確保不重號
|
|
int maxRetries = 5;
|
|
for (int retry = 0; retry < maxRetries; retry++)
|
|
{
|
|
try
|
|
{
|
|
using (var _db = new Model.ezEntities())
|
|
using (var transaction = _db.Database.BeginTransaction())
|
|
{
|
|
// 在交易中查詢最大序號
|
|
int nextSerial = GetNextSerialFromDatabase(_db, datePart, selectedSex);
|
|
string f_number = GenerateFNumber(selectedSex, datePart, nextSerial);
|
|
|
|
// 立即檢查是否重複(在交易中)
|
|
if (!_db.followers.Any(f => f.f_number == f_number))
|
|
{
|
|
transaction.Commit();
|
|
return f_number;
|
|
}
|
|
|
|
// 如果重複,回滾交易並重試
|
|
transaction.Rollback();
|
|
|
|
// 短暫延遲後重試
|
|
if (retry < maxRetries - 1)
|
|
{
|
|
System.Threading.Thread.Sleep(10 + retry * 5); // 10ms, 15ms, 20ms, 25ms
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine($"生成編號失敗 (重試 {retry + 1}): {ex.Message}");
|
|
if (retry == maxRetries - 1)
|
|
{
|
|
// 最後一次重試失敗,使用時間戳記確保唯一性
|
|
return GenerateFNumberWithTimestamp(selectedSex, datePart);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 如果所有重試都失敗,使用時間戳記
|
|
return GenerateFNumberWithTimestamp(selectedSex, datePart);
|
|
}
|
|
|
|
private static int GetNextSerialFromDatabase(Model.ezEntities _db, string datePart, string sex)
|
|
{
|
|
var prefix = sex == "男眾" ? "M" : "F";
|
|
var searchPattern = prefix + datePart;
|
|
|
|
var maxFNumber = _db.followers
|
|
.Where(m =>
|
|
m.f_number.Length == 14 &&
|
|
m.f_number.StartsWith(searchPattern))
|
|
.OrderByDescending(m => m.f_number)
|
|
.Select(m => m.f_number)
|
|
.FirstOrDefault();
|
|
|
|
if (!string.IsNullOrEmpty(maxFNumber))
|
|
{
|
|
var serialPart = maxFNumber.Substring(9, 5);
|
|
return int.Parse(serialPart) + 1;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
private static string GenerateFNumber(string sex, string datePart, int serial)
|
|
{
|
|
string prefix = sex == "男眾" ? "M" : "F";
|
|
return prefix + datePart + serial.ToString("D5");
|
|
}
|
|
|
|
private static string GenerateFNumberWithTimestamp(string sex, string datePart)
|
|
{
|
|
// 使用時間戳記確保唯一性(最後手段)
|
|
string prefix = sex == "男眾" ? "M" : "F";
|
|
var timestamp = DateTime.Now.ToString("HHmmss");
|
|
return prefix + datePart + timestamp;
|
|
}
|
|
}
|
|
|
|
}
|