Files
17168ERP/web/App_Code/Model/Partial/follower.cs
2025-09-11 00:47:51 +08:00

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;
}
}
}