Compare commits
3 Commits
e6c6b1f43f
...
yiming-250
| Author | SHA1 | Date | |
|---|---|---|---|
| b71f72774a | |||
| c90d181b5e | |||
| 05a7cc3e9b |
Binary file not shown.
@@ -8,5 +8,5 @@ using System.Web;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class GlobalVariables
|
public static class GlobalVariables
|
||||||
{
|
{
|
||||||
public static readonly object FNumberLock = new object();
|
// FNumberLock 已移除,因為改用資料庫直接取號,不再需要 Application 狀態鎖定
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,8 @@ using System.Reflection.Emit;
|
|||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using System.Web.Http;
|
using System.Web.Http;
|
||||||
|
using tyme.solar;
|
||||||
|
|
||||||
|
|
||||||
namespace Model
|
namespace Model
|
||||||
{
|
{
|
||||||
@@ -71,12 +73,12 @@ namespace Model
|
|||||||
鼠 = 1, 牛 = 2, 虎 = 3, 兔 = 4, 龍 = 5, 蛇 = 6,
|
鼠 = 1, 牛 = 2, 虎 = 3, 兔 = 4, 龍 = 5, 蛇 = 6,
|
||||||
馬 = 7, 羊 = 8, 猴 = 9, 雞 = 10, 狗 = 11, 豬 = 12
|
馬 = 7, 羊 = 8, 猴 = 9, 雞 = 10, 狗 = 11, 豬 = 12
|
||||||
}
|
}
|
||||||
enum heavenlyStems
|
public enum heavenlyStems
|
||||||
{
|
{
|
||||||
甲 = 1, 乙, 丙, 丁, 戊, 己, 庚, 辛, 壬, 癸
|
甲 = 1, 乙, 丙, 丁, 戊, 己, 庚, 辛, 壬, 癸
|
||||||
}
|
}
|
||||||
|
|
||||||
enum earthlyBranches
|
public enum earthlyBranches
|
||||||
{
|
{
|
||||||
子 = 1, 丑, 寅, 卯, 辰, 巳, 午, 未, 申, 酉, 戌, 亥
|
子 = 1, 丑, 寅, 卯, 辰, 巳, 午, 未, 申, 酉, 戌, 亥
|
||||||
}
|
}
|
||||||
@@ -85,28 +87,24 @@ namespace Model
|
|||||||
public static string chagenSign(DateTime? date)
|
public static string chagenSign(DateTime? date)
|
||||||
{ //可改公用
|
{ //可改公用
|
||||||
//生肖
|
//生肖
|
||||||
|
if (date == null) return null;
|
||||||
|
|
||||||
|
DateTime d = date.Value;
|
||||||
|
|
||||||
|
// 使用 tyme4net 方法
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (date != null)
|
var solarDay = SolarDay.FromYmd(d.Year, d.Month, d.Day);
|
||||||
{
|
var lunarDay = solarDay.GetLunarDay();
|
||||||
DateTime d = date ?? DateTime.Now;
|
|
||||||
int year = d.Year;
|
|
||||||
int birthpet; //宣告生肖要用的變數
|
|
||||||
|
|
||||||
birthpet = year % 12; //西元年除12取餘數
|
// 使用正確的 tyme4net API
|
||||||
birthpet -= 3;
|
var lunarYear = tyme.lunar.LunarYear.FromYear(lunarDay.Year);
|
||||||
//餘數-3
|
return lunarYear.SixtyCycle.EarthBranch.GetZodiac().GetName();
|
||||||
if (birthpet <= 0) birthpet += 12;
|
|
||||||
//判斷餘數是否大於0,小於0必須+12
|
|
||||||
return Enum.GetName(typeof(chinese), birthpet);
|
|
||||||
//return ((chinese)birthpet).ToString(); //也可以
|
|
||||||
}
|
}
|
||||||
}
|
catch (Exception ex)
|
||||||
catch
|
|
||||||
{
|
{
|
||||||
//return null;
|
return $"生肖計算錯誤: {ex.Message}";
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
public static string sexagenary(DateTime? date)
|
public static string sexagenary(DateTime? date)
|
||||||
{
|
{
|
||||||
@@ -190,21 +188,87 @@ namespace Model
|
|||||||
public static string generate_f_number(string sex = "男眾")
|
public static string generate_f_number(string sex = "男眾")
|
||||||
{
|
{
|
||||||
string selectedSex = sex;
|
string selectedSex = sex;
|
||||||
string f_number = selectedSex == "男眾" ? "M" : "F";
|
|
||||||
var datePart = DateTime.Now.ToString("yyyyMMdd");
|
var datePart = DateTime.Now.ToString("yyyyMMdd");
|
||||||
f_number += datePart;
|
|
||||||
|
|
||||||
|
// 使用重試機制確保不重號
|
||||||
int nextSerial = 1;
|
int maxRetries = 5;
|
||||||
|
for (int retry = 0; retry < maxRetries; retry++)
|
||||||
lock (GlobalVariables.FNumberLock)
|
|
||||||
{
|
{
|
||||||
nextSerial = (int)HttpContext.Current.Application["FNumberSerial"] + 1;
|
try
|
||||||
HttpContext.Current.Application["FNumberSerial"] = nextSerial;
|
{
|
||||||
}
|
using (var _db = new Model.ezEntities())
|
||||||
f_number += nextSerial.ToString("D5");
|
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;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ using System.Drawing.Imaging;
|
|||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
|
using tyme.solar;
|
||||||
|
using tyme.lunar;
|
||||||
|
using tyme.sixtycycle;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// publicFun 的摘要描述
|
/// publicFun 的摘要描述
|
||||||
@@ -86,27 +89,35 @@ public class publicFun
|
|||||||
public static string chagenDate(DateTime? date)//因為欄位值是nullable, 所以把null的處理拉進函數做
|
public static string chagenDate(DateTime? date)//因為欄位值是nullable, 所以把null的處理拉進函數做
|
||||||
{ //可改公用
|
{ //可改公用
|
||||||
//農曆年
|
//農曆年
|
||||||
ChineseLunisolarCalendar chineseDate = new ChineseLunisolarCalendar();
|
if (date == null) return null;
|
||||||
|
|
||||||
|
DateTime d = date.Value;
|
||||||
|
|
||||||
|
// 使用 tyme4net 方法
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (date != null)
|
var solarDay = SolarDay.FromYmd(d.Year, d.Month, d.Day);
|
||||||
|
var lunarDay = solarDay.GetLunarDay();
|
||||||
|
|
||||||
|
int minYear = lunarDay.Year - 1911;
|
||||||
|
return $"民{minYear}年/{lunarDay.ToString().Substring(2)}";
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
DateTime d = date ?? DateTime.Now;
|
// 如果 tyme4net 完全失敗,回退到原本的方法
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ChineseLunisolarCalendar chineseDate = new ChineseLunisolarCalendar();
|
||||||
int yy = chineseDate.GetYear(d) - 1911;
|
int yy = chineseDate.GetYear(d) - 1911;
|
||||||
int mm = chineseDate.GetMonth(d);
|
int mm = chineseDate.GetMonth(d);
|
||||||
int dd = chineseDate.GetDayOfMonth(d);
|
int dd = chineseDate.GetDayOfMonth(d);
|
||||||
string dstr = $"民{yy}年{mm:00}月{dd:00}日";
|
return $"民{yy}年{mm:00}月{dd:00}日";
|
||||||
return dstr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{ //try catch可能會很慢, 已知條件先判斷
|
{
|
||||||
//return null;
|
return $"農曆轉換錯誤: {ex.Message}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
//民國年
|
|
||||||
//System.Globalization.TaiwanCalendar tc = new System.Globalization.TaiwanCalendar();
|
|
||||||
// tc.GetYear(d), tc.GetMonth(d), tc.GetDayOfMonth(d)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region 刪除檔案 for api
|
#region 刪除檔案 for api
|
||||||
|
|||||||
BIN
web/Bin/tyme.dll
Normal file
BIN
web/Bin/tyme.dll
Normal file
Binary file not shown.
@@ -27,8 +27,6 @@
|
|||||||
//GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
|
//GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
|
||||||
//註冊自訂路由
|
//註冊自訂路由
|
||||||
RouteConfig.RegisterRoutes(RouteTable.Routes);
|
RouteConfig.RegisterRoutes(RouteTable.Routes);
|
||||||
InitializeFNumberSerial();//啟動項目的時候查詢出信眾編號的最大值放在記憶體中
|
|
||||||
|
|
||||||
//bundle js、css
|
//bundle js、css
|
||||||
//BundleConfig.RegisterBundles(BundleTable.Bundles);
|
//BundleConfig.RegisterBundles(BundleTable.Bundles);
|
||||||
|
|
||||||
@@ -63,38 +61,4 @@
|
|||||||
System.Web.HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
|
System.Web.HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeFNumberSerial()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (var _db = new Model.ezEntities())
|
|
||||||
{
|
|
||||||
var maxFNumber = _db.followers
|
|
||||||
.Where(m =>
|
|
||||||
////m.IsDel == false && ////不確定是否新增欄位? 先註解
|
|
||||||
m.f_number.Length == 14 &&
|
|
||||||
(m.f_number.StartsWith("M") || m.f_number.StartsWith("F")))
|
|
||||||
.OrderByDescending(m => m.reg_time)
|
|
||||||
.Select(m => m.f_number)
|
|
||||||
.FirstOrDefault();
|
|
||||||
|
|
||||||
int nextSerial = 0;
|
|
||||||
if (!string.IsNullOrEmpty(maxFNumber))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var serialPart = maxFNumber.Substring(9, 5);
|
|
||||||
nextSerial = int.Parse(serialPart);
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
}
|
|
||||||
|
|
||||||
Application["FNumberSerial"] = nextSerial;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Application["FNumberSerial"] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -45,7 +45,6 @@
|
|||||||
{ text: '身分別', value: 'identity_type_desc' },
|
{ text: '身分別', value: 'identity_type_desc' },
|
||||||
{ text: '性別', value: 'sex' },
|
{ text: '性別', value: 'sex' },
|
||||||
{ text: '生日', value: 'birthday' },
|
{ text: '生日', value: 'birthday' },
|
||||||
{ text: '生肖/干支', value: 'sign', sortable: false },
|
|
||||||
{ text: '報名記錄', value: 'order_record' },
|
{ text: '報名記錄', value: 'order_record' },
|
||||||
{ 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' },
|
||||||
@@ -414,11 +413,15 @@
|
|||||||
class="elevation-1">
|
class="elevation-1">
|
||||||
|
|
||||||
<template #item.birthday="{ item }" >
|
<template #item.birthday="{ item }" >
|
||||||
<div><span class="badge bg-secondary">西元</span> {{ item.birthday|timeString('YYYY/MM/DD') }} </div>
|
<div v-if="item.birthday">
|
||||||
<div><span class="badge bg-secondary">農曆</span> {{ item.birthday2 }} </div>
|
<span class="badge bg-secondary">西元</span> {{ item.birthday|timeString('YYYY/MM/DD') }}
|
||||||
</template>
|
</div>
|
||||||
<template #item.sign="{ item }" >
|
<div v-if="item.birthday2">
|
||||||
{{ item.sign }}/{{ item.sexagenary }}
|
<span class="badge bg-secondary">農曆</span> {{ item.birthday2 }} ({{ item.sign }})
|
||||||
|
</div>
|
||||||
|
<div v-if="!item.birthday && !item.birthday2">
|
||||||
|
<span class="badge bg-light text-muted">未填寫</span>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #item.slot_btn="{ item }">
|
<template #item.slot_btn="{ item }">
|
||||||
<a :href="'reg.aspx?num='+item.num" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-pencil-box-outline"></i>修改</a>
|
<a :href="'reg.aspx?num='+item.num" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-pencil-box-outline"></i>修改</a>
|
||||||
|
|||||||
@@ -528,6 +528,13 @@
|
|||||||
// //this.calculateLunarBirthday();
|
// //this.calculateLunarBirthday();
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
// 提示訊息
|
||||||
|
snackbar: {
|
||||||
|
show: false,
|
||||||
|
message: '',
|
||||||
|
color: 'error'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
search_show(curr) {
|
search_show(curr) {
|
||||||
@@ -1046,6 +1053,15 @@
|
|||||||
},
|
},
|
||||||
fam_save(item) {
|
fam_save(item) {
|
||||||
console.log("fam_save 1:", this.family.edItem);
|
console.log("fam_save 1:", this.family.edItem);
|
||||||
|
|
||||||
|
// 驗證必填欄位 - 只有姓名必填
|
||||||
|
if (!this.family.edItem.fam_name || this.family.edItem.fam_name.trim() === '') {
|
||||||
|
this.snackbar.message = '請填寫姓名';
|
||||||
|
this.snackbar.color = 'error';
|
||||||
|
this.snackbar.show = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!this.family.is_tw) {
|
if (!this.family.is_tw) {
|
||||||
this.family.edItem.city = '';
|
this.family.edItem.city = '';
|
||||||
this.family.edItem.area = '';
|
this.family.edItem.area = '';
|
||||||
@@ -1956,7 +1972,7 @@
|
|||||||
<v-form ref="familyForm">
|
<v-form ref="familyForm">
|
||||||
<v-text-field
|
<v-text-field
|
||||||
v-model="family.edItem.fam_name"
|
v-model="family.edItem.fam_name"
|
||||||
label="姓名"
|
label="姓名 * "
|
||||||
required
|
required
|
||||||
></v-text-field>
|
></v-text-field>
|
||||||
|
|
||||||
@@ -2124,9 +2140,10 @@
|
|||||||
</v-dialog>
|
</v-dialog>
|
||||||
<v-snackbar
|
<v-snackbar
|
||||||
v-model="snackbar.show"
|
v-model="snackbar.show"
|
||||||
timeout="2000"
|
:color="snackbar.color"
|
||||||
|
timeout="3000"
|
||||||
>
|
>
|
||||||
{{ snackbar.text }}
|
{{ snackbar.message }}
|
||||||
<template v-slot:action="{ attrs }">
|
<template v-slot:action="{ attrs }">
|
||||||
<v-btn
|
<v-btn
|
||||||
text
|
text
|
||||||
|
|||||||
@@ -105,7 +105,6 @@ public partial class admin_follower_reg : MyWeb.config
|
|||||||
{
|
{
|
||||||
Literal1.Text = publicFun.chagenDate(prod.birthday.Value);
|
Literal1.Text = publicFun.chagenDate(prod.birthday.Value);
|
||||||
Literal2.Text = Model.follower.chagenSign(prod.birthday.Value);
|
Literal2.Text = Model.follower.chagenSign(prod.birthday.Value);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (prod.leader.HasValue)
|
if (prod.leader.HasValue)
|
||||||
{
|
{
|
||||||
@@ -207,25 +206,8 @@ public partial class admin_follower_reg : MyWeb.config
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 使用新的 generate_f_number 方法,已內建重號檢查和重試機制
|
||||||
followers.f_number = follower.generate_f_number(sex.SelectedValue);
|
followers.f_number = follower.generate_f_number(sex.SelectedValue);
|
||||||
if (chk_pro_num(followers.f_number))
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
followers.f_number = follower.generate_f_number(sex.SelectedValue);
|
|
||||||
if (chk_pro_num(followers.f_number))
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
L_msg.Type = alert_type.danger;
|
|
||||||
L_msg.Text = "信眾編號重複";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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;
|
||||||
|
|||||||
@@ -378,7 +378,7 @@
|
|||||||
start_date: new Date().format("yyyy-MM-dd"),
|
start_date: new Date().format("yyyy-MM-dd"),
|
||||||
extend_date: '',
|
extend_date: '',
|
||||||
price: 0,
|
price: 0,
|
||||||
qty: 0,
|
qty: 1,
|
||||||
writeBedQty: 0,
|
writeBedQty: 0,
|
||||||
notBedQty: 0,
|
notBedQty: 0,
|
||||||
category: 0,
|
category: 0,
|
||||||
|
|||||||
Reference in New Issue
Block a user