using Aspose.Cells;
using Aspose.Words;
using Aspose.Words.Drawing;
using Aspose.Words.Tables;
using DiffMatchPatch;
using Microsoft.AspNetCore.SignalR;
using NPOI.SS.Formula.Functions;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
using OASystem.API.Middlewares;
using OASystem.API.OAMethodLib;
using OASystem.API.OAMethodLib.APNs;
using OASystem.API.OAMethodLib.DeepSeekAPI;
using OASystem.API.OAMethodLib.File;
using OASystem.API.OAMethodLib.Hub.HubClients;
using OASystem.API.OAMethodLib.Hub.Hubs;
using OASystem.API.OAMethodLib.JuHeAPI;
using OASystem.API.OAMethodLib.KiMiApi;
using OASystem.API.OAMethodLib.Logging;
using OASystem.API.OAMethodLib.QiYeWeChatAPI.AppNotice;
using OASystem.Domain.AesEncryption;
using OASystem.Domain.Attributes;
using OASystem.Domain.Dtos.CRM;
using OASystem.Domain.Dtos.FileDto;
using OASystem.Domain.Dtos.Financial;
using OASystem.Domain.Dtos.Groups;
using OASystem.Domain.Entities.Customer;
using OASystem.Domain.Entities.Financial;
using OASystem.Domain.Entities.Groups;
using OASystem.Domain.ViewModels.CRM;
using OASystem.Domain.ViewModels.Financial;
using OASystem.Domain.ViewModels.Groups;
using OASystem.Domain.ViewModels.OCR;
using OASystem.Infrastructure.Repositories.CRM;
using OASystem.Infrastructure.Repositories.Financial;
using OASystem.Infrastructure.Repositories.Groups;
using Quartz.Logging;
using Quartz.Util;
using SQLitePCL;
using SqlSugar.Extensions;
using System.Collections;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq.Expressions;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using static OASystem.API.OAMethodLib.JWTHelper;
using static OASystem.Infrastructure.Repositories.Groups.AirTicketResRepository;
using static OpenAI.GPT3.ObjectModels.SharedModels.IOpenAiModels;
using Bookmark = Aspose.Words.Bookmark;
using Cell = Aspose.Words.Tables.Cell;
using Table = Aspose.Words.Tables.Table;
namespace OASystem.API.Controllers
{
///
/// 团组相关
///
//[Authorize]
[Route("api/[controller]/[action]")]
public class GroupsController : ControllerBase
{
private readonly ILogger _logger;
private readonly ITextFileLogger _eec_textLogger;
private readonly IGroupTextFileLogger _groupTextLogger;
private readonly GrpScheduleRepository _grpScheduleRep;
private readonly IMapper _mapper;
private readonly DelegationInfoRepository _groupRepository;
private readonly TaskAssignmentRepository _taskAssignmentRep;
private readonly AirTicketResRepository _airTicketResRep;
private readonly DecreasePaymentsRepository _decreasePaymentsRep;
private readonly InvitationOfficialActivitiesRepository _InvitationOfficialActivitiesRep;
private readonly DelegationEnDataRepository _delegationEnDataRep;
private readonly DelegationVisaRepository _delegationVisaRep;
private readonly VisaPriceRepository _visaPriceRep;
private readonly CarTouristGuideGroundRepository _carTouristGuideGroundRep;
private readonly HotelPriceRepository _hotelPriceRep;
private readonly CustomersRepository _customersRep;
private readonly MessageRepository _message;
private readonly SqlSugarClient _sqlSugar;
private readonly TourClientListRepository _tourClientListRep;
private readonly TeamRateRepository _teamRateRep;
#region 成本相关
private readonly CheckBoxsRepository _checkBoxs;
private readonly GroupCostRepository _GroupCostRepository;
private readonly CostTypeHotelNumberRepository _CostTypeHotelNumberRepository;
private readonly GroupCostParameterRepository _GroupCostParameterRepository;
#endregion
private readonly SetDataRepository _setDataRep;
private string url;
private string path;
private readonly EnterExitCostRepository _enterExitCostRep;
private readonly IHubContext _hubContext;
private readonly UsersRepository _usersRep;
private readonly IJuHeApiService _juHeApi;
private readonly InvertedListRepository _invertedListRep;
private readonly VisaFeeInfoRepository _visaFeeInfoRep;
private readonly TicketBlackCodeRepository _ticketBlackCodeRep;
private readonly ThreeCodeRepository _threeCodeRepository;
private readonly HotelInquiryRepository _hotelInquiryRep;
private readonly FeeAuditRepository _feeAuditRep;
private readonly VisaCommissionRepository _visaCommissionRep;
private readonly ForeignReceivablesRepository _ffrRep; //对外收款账单仓库
private readonly OpinionaireRepository _opinionaireRep; //对外收款账单仓库
private readonly List _currencyInit;
private readonly List _portTypeData;
private readonly TableOperationRecordRepository _tableorRep;
private readonly EnterExitCostDraftRepository _enterExitCostDraftRep;
private readonly RestaurantRepository _restaurantRep;
private readonly EnterExitCostQuoteRepository _enterExitCostQuoteRep;
private readonly GroupOrderPreInfoRepository _grpOrderPreInfoRep;
private readonly VisaProcessRepository _visaProcessRep;
private readonly ProcessOverviewRepository _processOverviewRep;
private readonly IDeepSeekService _deepSeekService;
///
/// 构造函数
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
public GroupsController(
ILogger logger,
ITextFileLogger eec_textLogger,
IGroupTextFileLogger groupTextLogger,
IMapper mapper,
IHubContext hubContext,
SqlSugarClient sqlSugar,
GrpScheduleRepository grpScheduleRep,
DelegationInfoRepository groupRepository,
TaskAssignmentRepository taskAssignmentRep,
AirTicketResRepository airTicketResRep,
DecreasePaymentsRepository decreasePaymentsRep,
InvitationOfficialActivitiesRepository InvitationOfficialActivitiesRep,
DelegationEnDataRepository delegationEnDataRep,
EnterExitCostRepository enterExitCostRep,
DelegationVisaRepository delegationVisaRep,
MessageRepository message,
VisaPriceRepository visaPriceRep,
CarTouristGuideGroundRepository carTouristGuideGroundRep,
CheckBoxsRepository checkBoxs,
GroupCostRepository GroupCostRepository,
CostTypeHotelNumberRepository CostTypeHotelNumberRepository,
GroupCostParameterRepository GroupCostParameterRepository,
HotelPriceRepository hotelPriceRep,
CustomersRepository customersRep,
SetDataRepository setDataRep,
TourClientListRepository tourClientListRep,
TeamRateRepository teamRateRep,
UsersRepository usersRep,
IJuHeApiService juHeApi,
InvertedListRepository invertedListRep,
VisaFeeInfoRepository visaFeeInfoRep,
TicketBlackCodeRepository ticketBlackCodeRep,
HotelInquiryRepository hotelInquiryRep,
ThreeCodeRepository threeCodeRepository,
FeeAuditRepository feeAuditRep,
VisaCommissionRepository visaCommissionRep,
ForeignReceivablesRepository ffrRep,
OpinionaireRepository opinionaireRep,
TableOperationRecordRepository tableorRep,
EnterExitCostDraftRepository enterExitCostDraftRep,
RestaurantRepository restaurantRep,
EnterExitCostQuoteRepository enterExitCostQuoteRep,
GroupOrderPreInfoRepository grpOrderPreInfoRep,
VisaProcessRepository visaProcessRep,
ProcessOverviewRepository processOverviewRep
)
{
_logger = logger;
_eec_textLogger = eec_textLogger;
_groupTextLogger = groupTextLogger;
_mapper = mapper;
_grpScheduleRep = grpScheduleRep;
_groupRepository = groupRepository;
_taskAssignmentRep = taskAssignmentRep;
_airTicketResRep = airTicketResRep;
_sqlSugar = sqlSugar;
url = AppSettingsHelper.Get("ExcelBaseUrl");
path = AppSettingsHelper.Get("ExcelBasePath");
if (!System.IO.Directory.Exists(path))
{
System.IO.Directory.CreateDirectory(path);//不存在就创建文件夹
}
_decreasePaymentsRep = decreasePaymentsRep;
_InvitationOfficialActivitiesRep = InvitationOfficialActivitiesRep;
_delegationEnDataRep = delegationEnDataRep;
_enterExitCostRep = enterExitCostRep;
_delegationVisaRep = delegationVisaRep;
_message = message;
_visaPriceRep = visaPriceRep;
_carTouristGuideGroundRep = carTouristGuideGroundRep;
_checkBoxs = checkBoxs;
_GroupCostRepository = GroupCostRepository;
_CostTypeHotelNumberRepository = CostTypeHotelNumberRepository;
_GroupCostParameterRepository = GroupCostParameterRepository;
_hotelPriceRep = hotelPriceRep;
_customersRep = customersRep;
_setDataRep = setDataRep;
_tourClientListRep = tourClientListRep;
_teamRateRep = teamRateRep;
_hubContext = hubContext;
_usersRep = usersRep;
_juHeApi = juHeApi;
_invertedListRep = invertedListRep;
_visaFeeInfoRep = visaFeeInfoRep;
_ticketBlackCodeRep = ticketBlackCodeRep;
_hotelInquiryRep = hotelInquiryRep;
_threeCodeRepository = threeCodeRepository;
_feeAuditRep = feeAuditRep;
_visaCommissionRep = visaCommissionRep;
_ffrRep = ffrRep;
_opinionaireRep = opinionaireRep;
_currencyInit = new List()
{
new(){ CurrencyCode="USD",CurrencyName = "美元",Rate = 7.5000M },
new(){ CurrencyCode="EUR",CurrencyName = "欧元",Rate = 8.0000M },
new(){ CurrencyCode="GBP",CurrencyName = "英镑",Rate = 9.5000M },
new(){ CurrencyCode="JPY",CurrencyName = "日元",Rate = 0.0500M },
new(){ CurrencyCode="HKD",CurrencyName = "港币",Rate = 0.9500M },
};
_portTypeData = new List() { 2, 3 };
_tableorRep = tableorRep;
_enterExitCostDraftRep = enterExitCostDraftRep;
_restaurantRep = restaurantRep;
_enterExitCostQuoteRep = enterExitCostQuoteRep;
_grpOrderPreInfoRep = grpOrderPreInfoRep;
_visaProcessRep = visaProcessRep;
_processOverviewRep = processOverviewRep;
}
#region 流程管控
///
/// 获取团组流程管控信息
///
/// 查询参数
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task PostSearchGrpSchedule(JsonDtoBase _jsonDto)
{
if (string.IsNullOrEmpty(_jsonDto.Paras))
{
return Ok(JsonView(false, "参数为空"));
}
Grp_ScheduleDto _ScheduleDto = JsonConvert.DeserializeObject(_jsonDto.Paras);
if (_ScheduleDto != null)
{
if (_ScheduleDto.SearchType == 2)//获取列表
{
List _grpScheduleViewList = await _grpScheduleRep.GetViewList_GrpSchedule(_ScheduleDto);
return Ok(JsonView(_grpScheduleViewList));
}
else//获取对象
{
Grp_ScheduleCombinView _grpScheduleView = await _grpScheduleRep.GetView_GrpSchedule(_ScheduleDto);
if (_grpScheduleView != null)
{
return Ok(JsonView(_grpScheduleView));
}
}
}
else
{
return Ok(JsonView(false, "参数反序列化失败"));
}
return Ok(JsonView(false, "暂无数据!"));
}
///
/// 修改团组流程管控详细表数据
///
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task PostUpdateGrpScheduleDetail(Grp_ScheduleDetailUpdDto dto)
{
Grp_ScheduleDetailInfo _detail = _mapper.Map(dto);
var result = await _grpScheduleRep._sqlSugar.Updateable()
.SetColumns(it => it.Duty == _detail.Duty)
.SetColumns(it => it.ExpectBeginDt == _detail.ExpectBeginDt)
.SetColumns(it => it.ExpectEndDt == _detail.ExpectEndDt)
.SetColumns(it => it.JobContent == _detail.JobContent)
.SetColumns(it => it.Remark == _detail.Remark)
.SetColumns(it => it.StepStatus == _detail.StepStatus)
.Where(s => s.Id == dto.Id)
//.UpdateColumns(s => new { s.Duty, s.ExpectBeginDt, s.ExpectEndDt, s.JobContent, s.Remark, s.StepStatus })
.ExecuteCommandAsync();
if (result > 0)
{
return Ok(JsonView(true, "保存成功!"));
}
return Ok(JsonView(false, "保存失败!"));
}
///
/// 删除团组流程管控详细表数据,删除人Id请放在Duty
///
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task PostDeleteGrpScheduleDetail(Grp_ScheduleDetailUpdDto dto)
{
Grp_ScheduleDetailInfo _detail = _mapper.Map(dto);
_detail.IsDel = 1;
_detail.DeleteUserId = dto.Duty;
_detail.DeleteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
var result = await _grpScheduleRep._sqlSugar.Updateable()
.SetColumns(it => it.IsDel == _detail.IsDel)
.SetColumns(it => it.DeleteUserId == _detail.DeleteUserId)
.SetColumns(it => it.DeleteTime == _detail.DeleteTime)
.Where(it => it.Id == dto.Id)
//.UpdateColumns(s => new { s.IsDel, s.DeleteUserId, s.DeleteTime })
//.WhereColumns(s => s.Id == dto.Id)
.ExecuteCommandAsync();
if (result > 0)
{
return Ok(JsonView(true, "删除成功!"));
}
return Ok(JsonView(false, "删除失败!"));
}
///
/// 增加团组流程管控详细表数据
///
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task PostInsertGrpScheduleDetail(Grp_ScheduleDetailInsertDto dto)
{
Grp_ScheduleDetailInfo _detail = _mapper.Map(dto);
if (DateTime.Now < _detail.ExpectBeginDt)
{
_detail.StepStatus = 0;
}
else
{//若大于设置时间,不考虑设置的预计结束日期,统一视为进行中
_detail.StepStatus = 1;
}
var result = await _grpScheduleRep._sqlSugar.Insertable(_detail).ExecuteReturnIdentityAsync();
if (result > 0)
{
Grp_ScheduleDetailView _result = await _grpScheduleRep.GetInsertBackData(result);
return Ok(JsonView(true, "添加成功!", _result));
}
return Ok(JsonView(false, "添加失败!"));
}
#endregion
#region 团组前期信息
///
/// 团组前期信息H5-URL(员工对应地址)
///
/// 用户名称
///
[HttpGet]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GroupOrderPreInfoH5URLList([FromQuery] string name)
{
var userURLs = await _sqlSugar.Queryable()
.Where(x => x.IsDel == 0)
.WhereIF(!string.IsNullOrEmpty(name), x => x.CnName.Contains(name))
.OrderBy(x => x.Id)
.Select(x => new
{
name = x.CnName,
url = $"http://oa.pan-american-intl.com:4399/#/MarketplacePick?userid={x.Id}",
})
.ToListAsync();
return Ok(JsonView(true, "操作成功!", userURLs, userURLs.Count));
}
///
/// 团组前期信息 List
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GroupOrderPreInfoList(GroupOrderPreInfoListDto dto)
{
var search = dto.Search;
int[] nameTempIds = new int[] { 1, 12, 28 },
countryTempIds = new int[] { 2, 13, 29 },
daysTempIds = new int[] { 4, 15, 31 },
ppNumTempIds = new int[] { 6 };
var list = await _sqlSugar.Queryable()
.LeftJoin((opi, u) => opi.CreateUserId == u.Id)
.Where((opi, u) => opi.IsDel == 0)
.OrderByDescending((opi, u) => opi.CreateTime)
.Select((opi, u) => new GroupOrderPreInfoListView()
{
Id = opi.Id,
Name = opi.Name,
UnitName = SqlFunc.Subqueryable().Where(x => x.ParentId == opi.Id && nameTempIds.Contains(x.FormTempId)).Select(x => x.Value),
VisitCountryVal = SqlFunc.Subqueryable().Where(x => x.ParentId == opi.Id && countryTempIds.Contains(x.FormTempId)).Select(x => x.Value),
VisitDays = SqlFunc.Subqueryable().Where(x => x.ParentId == opi.Id && daysTempIds.Contains(x.FormTempId)).Select(x => x.Value),
VisiPpNum = SqlFunc.Subqueryable().Where(x => x.ParentId == opi.Id && ppNumTempIds.Contains(x.FormTempId)).Select(x => x.Value),
Operator = u.CnName,
OperationTime = opi.CreateTime
})
//.WhereIF(!string.IsNullOrEmpty(search), x => x.Name.Contains(search) || x.UnitName.Contains(search) || x.VisitCountrys.Contains(search))
//.ToPageListAsync(dto.PageIndex, dto.PageSize, total);
.ToListAsync();
var listPageData = list.WhereIF(!string.IsNullOrEmpty(search), x => x.Name.Contains(search) || x.UnitName.Contains(search) || x.VisitCountrys.Contains(search)).ToList();
int total = list.Count;
int totalPageCount = (int)Math.Ceiling(list.Count / (double)dto.PageSize);
var listPageData1 = listPageData
.Skip((dto.PageIndex - 1) * dto.PageSize)
.Take(dto.PageSize)
.ToList();
var infoIds = listPageData1.Select(x => x.Id).ToList();
var typeDatas = await _sqlSugar.Queryable()
.Where(x => x.IsDel == 0 && x.STid == 109)
.ToArrayAsync();
var items = await _sqlSugar.Queryable()
.LeftJoin((opi, ft) => opi.FormTempId == ft.Id)
.Where((opi, ft) => opi.IsDel == 0 && infoIds.Contains(opi.ParentId))
.Select((opi, ft) => new { opi.ParentId, opi.FormTempId, ft.TempId })
.ToListAsync();
foreach (var item in listPageData1)
{
var typeDatas1 = typeDatas.Select(x => new
{
x.Id,
x.Name,
IsNull = !items.Any(x1 => item.Id == x1.ParentId && x.Id == x1.TempId)
}).ToArray();
item.VersionDetails = typeDatas1;
}
return Ok(JsonView(listPageData1, listPageData1.Count));
}
///
/// 团组前期信息 Init
///
///
[HttpGet("{userId}")]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GroupOrderPreInfo(int userId)
{
return Ok(await _grpOrderPreInfoRep.DataInit(userId));
}
///
/// 国家数据源
///
/// 当前页码
/// 每页条数
/// 查询条件
///
[HttpGet]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task CountryInit([FromQuery] int pageIndex, [FromQuery] int pageSize, [FromQuery] string search)
{
var countrys = await _sqlSugar.Queryable().Where(x => x.IsDel == 0).Select(x => x.Country).Distinct().ToListAsync();
if (pageIndex == 0 && pageSize == 0)
{
//所有数据
return Ok(JsonView(countrys, countrys.Count));
}
//分页
int skip = (pageIndex - 1) * pageSize;
int take = pageSize;
if (!string.IsNullOrEmpty(search))
{
IEnumerable charSequence = search.Select(c => c);
var pageResult1 = countrys.Where(x => charSequence.All(x1 => x.Contains(x1))).ToList();
var pageData = pageResult1.Skip(skip).Take(take).ToList();
return Ok(JsonView(pageData, pageResult1.Count));
}
var pageResult2 = countrys.Skip(skip).Take(take).ToList();
return Ok(JsonView(pageResult2, countrys.Count));
}
///
/// 城市数据源
///
/// 国家名称 多个使用英文逗号隔开
/// 当前页码
/// 每页条数
/// 查询条件
///
[HttpGet("{countryLabel}")]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task CityByCountry(
string countryLabel,
[FromQuery] int pageIndex,
[FromQuery] int pageSize,
[FromQuery] string search)
{
countryLabel = HttpUtility.UrlDecode(countryLabel);
var countryList = countryLabel.Split(',', StringSplitOptions.RemoveEmptyEntries).ToArray();
var citys = Array.Empty();
if (countryList.Any())
{
var cityDatas = await _sqlSugar
.Queryable()
.Where(x => x.IsDel == 0 && countryList.Contains(x.Country) && !string.IsNullOrEmpty(x.City))
.ToArrayAsync();
foreach (var item in cityDatas)
{
if (item.City.Contains("城市"))
{
item.City = item.Country + "-所有城市";
}
}
var cityDatas1 = cityDatas.OrderBy(x => x.Country);
citys = cityDatas1.Select(x => x.City).Distinct().ToArray();
}
if (pageIndex == 0 && pageSize == 0)
{
//所有数据
return Ok(JsonView(citys, citys?.Length ?? 0));
}
//分页
int skip = (pageIndex - 1) * pageSize;
int take = pageSize;
if (!string.IsNullOrEmpty(search))
{
IEnumerable charSequence = search.Select(c => c);
var pageResult1 = citys.Where(x => charSequence.All(x1 => x.Contains(x1))).ToList();
var pageData = pageResult1.Skip(skip).Take(take).ToList();
return Ok(JsonView(pageData, pageResult1.Count));
}
var pageResult2 = citys.Skip(skip).Take(take).ToList();
return Ok(JsonView(pageResult2, citys?.Length ?? 0));
}
///
/// 团组前期信息 Info
///
/// Id
///
[HttpGet("{Id}/{TempId}")]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GroupOrderPreInfo([FromRoute] GroupOrderPreInfoDto dto)
{
return Ok(await _grpOrderPreInfoRep.InfoAsync(dto.Id, dto.TempId));
}
///
/// 团组前期信息 移动端 Info
///
/// Id
///
[HttpGet("{Id}/{TempId}")]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GroupOrderPreMobileInfo([FromRoute] GroupOrderPreInfoDto dto)
{
return Ok(await _grpOrderPreInfoRep.MobileInfoAsync(dto.Id, dto.TempId));
}
///
/// 团组前期信息 Save
///
/// Id
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GroupOrderPreInfoSave(GroupOrderPreInfoOpDto dto)
{
return Ok(await _grpOrderPreInfoRep.OpAsync(dto));
}
///
/// 团组前期信息 Del
///
/// Id
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GroupOrderPreInfoDel(GroupOrderPreInfoDelDto dto)
{
return Ok(await _grpOrderPreInfoRep.DelAsync(dto));
}
///
/// 团组前期信息 文件下载
///
/// Id
///
[HttpGet("{Id}/{TempId}")]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GroupOrderPreInfoFileDownload([FromRoute] GroupOrderPreInfoDto dto)
{
int id = dto.Id, tempId = dto.TempId;
var view = await _grpOrderPreInfoRep.InfoAsync(id, tempId);
var data = view.Data as GrpOrderPreInfoView;
#region Excel
var tempPath = AppSettingsHelper.Get("ExcelTempPath");
var servicePath = AppSettingsHelper.Get("GrpFileBaseUrl");
var savePath = AppSettingsHelper.Get("ExcelBasePath") + "GroupOrderPreInfo/";
var ftpPath = AppSettingsHelper.Get("ExcelFtpPath") + "GroupOrderPreInfo/";
var fileNamePrefix = string.Empty;
if (tempId == 1405)
{
tempPath += $"前期需客户提供信息_无商邀版Temp.xlsx";
fileNamePrefix = $"{data.Name}_无商邀版";
}
else if (tempId == 1406)
{
tempPath += $"前期需客户提供信息_有商邀版Temp.xlsx";
fileNamePrefix = $"{data.Name}_有商邀版";
}
else
{
//tempId == 1404 默认下载
tempPath += $"前期需客户提供信息_单接送机Temp.xlsx";
fileNamePrefix = $"{data.Name}_单接送机";
}
foreach (var item in data.Items)
{
var obj = item.NewValue;
if (obj == null) item.OriginVal = "";
else if (obj.Equals("有") || obj.Equals("无"))
{
item.OriginVal = obj.ToString();
}
else if (obj is object[] objArray)
{
string[] stringArray = Array.ConvertAll(objArray, item => item?.ToString() ?? string.Empty);
item.OriginVal = string.Join("、", stringArray);
}
else if (obj is string[] stringArray)
{
item.OriginVal = string.Join("、", stringArray);
}
else if (obj.Equals("-"))
{
item.OriginVal = "";
}
}
var fileName = $"{fileNamePrefix}{CommonFun.GUID}.xlsx";
fileName = CommonFun.ValidFileName(fileName);
//载入模板
var designer = new WorkbookDesigner
{
Workbook = new Workbook(tempPath)
};
if (tempId == 1406)
{
var view1 = data.Items.Where(x => x.Index < 11).ToArray();
var view2 = data.Items.Where(x => x.Index > 10).ToArray();
for (int i = 1; i <= view2.Length; i++)
{
view2[i - 1].Index = i;
}
designer.SetDataSource("View1", view1);
designer.SetDataSource("View2", view2);
}
else
{
designer.SetDataSource("View", data.Items);
}
designer.Process();
if (!Directory.Exists(savePath))
{
Directory.CreateDirectory(savePath);
}
string serverPath = $"{savePath}{fileName}";
designer.Workbook.Save(serverPath);
string rst = $"{servicePath}{ftpPath}{fileName}";
#endregion
return Ok(JsonView(new { url = rst }));
}
#endregion
#region 团组基本信息
///
/// 接团信息列表
///
/// 团组列表请求dto
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GetGroupList(GroupListDto dto)
{
var groupData = await _groupRepository.GetGroupList(dto);
if (groupData.Code != 0)
{
return Ok(JsonView(false, groupData.Msg));
}
return Ok(JsonView(groupData.Data));
}
///
/// 分页查询团组列表
///
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task QueryGroupListOffset(QueryGroupListOffsetDto dto)
{
var watch = new Stopwatch();
watch.Start();
RefAsync total = 0;
var countyDatas = await _sqlSugar.Queryable()
.Where((di) => di.IsDel == 0 && !string.IsNullOrWhiteSpace(di.TeamName))
.WhereIF(!string.IsNullOrEmpty(dto.Search), (di) => di.TeamName.Contains(dto.Search))
.OrderBy((di) => new { id = SqlFunc.Desc(di.Id) })
.Select((di) => new { id = di.Id, name = di.TeamName, di.ClientName, di.VisitPNumber, di.VisitCountry, di.VisitDays, di.VisitStartDate, di.VisitEndDate, di.TourCode })
.Distinct()
.ToPageListAsync(dto.PageIndex, dto.PageSize, total);
watch.Stop();
return Ok(JsonView(true, $"{MsgTips.Succeed},耗时 {watch.ElapsedMilliseconds} ms", countyDatas, total));
}
///
/// 接团信息列表 Page Init
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task PostGroupPageListInit()
{
var depDatas = await GeneralMethod.GroupOpAffiliationBranchInit();
var rankDatas = await _sqlSugar.Queryable().Where(x => x.IsDel == 0 && x.STid == 56).Select(x => new { x.Id, x.Name }).ToListAsync();
rankDatas.Insert(0, new { Id = 0, Name = "全部" });
var _view = new
{
depData = depDatas,
rankData = rankDatas
};
return Ok(JsonView(true, "查询成功!", _view));
}
///
/// 接团信息列表 Page
///
/// 团组列表请求dto
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task PostGroupPageList(GroupPageListDto dto)
{
#region 参数验证
if (dto.UserId < 1) return Ok(JsonView(false, "员工Id为空"));
if (dto.PageId < 1) return Ok(JsonView(false, "页面Id为空"));
#region 页面操作权限验证
var pageFunAuthView = await GeneralMethod.PostUserPageFuncDatas(dto.UserId, dto.PageId);
if (pageFunAuthView.CheckAuth == 0) return Ok(JsonView(false, "您没有查看权限"));
#endregion
#endregion
if (dto.PortType == 1 || dto.PortType == 2) // web/Android
{
string sqlWhere = string.Empty;
if (dto.IsSure == 0) //未完成
{
sqlWhere += string.Format(@" And IsSure = 0");
}
else if (dto.IsSure == 1) //已完成
{
sqlWhere += string.Format(@" And IsSure = 1");
}
if (!string.IsNullOrEmpty(dto.SearchCriteria))
{
string tj = dto.SearchCriteria;
sqlWhere += string.Format(@"And (ssd.Name Like '%{0}%' Or TeamName Like '%{1}%' Or ClientName Like '%{2}%' Or ClientName Like '%{3}%' Or su.CnName Like '%{4}%')",
tj, tj, tj, tj, tj);
}
if (int.TryParse(dto.Rank, out int rankId))
{
if (rankId > 0) sqlWhere += string.Format("And gdi.TeamLevSId = {0}", rankId);
}
string sqlWhere1 = string.Empty;
if (!string.IsNullOrEmpty(dto.Department) && !dto.Department.Equals("全部"))
{
sqlWhere1 = string.Format("Where Department = '{0}'", dto.Department);
}
string sql = string.Format(@"Select Row_Number,Id,SalesQuoteNo,TourCode,TeamTypeId, TeamType,Department,
TeamLevId,TeamLev,TeamName,ClientName,ClientUnit,
VisitDate,VisitDays,VisitPNumber,JietuanOperatorId,
JietuanOperator,IsSure,CreateTime,IsBid,Step
From (
Select row_number() over(order by gdi.VisitStartDate Desc) as Row_Number,
CASE WHEN gdi.JietuanOperator = 4 OR gdi.JietuanOperator = 21 THEN '国交部'
ELSE (Select DepName FROM OA2023DB.dbo.Sys_Department WHERE Id = su.DepId) END AS 'Department',
gdi.Id,SalesQuoteNo,TourCode,ssd.Id TeamTypeId, ssd.Name TeamType,gdi.Step,
ssd1.Id TeamLevId,ssd1.Name TeamLev,TeamName,ClientName,ClientUnit,
VisitDate,VisitDays,VisitPNumber,JietuanOperator JietuanOperatorId,
su.CnName JietuanOperator,IsSure,gdi.CreateTime,gdi.IsBid
From Grp_DelegationInfo gdi
Left Join Sys_SetData ssd On gdi.TeamDid = ssd.Id
Left Join Sys_SetData ssd1 On gdi.TeamLevSId = ssd1.Id
Left Join Sys_Users su On gdi.JietuanOperator = su.Id
Where gdi.IsDel = 0 {0}
) temp {1}", sqlWhere, sqlWhere1);
RefAsync total = 0;//REF和OUT不支持异步,想要真的异步这是最优解
var _DelegationList = await _sqlSugar.SqlQueryable(sql).ToPageListAsync(dto.PageIndex, dto.PageSize, total);//ToPageAsync
//处理 团组模块实际操作人
_DelegationList.ForEach(async x =>
{
var operators = GeneralMethod.GetGroupModuleOperators(x.Id);
var operatorNames = new StringBuilder();
//operatorNames.AppendLine("各模块实际操作人:");
if (operators.Any())
{
operators.ForEach(y =>
{
string label = string.Empty;
if (y.OperationUsers.Any())
{
var users = y.OperationUsers.Select(x => x.UserName).ToList();
label = string.Join('、', users);
}
else label = "暂未指定";
operatorNames.AppendLine($"{y.CTableName}:{label}");
operatorNames.AppendLine();
});
}
x.OperatorLabel = operatorNames.ToString().TrimEnd('\n', '\r');
});
var _view = new
{
PageFuncAuth = pageFunAuthView,
Data = _DelegationList
};
return Ok(JsonView(true, "查询成功!", _view, total));
}
else
{
return Ok(JsonView(false, "查询失败"));
}
}
///
/// 团组列表
///
///
[HttpPost]
public async Task GetGroupListByWhere(GroupListByWhere dto)
{
#region 参数验证
if (dto.UserId < 1) return Ok(JsonView(false, "员工Id为空"));
if (dto.PageId < 1) return Ok(JsonView(false, "页面Id为空"));
#region 页面操作权限验证
var pageFunAuthView = await GeneralMethod.PostUserPageFuncDatas(dto.UserId, dto.PageId);
if (pageFunAuthView.CheckAuth == 0) return Ok(JsonView(false, "您没有查看权限"));
#endregion
#endregion
if (dto.PortType != 1 && dto.PortType != 2)
{
return Ok(JsonView(false, "查询失败!"));
}
string orderbyStr = "order by gdi.CreateTime Desc";
string sqlWhere = string.Empty;
if (dto.IsSure == 0) //未完成
{
sqlWhere += string.Format(@" And IsSure = 0");
}
else if (dto.IsSure == 1) //已完成
{
sqlWhere += string.Format(@" And IsSure = 1");
}
//团组类型
if (dto.TeamDid > 0)
{
sqlWhere += string.Format(@"And TeamDid = {0} ", dto.TeamDid);
}
//团组名称
if (!string.IsNullOrEmpty(dto.TeamName))
{
sqlWhere += string.Format(@"And TeamName Like '%{0}%'", dto.TeamName);
}
//客户名称
if (!string.IsNullOrEmpty(dto.ClientName))
{
sqlWhere += string.Format(@"And ClientName Like '%{0}%'", dto.ClientName);
}
//客户单位
if (!string.IsNullOrEmpty(dto.ClientUnit))
{
sqlWhere += string.Format(@"And ClientUnit Like '%{0}%'", dto.ClientUnit);
}
//出访时间
if (!string.IsNullOrEmpty(dto.visitDataTime))
{
sqlWhere += string.Format(@"And VisitDate >= '{0}'", dto.visitDataTime);
orderbyStr = "order by gdi.VisitDate";
}
string sql = string.Format(@"Select Row_Number,Id,SalesQuoteNo,TourCode,TeamTypeId, TeamType,
TeamLevId,TeamLev,TeamName,ClientName,ClientUnit,
VisitDate,VisitDays,VisitPNumber,JietuanOperatorId,
JietuanOperator,IsSure,CreateTime
From (
Select row_number() over({0}) as Row_Number,
gdi.Id,SalesQuoteNo,TourCode,ssd.Id TeamTypeId, ssd.Name TeamType,
ssd1.Id TeamLevId,ssd1.Name TeamLev,TeamName,ClientName,ClientUnit,
VisitDate,VisitDays,VisitPNumber,JietuanOperator JietuanOperatorId,
su.CnName JietuanOperator,IsSure,gdi.CreateTime
From Grp_DelegationInfo gdi
Left Join Sys_SetData ssd On gdi.TeamDid = ssd.Id
Left Join Sys_SetData ssd1 On gdi.TeamLevSId = ssd1.Id
Left Join Sys_Users su On gdi.JietuanOperator = su.Id
Where gdi.IsDel = 0 {1}
) temp ", orderbyStr, sqlWhere);
RefAsync total = 0;//REF和OUT不支持异步,想要真的异步这是最优解
var _DelegationList = await _sqlSugar.SqlQueryable(sql).ToPageListAsync(dto.PageIndex, dto.PageSize, total);//ToPageAsync
#region 处理所属部门
/*
* 1.sq 和 gyy 等显示 市场部
* 2.王鸽和主管及张总还有管理员号统一国交部
* 2-1. 4 管理员 ,21 张海麟
*/
var userIds = _DelegationList.Select(it => it.JietuanOperatorId).ToList();
var userIds1 = new List() { 4, 21 };
var UserDepDatas = _sqlSugar.Queryable()
.LeftJoin((u, d) => u.DepId == d.Id)
.Where(u => u.IsDel == 0 && userIds.Contains(u.Id))
.Select((u, d) => new { UserId = u.Id, DepName = userIds1.Contains(u.Id) ? "国交部" : d.DepName })
.ToList();
foreach (var item in _DelegationList)
{
item.Department = UserDepDatas.Find(it => item.JietuanOperatorId == it.UserId)?.DepName ?? "Unknown";
}
#endregion
var _view = new
{
PageFuncAuth = pageFunAuthView,
Data = _DelegationList
};
return Ok(JsonView(true, "查询成功!", _view, total));
}
///
/// 接团信息详情
///
/// 团组info请求dto
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GetGroupInfo(GroupInfoDto dto)
{
var groupData = await _groupRepository.GetGroupInfo(dto);
if (groupData.Code != 0)
{
return Ok(JsonView(false, groupData.Msg));
}
return Ok(JsonView(groupData.Data));
}
///
/// 接团信息 编辑添加
/// 基础信息数据源
///
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GroupEditBasicSource(GroupListDto dto)
{
var groupData = await _groupRepository.GroupEditBasicSource(dto);
if (groupData.Code != 0)
{
return Ok(JsonView(false, groupData.Msg));
}
return Ok(JsonView(groupData.Data));
}
///
/// 成本修改团组信息
///
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GroupCostEditGroupInfo(GroupCostEditGroupInfoDto dto)
{
var jw = JsonView(false, "操作失败");
var di = _sqlSugar.Queryable().First(x => x.Id == dto.Diid && x.IsDel == 0);
if (di == null)
{
jw.Msg = "参数有误!";
return Ok(jw);
}
#region 添加出访起止时间
var startTime = new DateTime();
var endTime = new DateTime();
if (DateTime.TryParse(dto.VisitDate, out startTime))
{
endTime = startTime.AddDays(dto.VisitDays - 1);//含当天
}
else
{
jw.Msg = "参数有误!";
return Ok(jw);
}
#endregion
di.VisitDate = startTime;
di.VisitPNumber = dto.VisitPNumber;
di.VisitDays = dto.VisitDays;
di.VisitStartDate = startTime;
di.VisitEndDate = endTime;
var count = _sqlSugar.Updateable(di)
.UpdateColumns(x => new { x.VisitDate, x.VisitPNumber, x.VisitDays, x.VisitStartDate, x.VisitEndDate })
.ExecuteCommand();
return Ok(count > 0 ? JsonView(true, "操作成功") : jw);
}
///
/// 接团信息 编辑添加
/// 省份-城市 基础信息数据源
///
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GroupProvCityBasicSource(GroupProvCityBasicSourceDto dto)
{
int pageIndex = dto.PageIndex, pageSize = dto.PageSize;
string search = dto.Search;
var data = await _groupRepository.CityBasicSource();
int total = data.Length;
data = data.WhereIF(!string.IsNullOrEmpty(search), x => x.Name.Contains(search))
.Skip((pageIndex - 1) * pageSize)
.Take(pageSize)
.ToArray();
return Ok(JsonView(data, total));
}
///
/// 接团信息 操作(增改)
///
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GroupOperation(GroupOperationDto dto)
{
// 创建 Stopwatch 实例
Stopwatch stopwatch = Stopwatch.StartNew();
decimal ffrPrice = 0.00M;
DateTime? visitDt = null;
if (dto.Status == 2)
{
var groupInfo = await _sqlSugar.Queryable().FirstAsync(x => x.Id == dto.Id && x.IsDel == 0);
if (groupInfo != null)
{
ffrPrice = groupInfo.PaymentMoney;
visitDt = groupInfo.VisitDate.AddDays(-groupInfo.PayDay);
}
}
var groupData = await _groupRepository.GroupOperation(dto);
if (groupData.Code != 0)
{
return Ok(JsonView(false, groupData.Msg));
}
int diId = 0;
try
{
//添加时 默认加入团组汇率
if (dto.Status == 1) //添加
{
diId = groupData.Data;
//添加默认币种
await GeneralMethod.PostGroupRateAddInit(dto.UserId, diId);
//默认分配权限
await GeneralMethod.PostGroupAuthAddInit(dto.UserId, diId);
//消息提示 王鸽 主管号 2024-10-21 新增LZ UID
var _managerIds = new List() { 22, 32, 21 };
var userIds = _usersRep._sqlSugar.Queryable().Where(it => it.IsDel == 0 && _managerIds.Contains(it.JobPostId)).Select(it => it.Id).ToList();
if (userIds.Count > 0)
{
userIds.Add(208);
//创建团组管控
GroupStepForDelegation.CreateWorkStep(diId);
//发送消息
string groupName = dto.TeamName;
string createGroupUser = string.Empty;
var userInfo = _usersRep._sqlSugar.Queryable().Where(it => it.IsDel == 0 && it.Id == dto.UserId).First();
if (userInfo != null) createGroupUser = userInfo.CnName;
string title = $"系统通知";
string content = $"团组[{groupName}(创建人:{createGroupUser})]创建成功,请前往页面进行下一步操作!";
await GeneralMethod.MessageIssueAndNotification(MessageTypeEnum.GroupBusinessOperations, title, content, userIds, diId);
}
//默认创建倒推表
await _invertedListRep._Create(dto.UserId, diId);
//默认创建签证流程
await _visaProcessRep.Create(dto.UserId, diId);
//默认创建团组流程总览信息
await _processOverviewRep.ProcessInitAsync(diId, dto.UserId);
}
else if (dto.Status == 2)
{
diId = dto.Id;
}
#region 签证人员团组时间通知
#region 计算出访起止时间
var startTime = new DateTime();
var endTime = new DateTime();
if (DateTime.TryParse(dto.VisitDate, out startTime))
{
endTime = startTime.AddDays(dto.VisitDays - 1);//含当天
}
#endregion
#endregion
#region 团组操作默认添加/修改收款账单
if (dto.PayDay > 0 && dto.PaymentMoney > 0)
{
var ffrInfo = await _sqlSugar.Queryable()
.Where(x => x.IsDel == 0 &&
x.Diid == diId &&
x.Remark.Equals("预付款")
)
.WhereIF(ffrPrice > 0, x => x.ItemSumPrice == ffrPrice)
.WhereIF(visitDt != null, x => x.CreateTime == visitDt)
.FirstAsync();
ffrInfo = new Fin_ForeignReceivables()
{
Diid = diId,
PriceName = dto.ClientUnit,
Price = dto.PaymentMoney,
Count = 1,
Unit = $"元",
ItemSumPrice = dto.PaymentMoney,
Rate = 1.0000M,
Currency = 836,
AddingWay = 0,
CreateUserId = dto.UserId,
CreateTime = Convert.ToDateTime(dto.VisitDate).AddDays(-dto.PayDay),
Remark = $"预付款"
};
if (ffrInfo == null) //Add
{
await _sqlSugar.Insertable(ffrInfo).ExecuteCommandAsync();
}
else //修改
{
await _sqlSugar.Updateable(ffrInfo)
.UpdateColumns(x => new
{
x.PriceName,
x.Price,
x.ItemSumPrice,
x.CreateTime,
x.CreateUserId
})
.WhereColumns(x => x.Id)
.ExecuteCommandAsync();
}
}
#endregion
if (diId > 0)
{
await AppNoticeLibrary.SendUserMsg_GroupTimeInfo_ToVisaUser(diId, startTime.ToString("yyyy-MM-dd"), endTime.ToString("yyyy-MM-dd"));
}
// 停止计时
stopwatch.Stop();
return Ok(JsonView(true, $"操作成功!{stopwatch.ElapsedMilliseconds}ms", diId));
}
catch (Exception ex)
{
// 停止计时
stopwatch.Stop();
Logs("[response]" + JsonConvert.SerializeObject(dto));
Logs(ex.Message);
//return Ok(JsonView(false, $"{ex.Message}[{stopwatch.ElapsedMilliseconds}ms]"));
}
// 停止计时
stopwatch.Stop();
return Ok(JsonView(true, $"操作成功!{stopwatch.ElapsedMilliseconds}ms", diId));
}
///
/// 接团流程操作(增改)
/// 安卓端使用 建团时添加客户名单
///
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GroupProcessOperation(GroupProcessOperationDto dto)
{
#region 参数验证
if (dto.UserId < 1) return Ok(JsonView(false, "请传入有效的UserId参数"));
#region 页面操作权限验证
//pageFunAuthView = await GeneralMethod.PostUserPageFuncDatas(dto.UserId, 104);
//if (pageFunAuthView.AddAuth == 0) return Ok(JsonView(false, "客户名单您没有添加权限!"));
var pageFunAuthView = await GeneralMethod.PostUserPageFuncDatas(dto.UserId, 27);
if (pageFunAuthView.AddAuth == 0) return Ok(JsonView(false, "团组操作您没有添加权限!"));
#endregion
#endregion
try
{
//_sqlSugar.BeginTran();
decimal ffrPrice = 0.00M;
DateTime? visitDt = null;
if (dto.Status == 2)
{
var groupInfo = await _sqlSugar.Queryable().FirstAsync(x => x.Id == dto.Id && x.IsDel == 0);
if (groupInfo != null)
{
ffrPrice = groupInfo.PaymentMoney;
visitDt = groupInfo.VisitDate.AddDays(-groupInfo.PayDay);
}
}
var _dto = new GroupOperationDto();
_dto = _mapper.Map(dto);
var groupData = await _groupRepository.GroupOperation(_dto);
if (groupData.Code != 0)
{
return Ok(JsonView(false, "团组操作添加失败!" + groupData.Msg));
}
int diId = 0;
//添加时 默认加入团组汇率
if (dto.Status == 1) //添加
{
diId = groupData.Data;
//添加默认币种
await GeneralMethod.PostGroupRateAddInit(dto.UserId, diId);
//默认分配权限
await GeneralMethod.PostGroupAuthAddInit(dto.UserId, diId);
//消息提示 王鸽 主管号 2024-10-21 新增LZ UID
var _managerIds = new List() { 21, 22, 32 };
var userIds = _usersRep._sqlSugar.Queryable().Where(it => it.IsDel == 0 && _managerIds.Contains(it.JobPostId)).Select(it => it.Id).ToList();
if (userIds.Count > 0)
{
userIds.Add(208);
//创建团组管控
GroupStepForDelegation.CreateWorkStep(diId);
//发送消息
string groupName = dto.TeamName;
string createGroupUser = string.Empty;
var userInfo = _usersRep._sqlSugar.Queryable().Where(it => it.IsDel == 0 && it.Id == dto.UserId).First();
if (userInfo != null) createGroupUser = userInfo.CnName;
string title = $"系统通知";
string content = $"团组[{groupName}(创建人:{createGroupUser})]创建成功,请前往页面进行下一步操作!";
await GeneralMethod.MessageIssueAndNotification(MessageTypeEnum.GroupBusinessOperations, title, content, userIds, diId);
}
#region 应用推送
try
{
await AppNoticeLibrary.SendChatMsg_GroupStatus_Create(diId, QiyeWeChatEnum.CompanyCRMChat);
Sys_Users users = _airTicketResRep.Query(s => s.Id == dto.UserId).First();
Sys_Department department = _airTicketResRep.Query(s => s.Id == users.DepId).First();
if (department.Id == 6 && !string.IsNullOrEmpty(users.QiyeChatUserId))
{
var userList = new List() { users.QiyeChatUserId };
await AppNoticeLibrary.SendUserMsg_GroupStatus_Create(diId, userList);
}
}
catch (Exception ex)
{
}
#endregion
//默认创建倒推表
await _invertedListRep._Create(dto.UserId, diId);
//默认创建签证流程
await _visaProcessRep.Create(dto.UserId, diId);
//默认创建团组流程总览信息
await _processOverviewRep.ProcessInitAsync(diId, dto.UserId);
}
if (dto.Status == 2)
{
diId = dto.Id;
if (diId == 0)
{
//_sqlSugar.RollbackTran();
return Ok(JsonView(false, "修改失败! 未添加团组id" + groupData.Msg));
}
}
var viewData = await _tourClientListRep.OperMultiple(dto.TourClientListInfos, diId, dto.UserId);
if (viewData.Code != 0)
{
//_sqlSugar.RollbackTran();
return Ok(JsonView(false, "客户名单添加失败!" + viewData.Msg));
}
#region 团组操作默认添加/修改收款账单
if (dto.PayDay > 0 && dto.PaymentMoney > 0)
{
var ffrInfo = await _sqlSugar.Queryable()
.Where(x => x.IsDel == 0 &&
x.Diid == diId &&
x.Remark.Equals("预付款")
)
.WhereIF(ffrPrice > 0, x => x.ItemSumPrice == ffrPrice)
.WhereIF(visitDt != null, x => x.CreateTime == visitDt)
.FirstAsync();
ffrInfo = new Fin_ForeignReceivables()
{
Diid = diId,
PriceName = dto.ClientUnit,
Price = dto.PaymentMoney,
Count = 1,
Unit = $"元",
ItemSumPrice = dto.PaymentMoney,
Rate = 1.0000M,
Currency = 836,
AddingWay = 0,
CreateUserId = dto.UserId,
CreateTime = Convert.ToDateTime(dto.VisitDate).AddDays(-dto.PayDay),
Remark = $"预付款"
};
if (ffrInfo == null) //Add
{
await _sqlSugar.Insertable(ffrInfo).ExecuteCommandAsync();
}
else //修改
{
await _sqlSugar.Updateable(ffrInfo)
.UpdateColumns(x => new
{
x.PriceName,
x.Price,
x.ItemSumPrice,
x.CreateTime,
x.CreateUserId
})
.WhereColumns(x => x.Id)
.ExecuteCommandAsync();
}
}
#endregion
#region 签证人员团组时间通知
#region 计算出访起止时间
var startTime = new DateTime();
var endTime = new DateTime();
if (DateTime.TryParse(dto.VisitDate, out startTime))
{
endTime = startTime.AddDays(dto.VisitDays - 1);//含当天
}
#endregion
if (diId > 0)
{
await AppNoticeLibrary.SendUserMsg_GroupTimeInfo_ToVisaUser(diId, startTime.ToString("yyyy-MM-dd"), endTime.ToString("yyyy-MM-dd"));
}
#endregion
//_sqlSugar.CommitTran();
return Ok(JsonView(true, "添加成功"));
}
catch (Exception ex)
{
_sqlSugar.RollbackTran();
return Ok(JsonView(false, ex.Message));
}
}
///
/// 接团流程操作(增改)
/// 安卓端使用 建团时添加客户名单
///
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GroupProcessOperation1(GroupProcessOperationDto dto)
{
#region 参数验证
if (dto.UserId < 1) return Ok(JsonView(false, "请传入有效的UserId参数"));
#region 页面操作权限验证
//pageFunAuthView = await GeneralMethod.PostUserPageFuncDatas(dto.UserId, 104);
//if (pageFunAuthView.AddAuth == 0) return Ok(JsonView(false, "客户名单您没有添加权限!"));
var pageFunAuthView = await GeneralMethod.PostUserPageFuncDatas(dto.UserId, 27);
if (pageFunAuthView.AddAuth == 0) return Ok(JsonView(false, "团组操作您没有添加权限!"));
#endregion
#endregion
_sqlSugar.BeginTran();
decimal ffrPrice = 0.00M;
DateTime? visitDt = null;
if (dto.Status == 2)
{
var groupInfo = await _sqlSugar.Queryable().FirstAsync(x => x.Id == dto.Id && x.IsDel == 0);
if (groupInfo != null)
{
ffrPrice = groupInfo.PaymentMoney;
visitDt = groupInfo.VisitDate.AddDays(-groupInfo.PayDay);
}
}
var _dto = new GroupOperationDto();
_dto = _mapper.Map(dto);
var groupData = await _groupRepository.GroupOperation(_dto);
if (groupData.Code != 0)
{
_sqlSugar.RollbackTran();
return Ok(JsonView(false, "团组操作添加失败!" + groupData.Msg));
}
try
{
int diId = 0;
//添加时 默认加入团组汇率
if (dto.Status == 1) //添加
{
diId = groupData.Data;
//添加默认币种
await GeneralMethod.PostGroupRateAddInit(dto.UserId, diId);
//默认分配权限
await GeneralMethod.PostGroupAuthAddInit(dto.UserId, diId);
//消息提示 王鸽 主管号 2024-10-21 新增LZ UID
var _managerIds = new List() { 21, 22, 32 };
var userIds = _usersRep._sqlSugar.Queryable().Where(it => it.IsDel == 0 && _managerIds.Contains(it.JobPostId)).Select(it => it.Id).ToList();
if (userIds.Count > 0)
{
userIds.Add(208);
//创建团组管控
GroupStepForDelegation.CreateWorkStep(diId);
//发送消息
string groupName = dto.TeamName;
string createGroupUser = string.Empty;
var userInfo = _usersRep._sqlSugar.Queryable().Where(it => it.IsDel == 0 && it.Id == dto.UserId).First();
if (userInfo != null) createGroupUser = userInfo.CnName;
string title = $"系统通知";
string content = $"团组[{groupName}(创建人:{createGroupUser})]创建成功,请前往页面进行下一步操作!";
await GeneralMethod.MessageIssueAndNotification(MessageTypeEnum.GroupBusinessOperations, title, content, userIds, diId);
}
#region 应用推送
try
{
await AppNoticeLibrary.SendChatMsg_GroupStatus_Create(diId, QiyeWeChatEnum.CompanyCRMChat);
Sys_Users users = _airTicketResRep.Query(s => s.Id == dto.UserId).First();
Sys_Department department = _airTicketResRep.Query(s => s.Id == users.DepId).First();
if (department.Id == 6 && !string.IsNullOrEmpty(users.QiyeChatUserId))
{
var userList = new List() { users.QiyeChatUserId };
await AppNoticeLibrary.SendUserMsg_GroupStatus_Create(diId, userList);
}
}
catch (Exception ex)
{
_sqlSugar.CommitTran();
return Ok(JsonView(true, "操作成功! 应用推送异常:" + groupData.Msg));
}
#endregion
//默认创建倒推表
await _invertedListRep._Create(dto.UserId, diId);
}
else if (dto.Status == 2)
{
diId = dto.Id;
if (diId == 0)
{
_sqlSugar.RollbackTran();
return Ok(JsonView(false, "操作失败! 未添加团组id" + groupData.Msg));
}
}
var viewData = await _tourClientListRep.OperMultiple(dto.TourClientListInfos, diId, dto.UserId);
if (viewData.Code != 0)
{
_sqlSugar.RollbackTran();
return Ok(JsonView(false, "客户名单添加失败!" + viewData.Msg));
}
#region 团组操作默认添加/修改收款账单
if (dto.PayDay > 0 && dto.PaymentMoney > 0)
{
var ffrInfo = await _sqlSugar.Queryable()
.Where(x => x.IsDel == 0 &&
x.Diid == diId &&
x.Remark.Equals("预付款")
)
.WhereIF(ffrPrice > 0, x => x.ItemSumPrice == ffrPrice)
.WhereIF(visitDt != null, x => x.CreateTime == visitDt)
.FirstAsync();
ffrInfo = new Fin_ForeignReceivables()
{
Diid = diId,
PriceName = dto.ClientUnit,
Price = dto.PaymentMoney,
Count = 1,
Unit = $"元",
ItemSumPrice = dto.PaymentMoney,
Rate = 1.0000M,
Currency = 836,
AddingWay = 0,
CreateUserId = dto.UserId,
CreateTime = Convert.ToDateTime(dto.VisitDate).AddDays(-dto.PayDay),
Remark = $"预付款"
};
if (ffrInfo == null) //Add
{
await _sqlSugar.Insertable(ffrInfo).ExecuteCommandAsync();
}
else //修改
{
await _sqlSugar.Updateable(ffrInfo)
.UpdateColumns(x => new
{
x.PriceName,
x.Price,
x.ItemSumPrice,
x.CreateTime,
x.CreateUserId
})
.WhereColumns(x => x.Id)
.ExecuteCommandAsync();
}
}
#endregion
#region 签证人员团组时间通知
#region 计算出访起止时间
var startTime = new DateTime();
var endTime = new DateTime();
if (DateTime.TryParse(dto.VisitDate, out startTime))
{
endTime = startTime.AddDays(dto.VisitDays - 1);//含当天
}
#endregion
if (diId > 0)
{
await AppNoticeLibrary.SendUserMsg_GroupTimeInfo_ToVisaUser(diId, startTime.ToString("yyyy-MM-dd"), endTime.ToString("yyyy-MM-dd"));
}
#endregion
_sqlSugar.CommitTran();
return Ok(JsonView(true));
}
catch (Exception ex)
{
_sqlSugar.RollbackTran();
return Ok(JsonView(false, ex.Message));
}
}
///
/// 接团信息 操作(删除)
///
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GroupDel(GroupDelDto dto)
{
var diId = dto.Id;
if (diId < 1) return Ok(JsonView(false, MsgTips.Id));
#region 删除 验证
/*
* 1、收款账单数据:0 条
* 2、收款退还数据:0 条
* 3、机票费用数据:0 条
* 4、签证费用数据:0 条
* 5、保险费用数据:0 条
* 6、酒店费用数据:0 条
* 7、公务出访数据:1 条
* 8、邀请公务活动费用数据:1 条
* 9、OP费用数据:5 条
* 10、其他费用数据:0 条
* 11、团组日付报销费用数据:0 条
*
* 温馨提示:该团组已产生费用,不允许删除;如需删除,请先删除对应版块费用,谢谢!
*/
//收款账单
int frCount = _sqlSugar.Queryable().Where(x => x.IsDel == 0 && x.Diid == diId).Count();
//收款退还
int fraomCount = _sqlSugar.Queryable().Where(x => x.IsDel == 0 && x.DiId == diId).Count();
//机票费用
int arCount = _sqlSugar.Queryable().Where(x => x.IsDel == 0 && x.DIId == diId).Count();
//签证费用
int viCount = _sqlSugar.Queryable().Where(x => x.IsDel == 0 && x.DIId == diId).Count();
//保险费用
int cCount = _sqlSugar.Queryable().Where(x => x.IsDel == 0 && x.DiId == diId).Count();
//酒店费用
int hrCount = _sqlSugar.Queryable().Where(x => x.IsDel == 0 && x.DiId == diId).Count();
//公务出访
int oaCount = _sqlSugar.Queryable().Where(x => x.IsDel == 0 && x.DiId == diId).Count();
//邀请公务活动费用
int ioaCount = _sqlSugar.Queryable().Where(x => x.IsDel == 0 && x.DiId == diId).Count();
//OP费用
int ctggrCount = _sqlSugar.Queryable().Where(x => x.IsDel == 0 && x.DiId == diId).Count();
//其他费用
int dpCount = _sqlSugar.Queryable().Where(x => x.IsDel == 0 && x.DiId == diId).Count();
//团组日付报销费用
int dfpCount = _sqlSugar.Queryable().Where(x => x.IsDel == 0 && x.GroupId == diId).Count();
var feeCount = frCount + fraomCount + arCount + viCount + cCount + hrCount + oaCount + ioaCount + ctggrCount + dpCount + dfpCount;
if (feeCount > 0)
{
var delMsgTips = new StringBuilder();
delMsgTips.AppendLine($"1、收款账单数据:{frCount} 条");
delMsgTips.AppendLine($"2、收款退换数据:{fraomCount} 条");
delMsgTips.AppendLine($"3、机票费用数据:{arCount} 条");
delMsgTips.AppendLine($"4、签证费用数据:{viCount} 条");
delMsgTips.AppendLine($"5、保险费用数据:{cCount} 条");
delMsgTips.AppendLine($"6、酒店费用数据:{hrCount} 条");
delMsgTips.AppendLine($"7、公务出访数据:{oaCount} 条");
delMsgTips.AppendLine($"8、邀请公务活动费用数据:{ioaCount} 条");
delMsgTips.AppendLine($"9、OP费用数据:{ctggrCount} 条");
delMsgTips.AppendLine($"10、其他费用数据:{dpCount} 条");
delMsgTips.AppendLine($"11、团组日付报销费用数据:{dfpCount} 条");
delMsgTips.AppendLine($"");
delMsgTips.AppendLine($"温馨提示:该团组已产生费用,不允许删除;如需删除,请先删除对应版块费用,谢谢!");
return Ok(JsonView(false, delMsgTips.ToString()));
}
#endregion
var groupData = await _groupRepository.GroupDel(dto);
if (groupData.Code != 0)
{
return Ok(JsonView(false, groupData.Msg));
}
return Ok(JsonView(true));
}
///
/// 获取团组销售报价号
/// 团组添加时 使用
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GetGroupSalesQuoteNo()
{
var groupData = await _groupRepository.GetGroupSalesQuoteNo();
if (groupData.Code != 0)
{
return Ok(JsonView(false, groupData.Msg));
}
object salesQuoteNo = new
{
SalesQuoteNo = groupData.Data
};
return Ok(JsonView(salesQuoteNo));
}
///
/// 设置确认出团
///
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task SetConfirmationGroup(ConfirmationGroupDto dto)
{
var groupData = await _groupRepository.ConfirmationGroup(dto);
if (groupData.Code != 0)
{
return Ok(JsonView(false, groupData.Msg));
}
var groupInfo = _groupRepository.Query(s => s.Id == dto.GroupId).First();
#region OA消息推送
try
{
string groupName = groupInfo.TeamName;
var userIds = _airTicketResRep.Query(s => s.DepId == 7 && s.IsDel == 0).Select(x => x.Id).ToList();
string title = $"系统通知";
string content = $"团组[{groupName}]已确认出团!";
await GeneralMethod.MessageIssueAndNotification(MessageTypeEnum.GroupBusinessOperations, title, content, userIds, dto.GroupId);
}
catch (Exception ex)
{
}
#endregion
#region 应用推送
try
{
await AppNoticeLibrary.SendChatMsg_GroupStatus_Create(dto.GroupId, QiyeWeChatEnum.CompanyCRMChat);
Sys_Users users = _airTicketResRep.Query(s => s.Id == groupInfo.JietuanOperator).First();
Sys_Department department = _airTicketResRep.Query(s => s.Id == users.DepId).First();
if (department.Id == 6 && !string.IsNullOrEmpty(users.QiyeChatUserId))
{
var userList = new List() { users.QiyeChatUserId };
await AppNoticeLibrary.SendUserMsg_GroupStatus_Create(dto.GroupId, userList);
}
}
catch (Exception ex)
{
}
#endregion
GroupStepForDelegation.CreateWorkStep(dto.GroupId); //创建管控流程
return Ok(JsonView(true, "操作成功!", groupData.Data));
}
///
/// 获取团组名称data And 签证国别Data
///
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GetGroupNameAndVisaNationality(GroupNameDto dto)
{
var groupData = await _groupRepository.GetGroupNameAndVisaNationality(dto);
if (groupData.Code != 0)
{
return Ok(JsonView(false, groupData.Msg));
}
return Ok(JsonView(groupData.Data));
}
///
/// 根据CTable类型返回对应的团组名称及简单数据(APP端)
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task PostGroupNameAndEasy(DecreasePaymentsDto dto)
{
try
{
Result groupData = await _decreasePaymentsRep.PostGroupNameAndEasy(dto);
if (groupData.Code != 0)
{
return Ok(JsonView(false, groupData.Msg));
}
return Ok(JsonView(true, groupData.Msg, groupData.Data));
}
catch (Exception ex)
{
return Ok(JsonView(false, ex.Message));
throw;
}
}
///
/// 团组清单 Excel
///
/// 开始时间 EG:“2024-01-01”
/// 结束时间 EG;“2024-12-31”
///
[HttpGet]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GroupListFile([FromQuery] string beginDt, [FromQuery] string endDt)
{
bool beginBool = DateTime.TryParse($"{beginDt} 00:00:00", out DateTime _beginDt),
endBool = DateTime.TryParse($"{endDt} 23:59:59", out DateTime _endDt);
if (!beginBool && !endBool)
{
return Ok(JsonView(false, "开始或结束时间不正确!"));
}
string sql = string.Format(@"
SELECT
ROW_NUMBER,
Id,
SalesQuoteNo,
TourCode,
TeamTypeId,
TeamType,
TeamLevId,
TeamLev,
TeamName,
ClientName,
ClientUnit,
VisitDate,
VisitDays,
VisitPNumber,
JietuanOperatorId,
JietuanOperator,
IsSure,
CreateUserName,
IsBid
FROM
(
SELECT
ROW_NUMBER() OVER(
ORDER BY
gdi.VisitDate Desc
) AS ROW_NUMBER,
gdi.Id,
SalesQuoteNo,
TourCode,
ssd.Id TeamTypeId,
ssd.Name TeamType,
ssd1.Id TeamLevId,
ssd1.Name TeamLev,
TeamName,
ClientName,
ClientUnit,
VisitDate,
VisitDays,
VisitPNumber,
JietuanOperator JietuanOperatorId,
su.CnName JietuanOperator,
IsSure,
gdi.CreateTime,
su1.CnName As CreateUserName,
gdi.IsBid
FROM
Grp_DelegationInfo gdi
LEFT JOIN Sys_SetData ssd ON gdi.TeamDid = ssd.Id
LEFT JOIN Sys_SetData ssd1 ON gdi.TeamLevSId = ssd1.Id
LEFT JOIN Sys_Users su ON gdi.JietuanOperator = su.Id
LEFT JOIN Sys_Users su1 ON gdi.CreateUserId = su1.Id
WHERE
gdi.IsDel = 0
AND gdi.IsBid = 0
AND gdi.VisitDate BETWEEN '{0}' AND '{1}'
) temp", _beginDt.ToString("yyyy-MM-dd HH:mm:ss"), _endDt.ToString("yyyy-MM-dd HH:mm:ss"));
var groupList = await _sqlSugar.SqlQueryable(sql).ToListAsync();
#region 处理所属部门
/*
* 1.sq 和 gyy 等显示 市场部
* 2.王鸽和主管及张总还有管理员号统一国交部
* 2-1. 4 管理员 ,21 张海麟
*/
var userIds = groupList.Select(it => it.JietuanOperatorId).ToList();
var userIds1 = new List() { 4, 21 };
var userDepDatas = await _sqlSugar.Queryable()
.LeftJoin((u, d) => u.DepId == d.Id)
.Where(u => u.IsDel == 0 && userIds.Contains(u.Id))
.Select((u, d) => new { UserId = u.Id, DepName = userIds1.Contains(u.Id) ? "国交部" : d.DepName })
.ToListAsync();
var droupIds = groupList.Select(it => it.Id).ToList();
var deleClientList = _sqlSugar.Queryable()
.LeftJoin((tcl, dc) => tcl.ClientId == dc.Id && dc.IsDel == 0)
.LeftJoin((tcl, dc, cc) => dc.CrmCompanyId == cc.Id && dc.IsDel == 0)
.Where((tcl, dc, cc) => tcl.IsDel == 0 && droupIds.Contains(tcl.DiId))
.Select((tcl, dc, cc) => new ClientInfoInfo_Group
{
DiId = tcl.DiId,
LastName = dc.LastName,
FirstName = dc.FirstName,
Sex = dc.Sex,
Birthday = dc.BirthDay,
Company = cc.CompanyFullName,
Job = dc.Job,
CreateTime = tcl.CreateTime,
})
.ToList();
foreach (var item in groupList)
{
item.Department = userDepDatas.Find(it => item.JietuanOperatorId == it.UserId)?.DepName ?? "Unknown";
string groupFirstName = "";
var currDatas = deleClientList.Where(x => x.DiId == item.Id).ToList();
if (currDatas.Any())
{
groupFirstName = AesEncryptionHelper.Decrypt(currDatas[0].LastName) + AesEncryptionHelper.Decrypt(currDatas[0].FirstName);
}
item.GroupFirst = groupFirstName;
}
#endregion
#region Excel
var tempPath = AppSettingsHelper.Get("ExcelTempPath");
var servicePath = AppSettingsHelper.Get("GrpFileBaseUrl");
var savePath = AppSettingsHelper.Get("GrpListFileBasePath");
var ftpPath = AppSettingsHelper.Get("GrpListFileFtpPath");
var fileName = $"团组清单({beginDt}~{endDt}){DateTime.Now:yyyyMMddHHmmss}.xlsx";
//载入模板
var designer = new WorkbookDesigner
{
Workbook = new Workbook($"{tempPath}团组清单模板.xlsx")
};
designer.SetDataSource("Titel", $"团组清单({beginDt}~{endDt})");
DataTable dt = CommonFun.GetDataTableFromIList(groupList); ;
dt.TableName = "GroupList";
designer.SetDataSource(dt);
designer.Process();
if (!Directory.Exists(savePath))
{
Directory.CreateDirectory(savePath);
}
string serverPath = $"{savePath}{fileName}";
designer.Workbook.Save(serverPath);
string rst = $"{servicePath}{ftpPath}{fileName}";
#endregion
return Ok(JsonView(true, "操作成功!", rst));
}
///
/// 团组合同下载(1.付款80% 2.付全款)
///
///
///
///
[HttpPost]
public async Task DownGroupContractFile(DownGroupContractFileDto dto)
{
var jw = JsonView(false);
var di = await _sqlSugar.Queryable()
.FirstAsync(x => x.Id == dto.GroupId && x.IsDel == 0);
if (di == null)
{
jw.Msg = "团组Id有误!";
return Ok(jw);
}
#region 权限校验
var allDownFile = new List() { 21 };
try
{
var setting = _sqlSugar.Queryable()
.First(x => x.Id == 1418 && x.IsDel == 0);
allDownFile.AddRange(JsonConvert.DeserializeObject>(setting.Remark));
}
catch (Exception)
{ }
var guojiaoDownFile = new List() { 330, 383 };
var shichangDownFile = new List() { 95 };
if (allDownFile.Contains(dto.UserId))
{
}
else if (guojiaoDownFile.Contains(dto.UserId))
{
var guojiaobuDi = new List() { 4, 21 };
var departmentStr = _sqlSugar.Queryable()
.LeftJoin((d, u) => d.Id == u.DepId && u.IsDel == 0)
.Where((d, u) => u.Id == di.JietuanOperator)
.Select((d, u) => d.DepName)
.First();
if (!guojiaobuDi.Contains(di.JietuanOperator) && departmentStr != "策划部" && departmentStr != "国交部")
{
jw.Msg = "暂无下载权限!";
return Ok(jw);
}
}
else if (shichangDownFile.Contains(dto.UserId))
{
var dic = new Dictionary()
{
{ 95, new int []{ 95 , 337 , 302, 350, 355, 357, 353 , 359 , 361, 368, 364, 366, 369} }
};
try
{
var sqSetting = _sqlSugar.Queryable().First(x => x.Id == 1417);
if (sqSetting != null)
{
Dictionary result = JsonConvert.DeserializeObject>(sqSetting.Remark);
foreach (var item in result.Keys)
{
if (dic.ContainsKey(item))
{
int[] dilatation = new int[dic[item].Length + result[item].Length];
Array.Copy(dic[item], dilatation, dic[item].Length);
Array.Copy(result[item], 0, dilatation, dic[item].Length, result[item].Length);
dic[item] = dilatation;
}
else
{
dic.Add(item, result[item]);
}
}
}
if (!dic[95].Contains(di.CreateUserId))
{
jw.Msg = "暂无下载权限!";
return Ok(jw);
}
}
catch (Exception)
{ }
}
else if (dto.UserId == di.CreateUserId)
{
}
else
{
jw.Msg = "暂无下载权限!";
return Ok(jw);
}
#endregion
var blackCodeList = await _sqlSugar.Queryable()
.Where(x => x.DiId == dto.GroupId && x.IsDel == 0)
.ToListAsync();
if (!blackCodeList.Any())
{
jw.Msg = "该团无机票行程代码!";
return Ok(jw);
}
var groupEnterExitCost = await _sqlSugar.Queryable()
.FirstAsync(x => x.DiId == dto.GroupId && x.IsDel == 0);
if (groupEnterExitCost == null)
{
jw.Msg = "暂无三公费用信息!";
return Ok(jw);
}
var rateList = (List?)CommonFun.GetCurrencyChinaToList(groupEnterExitCost.CurrencyRemark);
rateList ??= new List();
var _DayAndCosts = _sqlSugar.Queryable().Where(it => it.IsDel == 0 && it.DiId == di.Id).ToList();
var dac5 = _sqlSugar.Queryable()
.LeftJoin((x, a) => a.IsDel == 0 && a.Id == x.SetDataId)
.LeftJoin((x, a, b) => b.IsDel == 0 && b.Id == x.Currency)
.Where((x, a, b) => x.IsDel == 0 && x.Diid == di.Id)
.Select((x, a, b) => new
{
x.Index,
itemName = a.Name,
CurrencyStr = b.Name,
x.Cost,
x.SubTotal,
x.Remark
})
.OrderBy((x) => x.Index)
.ToList();
decimal stayFeeTotal = groupEnterExitCost.ChoiceThree == 1 ? _DayAndCosts.Where(it => it.Type == 1).Sum(it => it.SubTotal) : 0.00M; // 住宿费
decimal mealsFeeTotal = groupEnterExitCost.ChoiceFour == 1 ? _DayAndCosts.Where(it => it.Type == 2).Sum(it => it.SubTotal) : 0.00M; // 伙食费费
decimal miscellaneousFeeTotal = groupEnterExitCost.ChoiceFive == 1 ? _DayAndCosts.Where(it => it.Type == 3).Sum(it => it.SubTotal) : 0.00M; // 公杂费
decimal tainFeeTotal = groupEnterExitCost.ChoiceSix == 1 ? _DayAndCosts.Where(it => it.Type == 4).Sum(it => it.SubTotal) : 0.00M; // 培训费
decimal otherPriceTotal = groupEnterExitCost.OtherExpenses_Checked == 1 ? dac5.Sum(x => x.SubTotal) : 0.00M; //其他费用
decimal insidePayTotal = groupEnterExitCost.ChoiceOne == 1 ? groupEnterExitCost.InsidePay : 0.00M;
decimal otherFeeTotal = insidePayTotal + stayFeeTotal + mealsFeeTotal + miscellaneousFeeTotal + tainFeeTotal + otherPriceTotal;
decimal subJJC = 0.00M,
subGWC = 0.00M,
subTDC = 0.00M;
//经济舱
if (groupEnterExitCost.SumJJC == 1)
{
subJJC = otherFeeTotal + groupEnterExitCost.OutsideJJPay;
}
//公务舱
if (groupEnterExitCost.SumGWC == 1)
{
subGWC = otherFeeTotal + groupEnterExitCost.OutsideGWPay;
}
//头等舱
if (groupEnterExitCost.SumTDC == 1)
{
subTDC = otherFeeTotal + groupEnterExitCost.OutsideTDPay;
}
var groupClints = await _sqlSugar.Queryable()
.LeftJoin((x, s) => s.Id == x.ShippingSpaceTypeId && s.IsDel == 0)
.LeftJoin((x, s, dc) => x.ClientId == dc.Id && dc.IsDel == 0)
.LeftJoin((x, s, dc, cc) => dc.CrmCompanyId == cc.Id && cc.IsDel == 0)
.Where((x, s, dc, cc) => x.DiId == dto.GroupId && x.IsDel == 0)
.Select((x, s, dc, cc) => new GroupClints
{
Id = x.Id,
Name = s.Name,
IsAccompany = x.IsAccompany,
CompanyFullName = cc.CompanyFullName
})
.ToListAsync();
groupClints.ForEach(x => x.CompanyFullName = AesEncryptionHelper.Decrypt(x.CompanyFullName));
//获取舱位人数
var cabinCount = groupClints.Where(x => x.IsAccompany != 2 && !x.CompanyFullName.Contains("泛美国际"))
.GroupBy(x => x.Name)
.Select(x => new { Cabin = x.Key, Count = x.Count() })
.ToList();
string cityPath = string.Empty;
string startCity = string.Empty;
string endCity = string.Empty;
foreach (var item in blackCodeList)
{
string city = GeneralMethod.GetGroupCityLine(item, "-");
cityPath += city + "\r\n";
if (item.Equals(blackCodeList.First()))
{
var sp = city.Split('-');
startCity = sp[0];
endCity = sp[^1];
}
}
di.VisitCountry = Regex.Replace(di.VisitCountry, @"[|-]", "、");
var bookMarkDic = new Dictionary
{
{ "ClientUnit", di.ClientUnit },
{ "VisitCountry", di.VisitCountry },
{ "VisitDate", di.VisitDate.ToString("yyyy年MM月dd日") },
{ "VisitPNumber", di.VisitPNumber.ToString() },
{ "CityPath", cityPath },
{ "StartCity", startCity },
{ "EndCity", endCity },
{ "StayDays", $"{di.VisitDays}天{di.VisitDays - 1}晚" }
};
Document doc = null;
var percentage = 0.8M;
var fileNameadd = "预付";
if (dto.FileType == 1)
{
doc = new Document($"{AppSettingsHelper.Get("WordBasePath")}GroupContractFile/Template/团组合同bookmarkFormat.doc");
}
else if (dto.FileType == 2)
{
doc = new Document($"{AppSettingsHelper.Get("WordBasePath")}GroupContractFile/Template/团组合同全款无表格.doc");
percentage = 1;
fileNameadd = "全款";
}
else
{
throw new Exception("FileType有误!");
}
var builder = new DocumentBuilder(doc);
decimal totalPrice = 0.00M;
Table firstTable = (Table)doc.GetChild(NodeType.Table, 0, true);
if (firstTable != null)
{
// 遍历表格的行和单元格
foreach (Aspose.Words.Tables.Row row in firstTable.Rows)
{
for (int i = 0; i < row.Cells.Count; i++)
{
var cell = row.Cells[i];
// 读取单元格内容
string cellTextFirst = row.Cells[0].FirstParagraph.ToString(Aspose.Words.SaveFormat.Text).Trim();
if (cellTextFirst.Contains("舱位"))
{
break;
}
if (cellTextFirst == "经济舱" || cellTextFirst == "公务舱")
{
if (i == 2)
{
if (cellTextFirst == "经济舱")
{
// 设置单元格内容
cell.FirstParagraph.Runs.Clear(); // 清除原有内容
cell.FirstParagraph.AppendChild(new Run(doc, subJJC.ToString())); // 添加
}
else
{
// 设置单元格内容
cell.FirstParagraph.Runs.Clear(); // 清除原有内容
cell.FirstParagraph.AppendChild(new Run(doc, subGWC.ToString())); // 添加
}
}
if (i == 3)
{
var count = cabinCount.Find(x => x.Cabin == cellTextFirst)?.Count;
if (count != null)
{
// 设置单元格内容
cell.FirstParagraph.Runs.Clear(); // 清除原有内容
cell.FirstParagraph.AppendChild(new Run(doc, count.ToString())); // 添加
}
}
if (i == 4)
{
var rowPrice = 0.00M;
var count = cabinCount.Find(x => x.Cabin == cellTextFirst)?.Count;
count ??= 0;
if (cellTextFirst == "经济舱")
{
rowPrice = subJJC * (int)count;
}
else
{
rowPrice = subGWC * (int)count;
}
totalPrice += rowPrice;
// 设置单元格内容
cell.FirstParagraph.Runs.Clear(); // 清除原有内容
cell.FirstParagraph.AppendChild(new Run(doc, rowPrice.ToString())); // 添加
}
}
}
}
}
bookMarkDic.Add("TotalPrice", (totalPrice).ToString("#0.00"));
bookMarkDic.Add("TotalPrice1", (totalPrice * percentage).ToString("#0.00"));
bookMarkDic.Add("TotalPriceChinese", decimal.Parse((totalPrice * percentage).ToString("#0.00")).ConvertCNYUpper());
//--合同表格部分
bookMarkDic.Add("TimeNowDate", DateTime.Now.ToString("yyyy年MM月dd日"));
bookMarkDic.Add("ClientUnit1", di.ClientUnit);
bookMarkDic.Add("VisitCountry1", di.VisitCountry);
bookMarkDic.Add("DayCount", di.VisitDays.ToString());
bookMarkDic.Add("VisitingArea", di.VisitDate.ToString("yyyy年MM月dd日") + "-" + di.VisitEndDate.ToString("yyyy年MM月dd日"));
bookMarkDic.Add("CityPath1", cityPath);
bookMarkDic.Add("CityPath2", cityPath);
Table contractTable = (Table)doc.GetChild(NodeType.Table, 1, true);
if (contractTable != null)
{
//数据源
var _DayAndCostsAndCity = _sqlSugar.Queryable()
.LeftJoin((it, y) => it.NationalTravelFeeId == y.Id && y.IsDel == 0)
.LeftJoin((it, y, s) => s.IsDel == 0 && s.Id == it.Currency)
.Where((it, y, s) => it.IsDel == 0 && it.DiId == di.Id)
.Select((it, y, s) => new
{
it.Cost,
it.SubTotal,
it.Type,
y.Id,
y.City,
s.Name,
CurrencyCodeCn = s.Remark
})
.ToList()
.Select(x => new
{
CurrencyCode = x.Name,
CityId = x.Id,
x.City,
di.VisitPNumber,
x.Type,
x.Cost,
x.SubTotal,
rateList.Find(y => y.CurrencyCode == x.Name)?.Rate,
x.CurrencyCodeCn,
});
var dac1 = _DayAndCostsAndCity.Where(it => it.Type == 1).GroupBy(x => x.CityId).ToList(); //住宿费
var dac2 = _DayAndCostsAndCity.Where(it => it.Type == 2).GroupBy(x => x.CityId).ToList(); //伙食费
var dac3 = _DayAndCostsAndCity.Where(it => it.Type == 3).GroupBy(x => x.CityId).ToList(); //公杂费
var dac4 = _DayAndCostsAndCity.Where(it => it.Type == 4).GroupBy(x => x.CityId).ToList(); //培训费
var tableSettings = new List()
{
new(){ Index = 1 , Property = "City"},
new(){ Index = 2 , Property = "CurrencyCodeCn"},
new(){ Index = 3 , Property = "Cost"},
new(){ Index = 4 , Property = "VisitPNumber"},
//new tableSetting{ Index = 5 , Property = ""},
//new tableSetting{ Index = 6 , Property = ""},
new(){ Index = 7 , Property = "Rate"},
//new tableSetting{ Index = 8 , Property = ""},
};
//1.住宿费
int cloneRow = 8;
int startDayPrice = 8; //写入index
decimal ZSPriceSum = 0.00M, HSPriceSum = 0.00M, GZPriceSum = 0.00M;
foreach (var dac in dac1)
{
var first = dac.First();
var dayCount = dac.Count();
Aspose.Words.Tables.Row row = contractTable.Rows[startDayPrice];
for (int i = 1; i < row.Cells.Count; i++)
{
var cell = row.Cells[i];
var findProperty = tableSettings.Find(x => x.Index == i);
if (findProperty != null)
{
string value = first.GetType().GetProperty(findProperty.Property).GetValue(first).ToString();
// 设置单元格内容
cell.FirstParagraph.Runs.Clear(); // 清除原有内容
cell.FirstParagraph.AppendChild(new Run(doc, value)); // 添加
}
else
{
switch (i)
{
case 5:
cell.FirstParagraph.Runs.Clear();
cell.FirstParagraph.AppendChild(new Run(doc, dayCount.ToString()));
break;
case 6:
var xiaoji = dayCount * first.VisitPNumber * first.Cost;
cell.FirstParagraph.Runs.Clear();
cell.FirstParagraph.AppendChild(new Run(doc, xiaoji.ToString("F2")));
break;
case 8:
var xiaojiRMB = dayCount * first.VisitPNumber * first.SubTotal;
cell.FirstParagraph.Runs.Clear();
cell.FirstParagraph.AppendChild(new Run(doc, xiaojiRMB.ToString("F2")));
ZSPriceSum += xiaojiRMB;
break;
default:
break;
}
}
}
startDayPrice++;
if (!dac1.Last().Equals(dac))
{
Aspose.Words.Tables.Row newRow = (Aspose.Words.Tables.Row)contractTable.Rows[cloneRow].Clone(true);
// 将克隆的行追加到原行后面
contractTable.Rows.Insert(startDayPrice, newRow);
}
else
{
cloneRow += dac1.Count + 1;
startDayPrice = cloneRow;
}
}
//2.伙食费
foreach (var dac in dac2)
{
var first = dac.First();
var dayCount = dac.Count();
Aspose.Words.Tables.Row row = contractTable.Rows[startDayPrice];
for (int i = 1; i < row.Cells.Count; i++)
{
var cell = row.Cells[i];
var findProperty = tableSettings.Find(x => x.Index == i);
if (findProperty != null)
{
string value = first.GetType().GetProperty(findProperty.Property).GetValue(first).ToString();
// 设置单元格内容
cell.FirstParagraph.Runs.Clear(); // 清除原有内容
cell.FirstParagraph.AppendChild(new Run(doc, value)); // 添加
}
else
{
switch (i)
{
case 5:
cell.FirstParagraph.Runs.Clear();
cell.FirstParagraph.AppendChild(new Run(doc, dayCount.ToString()));
break;
case 6:
var xiaoji = dayCount * first.VisitPNumber * first.Cost;
cell.FirstParagraph.Runs.Clear();
cell.FirstParagraph.AppendChild(new Run(doc, xiaoji.ToString("F2")));
break;
case 8:
var xiaojiRMB = dayCount * first.VisitPNumber * first.SubTotal;
cell.FirstParagraph.Runs.Clear();
cell.FirstParagraph.AppendChild(new Run(doc, xiaojiRMB.ToString("F2")));
HSPriceSum += xiaojiRMB;
break;
default:
break;
}
}
}
startDayPrice++;
if (!dac2.Last().Equals(dac))
{
Aspose.Words.Tables.Row newRow = (Aspose.Words.Tables.Row)contractTable.Rows[cloneRow].Clone(true);
// 将克隆的行追加到原行后面
contractTable.Rows.Insert(startDayPrice, newRow);
}
else
{
cloneRow += dac2.Count + 1;
startDayPrice = cloneRow;
}
}
//3.公杂费
foreach (var dac in dac3)
{
var first = dac.First();
var dayCount = dac.Count();
Aspose.Words.Tables.Row row = contractTable.Rows[startDayPrice];
for (int i = 1; i < row.Cells.Count; i++)
{
var cell = row.Cells[i];
var findProperty = tableSettings.Find(x => x.Index == i);
if (findProperty != null)
{
string value = first.GetType().GetProperty(findProperty.Property).GetValue(first).ToString();
// 设置单元格内容
cell.FirstParagraph.Runs.Clear(); // 清除原有内容
cell.FirstParagraph.AppendChild(new Run(doc, value)); // 添加
}
else
{
switch (i)
{
case 5:
cell.FirstParagraph.Runs.Clear();
cell.FirstParagraph.AppendChild(new Run(doc, dayCount.ToString()));
break;
case 6:
var xiaoji = dayCount * first.VisitPNumber * first.Cost;
cell.FirstParagraph.Runs.Clear();
cell.FirstParagraph.AppendChild(new Run(doc, xiaoji.ToString("F2")));
break;
case 8:
var xiaojiRMB = dayCount * first.VisitPNumber * first.SubTotal;
cell.FirstParagraph.Runs.Clear();
cell.FirstParagraph.AppendChild(new Run(doc, xiaojiRMB.ToString("F2")));
GZPriceSum += xiaojiRMB;
break;
default:
break;
}
}
}
startDayPrice++;
if (!dac3.Last().Equals(dac))
{
Aspose.Words.Tables.Row newRow = (Aspose.Words.Tables.Row)contractTable.Rows[cloneRow].Clone(true);
// 将克隆的行追加到原行后面
contractTable.Rows.Insert(startDayPrice, newRow);
}
else
{
cloneRow += dac3.Count + 1;
startDayPrice = cloneRow;
}
}
//合并单元格
for (int i = 8; i < contractTable.Rows.Count - 1; i++)
{
var currentRow = contractTable.Rows[i];
var nextRow = contractTable.Rows[i + 1];
// 获取当前行和下一行的第一个单元格
Cell currentCell = currentRow.Cells[0];
Cell nextCell = nextRow.Cells[0];
// 检查单元格内容是否一致(去除尾部的换行符)
string currentText = currentCell.GetText().Trim();
string nextText = nextCell.GetText().Trim();
if (currentText == nextText)
{
// 如果当前单元格已经被合并,找到合并的起始单元格
if (currentCell.CellFormat.VerticalMerge == CellMerge.Previous)
{
// 找到合并的起始单元格
int mergeStartIndex = FindMergeStartRowIndex(contractTable, i);
// 将下一行的单元格设置为合并的后续单元格
nextCell.CellFormat.VerticalMerge = CellMerge.Previous;
}
else
{
// 如果当前单元格是合并的起始单元格
currentCell.CellFormat.VerticalMerge = CellMerge.First;
// 将下一行的单元格设置为合并的后续单元格
nextCell.CellFormat.VerticalMerge = CellMerge.Previous;
}
}
else
{
// 如果内容不一致,重置当前单元格的合并属性
if (currentCell.CellFormat.VerticalMerge == CellMerge.Previous)
{
// 如果当前单元格是合并的后续单元格,找到合并的起始单元格并重置
int mergeStartIndex = FindMergeStartRowIndex(contractTable, i);
contractTable.Rows[mergeStartIndex].Cells[0].CellFormat.VerticalMerge = CellMerge.First;
}
else
{
currentCell.CellFormat.VerticalMerge = CellMerge.None;
}
}
}
bookMarkDic.Add("ZSPriceSum", ZSPriceSum.ToString("F2"));
bookMarkDic.Add("HSPriceSum", HSPriceSum.ToString("F2"));
bookMarkDic.Add("GZPriceSum", GZPriceSum.ToString("F2"));
}
foreach (var bookmarkName in bookMarkDic.Keys)
{
Bookmark bookmark = doc.Range.Bookmarks[bookmarkName];
if (bookmark != null)
{
if (bookmarkName == "ClientUnit")
{
// 移动到书签位置
builder.MoveTo(bookmark.BookmarkStart);
// 设置字体样式为下划线
builder.Font.Underline = Aspose.Words.Underline.Single;
// 插入书签值
builder.Write(bookMarkDic[bookmarkName]);
// 清除字体格式,避免影响后续文本
builder.Font.ClearFormatting();
}
else
{
builder.MoveToBookmark(bookmarkName);
builder.Write(bookMarkDic[bookmarkName]);
}
}
}
string savePaht = $"{AppSettingsHelper.Get("WordBasePath")}GroupContractFile/Export/{di.TeamName}_{fileNameadd}版本合同文件.doc";
doc.Save(savePaht);
jw.Msg = "生成成功!";
jw.Code = 200;
jw.Data = new { Url = AppSettingsHelper.Get("WordBaseUrl") + savePaht.Replace(AppSettingsHelper.Get("WordBasePath"), AppSettingsHelper.Get("WordFtpPath")) };
return Ok(jw);
}
static int FindMergeStartRowIndex(Table table, int rowIndex)
{
int index = rowIndex;
while (index > 0 && table.Rows[index].Cells[0].CellFormat.VerticalMerge == CellMerge.Previous)
{
index--;
}
return index;
}
///
/// 报批完成企微通知
///
///
///
[HttpPost]
public async Task EnterpriseWeChatNotificationAsyncBaoPi(EnterpriseWeChatNotificationAsyncBaoPiDto dto)
{
int currUserId = dto.currUserId;
int diid = dto.diid;
var jw = JsonView(true);
var users = new List();
var ssd = _sqlSugar.Queryable()
.First(x => x.Id == 1460);
try
{
users = JsonConvert.DeserializeObject>(ssd.Remark);
var groupModuleOperators = GeneralMethod.GetGroupModuleOperators(dto.diid);
//添加分配人员
// 79 车/导游地接
// 80 签证
// 81 邀请/公务活动
var setdataids = new List() { 79, 81 };
foreach (var groupModule in groupModuleOperators)
{
if (setdataids.Contains(groupModule.CTableId))
{
users.AddRange(groupModule.OperationUsers.Select(x => x.UserId.ToString()));
}
}
var res = await AppNoticeLibrary.SendUserMsg_BaoPi_ToUser(users, diid);
//消息通知成功 更改团组step、记录日志
if (res)
{
var groupStep = 0; //0-新建 1-企微消息通知
//更改团组step
var updStatus = await _sqlSugar.Updateable()
.SetColumns(x => new Grp_DelegationInfo()
{
Step = 2
})
.Where(x => x.Id == diid && x.IsDel == 0)
.ExecuteCommandAsync();
if (updStatus > 0) groupStep = 2;
string groupStepLabel = groupStep switch
{
1 => "新建",
2 => "企微消息通知(报批)",
_ => "未设置"
};
//记录日志
var teamName = _sqlSugar.Queryable()
.Where(x => x.Id == diid && x.IsDel == 0)
.Select(x => x.TeamName)
.First() ?? "-";
var operationName = _sqlSugar.Queryable()
.Where(x => x.Id == currUserId && x.IsDel == 0)
.Select(x => x.CnName)
.First() ?? "-";
_groupTextLogger.LogInformation("团组:【{teamName}({groupId})】 操作人:【{operationName}】 操作时间:【{operationTime}】{logContent}", teamName, diid, operationName, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), groupStepLabel);
//设置 签证流程初始值
await _visaProcessRep.UpdateBatchTop4Step(dto.diid, dto.currUserId);
}
}
catch (Exception ex)
{
return Ok(JsonView(false, ex.Message));
}
return Ok(jw);
}
#endregion
#region 团组&签证
#region 团组&签证 New
///
/// 团组&签证 New
/// DeepSeek API:测试API连通性
///
/// 请求dto
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task TestDeepSeekApiConnectivityAsync()
{
return Ok(JsonView(await _deepSeekService.TestApiConnectivityAsync()));
}
///
/// 团组&签证 New
/// DeepSeek API:检查可用端点
///
/// 请求dto
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task DiscoverAvailableEndpointsAsync()
{
return Ok(JsonView(await _deepSeekService.DiscoverAvailableEndpointsAsync()));
}
///
/// 团组&签证 New
/// 上传签证文件(客户填写签证文件),新增或更新 签证信息
///
/// 文件
///
/// 1. 澳新签证个人申请表
/// 2. 出国个人申请表
/// 3. 美国签证个人申请表格
/// 4. 沙特个人信息表格
/// 5. 申根签证个人资料表
/// 6. 中文个人简历模板
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task VisaFileUploadAndUpdate(IFormFile visaFile, int fileTypeId)
{
//文件验证
if (visaFile.Length < 1) return Ok(JsonView(false, "请选择文件!"));
//var visaFiles = new VisaUploadFileTypeView();
//var filetypes = VisaUploadFileTypeView.GetVisaUploadFileTypeViewItemInit();
//if (!filetypes.Any(x => x.FileId == fileTypeId)) return Ok(JsonView(false, "请选择文件类型!"));
//服务器存储文件
var fileServerPath = $"D:/FTP/File/OA2023/Office/Word/VisaClientData/Uploads";
if (!Directory.Exists(fileServerPath)) Directory.CreateDirectory(fileServerPath);
var filePath = Path.Combine(fileServerPath, visaFile.FileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
await visaFile.CopyToAsync(stream);
}
//日志记录-上传文件
_logger.LogInformation("【签证上传文件操作信息】签证文件存储成功!路径:{fileServerPath} 文件名称:{fileName}", fileServerPath, visaFile.FileName);
#region 上传文件到DeepSeekAPI
//IFormFile localFile = null;
////获取项目中的cs文件
//try
//{
// _logger.LogInformation("读取并上传项目文件请求");
// // 1. 读取项目文件
// var readResponse = await _deepSeekService.ReadProjectFilesAsync(new List() { @"OASystem.Domain\ViewModels\VisaFormDetails\AusNewVisaApplicationForm.cs" });
// if (readResponse.SuccessCount == 0)
// {
// return Ok(JsonView(false, "读取项目文件失败"));
// }
// localFile = readResponse.FileInfos.FirstOrDefault().FormFile;
//}
//catch (Exception ex)
//{
// _logger.LogError(ex, "读取项目文件失败");
// return Ok(JsonView(false, "读取项目文件失败"));
//}
//if (localFile == null)
//{
// return Ok(JsonView(false, "读取项目文件失败"));
//}
//var fileReq = new DeepSeekFileUploadRequest()
//{
// Files = new List { localFile, visaFile },
//};
//var filesResult = new List();
//try
//{
// _logger.LogInformation("开始上传 {FileCount} 个文件到DeepSeek API", fileReq.Files.Count);
// filesResult = await _deepSeekService.UploadFilesAsync(fileReq.Files, fileReq.Purpose);
// // 需要等待处理完成
// if (fileReq.WaitForProcessing)
// {
// foreach (var result in filesResult)
// {
// if (result.Success)
// {
// try
// {
// var processedFile = await _deepSeekService.WaitForFileProcessingAsync(result.FileId);
// result.Status = processedFile.Status;
// }
// catch (Exception ex)
// {
// _logger.LogError(ex, "DeepSeek API文件上传失败");
// return Ok(JsonView(false, $"DeepSeek API文件上传处理失败: {ex.Message}"));
// }
// }
// }
// }
//}
//catch (Exception ex)
//{
// _logger.LogError(ex, "DeepSeek API文件上传失败");
// return Ok(JsonView(false, $"DeepSeek API文件上传处理失败: {ex.Message}"));
//}
//#endregion
//if (filesResult == null || filesResult.Count < 1)
//{
// return Ok(JsonView(false, $"DeepSeek API文件上传处理失败"));
//}
////
//try
//{
// var fileIds = filesResult.Where(x => x.Success).Select(x => x.FileId).ToList();
// _logger.LogInformation("使用 {FileCount} 个文件进行聊天", fileIds.Count);
// string question = string.Format("将上传的文件内容按照识别为JSON格式,并按照 AusNewVisaApplicationForm 指定的实体类结构进行映射。确保字段和值对应、文档中数据的完整性、复选框选择打勾后的文本。第一项从不识别\"比如美国(2024年7月29日)\"相关文字。");
// var response = await _deepSeekService.ChatWithFilesAsync(fileIds, question);
// return Ok(response);
//}
//catch (Exception ex)
//{
// _logger.LogError(ex, "使用文件聊天失败");
// return Ok(JsonView(false, $"聊天失败: {ex.Message}"));
//}
#endregion
#region kimi API
//加载文件OpCarTouristGuideGroundContent
//kimi AI 识别文档返回json结果
int kimiAI_API_Index = 0; //KIMI-AI-API 访问计次
var KiMiApi = new KiMiApiClient();
var files = new List() { visaFile };
var seedConter = await KiMiApi.UploadFilesAsync(files);
if (seedConter.Count == 0) return Ok(JsonView(false, "Kimi AI 文件上传结果为空!"));
//var seedMessage = filetypes.Where(x => x.FileId == fileTypeId).FirstOrDefault()?.KimiAITips;
var seedMessage = string.Format(@"你是领事馆电子材料审核员,只关注 Word 里的表格,正文、页眉页脚、水印、批注全部忽略。
任务:把表格里的每个可填字段转换成“标题:值”的键值对,标题用原文,值用原文,不翻译。
规则如下:
1. 行列对齐:先按视觉补齐所有合并单元格——纵向合并则重复上方单元格内容,横向合并则留空字符串;无线表按对齐虚拟列线。
2. 单格内出现多个“□”时,把被勾选(☑、√、×、■)的选项原文输出;若没有任何勾选,该字段输出 null。
3. 所有日期统一转 yyyy-mm-dd,原格式“1990年1月1日”→1990-01-01;若缺日/月,用-01补位。
4. 电话、传真、手机号:输出连续数字,遇到“(0 )”或“-”一律删除,只保留 7~15 位数字;若缺区号,原样保留。
5. 金额:保留原数字,如“3000”。
6. 地址:省、市、区、街道、门牌、邮编用空格分隔,不省略。
7. 若同一张表出现“现住址”“家庭地址”“单位地址”等多列,依次编号 address_home / address_unit / address_legal。
8. 输出顺序:按表格从左到右、从上到下逐行扫描,字段名重复时加序号,如 child_name_1、child_name_2。
9. 结果格式:每行一个键值对,字段名与值之间用英文冒号+空格分隔,不要表格 Markdown,不要多余说明。
10. 文件命名空间:每份表的最前面加一行 filename 作为起始标记(例:出国个人申请表.doc)。
11. 内容为空的字段,显示标题,记空值。
12. 只返回json结果,不需要其他内容;json内容去掉换行。");
var messages = new List
{
new() { Role = KimiRole.system, Content = "你是 Kimi,由 Moonshot AI 提供的人工智能助手,你更擅长识别文件为Json格式的对话。你会为用户提供安全,有帮助,准确的回答。同时,你会拒绝一切涉及恐怖主义,种族歧视,黄色暴力等问题的回答。Moonshot AI 为专有名词,不可翻译成其他语言。" },
new() { Role = KimiRole.user, Content = seedMessage }
};
messages.InsertRange(1, seedConter);
string jsonString = string.Empty;
object jsonData = null;
bool isJson = false; // 是否是json格式 不是json格式继续访问AI
while (!isJson)
{
kimiAI_API_Index++;
var kimiApiResult = await KiMiApi.SeedMessage(messages);
var kimiApiResult_JObject = JObject.Parse(kimiApiResult);
jsonString += kimiApiResult_JObject["content"].ToString();
string startStr = "```json", endStr = "```";
// 判断并清除开头部分
if (jsonString.StartsWith(startStr))
{
jsonString = jsonString.Replace(startStr, "");
}
// 判断并清除结尾部分
if (jsonString.EndsWith(endStr))
{
jsonString = jsonString.Replace(endStr, "");
}
//验证json格式是否正确
try
{
jsonData = JsonDocument.Parse(jsonString);
isJson = true; // 如果解析成功,则是json格式
}
catch (Exception)
{
//messages = new List() { new() { Role = KimiRole.user, Content = "接着说" } };
messages.Add(new() { Role = KimiRole.user, Content = "接着上一个话题继续完成未完成的内容。" });
}
}
if (jsonData == null)
{
return Ok(JsonView(false, "kimi识别json转换失败。"));
}
var visaDetails = new VisaDetailsView();
//按照表格类型分别进行参数处理
// 1. 澳新签证个人申请表
// 2. 出国个人申请表
// 3. 美国签证个人申请表格
// 4. 沙特个人信息表格
// 5. 申根签证个人资料表
// 6. 中文个人简历模板
switch (fileTypeId)
{
//澳新签证个人申请表
case 1:
_logger.LogInformation("【签证上传文件操作信息】【澳新签证个人申请表】【KIMI-AI-API访问计次】{count} 次", kimiAI_API_Index);
VisaApplication resInfo = System.Text.Json.JsonSerializer.Deserialize(jsonString);
break;
//美国签证个人申请表格
case 3:
_logger.LogInformation("【签证上传文件操作信息】【美国签证个人申请表格】【KIMI-AI-API访问计次】{count} 次", kimiAI_API_Index);
string name = (string)jsonData.GetType().GetProperty("姓名")!.GetValue(jsonData)!;
string passportNo = (string)jsonData.GetType().GetProperty("护照号码")!.GetValue(jsonData)!;
string passportPlace = (string)jsonData.GetType().GetProperty("护照签发地")!.GetValue(jsonData)!;
string idNo = (string)jsonData.GetType().GetProperty("身份证号码")!.GetValue(jsonData)!;
string maritalStatusText = (string)jsonData.GetType().GetProperty("婚姻状况")!.GetValue(jsonData)!;
int maritalStatus = maritalStatusText switch
{
"未设置" => 0,
"未婚" => 1,
"已婚" => 2,
"离异" => 3,
"丧偶" => 4,
_ => -1
};
string birthDay = (string)jsonData.GetType().GetProperty("出生日期")!.GetValue(jsonData)!;
DateTime.TryParse(birthDay, out DateTime birthDayDt);
string birthPlace = (string)jsonData.GetType().GetProperty("出生地点")!.GetValue(jsonData)!;
var birthDay1 = CommonFun.SplitProvinceCity(birthPlace);
string birthDay_mate = (string)jsonData.GetType().GetProperty("配偶出生日期")!.GetValue(jsonData)!;
DateTime.TryParse(birthDay_mate, out DateTime birthDayDt_mate);
string birthPlace_mate = (string)jsonData.GetType().GetProperty("配偶出生地")!.GetValue(jsonData)!;
var birthDay1_mate = CommonFun.SplitProvinceCity(birthPlace_mate);
var addressText = (string)jsonData.GetType().GetProperty("家庭地址")!.GetValue(jsonData)!;
var address = SplitAddressZip(addressText);
//美国驾照信息
string driveText = (string)jsonData.GetType().GetProperty("是否有美国驾照")!.GetValue(jsonData)!;
var driveInfo = LicenseParser(driveText);
//美国社会安全号或者纳税ID号
string ssnText = (string)jsonData.GetType().GetProperty("是否有美国社会安全号或者纳税ID号")!.GetValue(jsonData)!;
//单位信息
string clientName = (string)jsonData.GetType().GetProperty("目前就职单位或就读学校")!.GetValue(jsonData)!;
string clientAddr = (string)jsonData.GetType().GetProperty("目前就职单位或就读学校地址")!.GetValue(jsonData)!;//
var (hasSsnItin, number) = SsnItinParser(ssnText);
//婚姻相关
var WeddingText = (string)jsonData.GetType().GetProperty("若离婚,婚姻起止时间")!.GetValue(jsonData)!;
var (f, t) = WeddingParser(WeddingText);
//美国联系人电话和邮箱
var peText = (string)jsonData.GetType().GetProperty("联系人电话及邮箱")!.GetValue(jsonData)!;
var usa_phone = Regex.Match(peText ?? "", @"[\d-]+").Value; // 数字和中横线
var usa_email = Regex.Match(peText ?? "", @"[^@\s]+@[^@\s]+\.[^@\s]+").Value;
//赴美时间、停留时间处理
var usa_dateText = (string)jsonData.GetType().GetProperty("联系人电话及邮箱")!.GetValue(jsonData)!;
var (usa_d, usa_days) = TravelParser(usa_dateText);
//赴美同行人
string usaCmpNameText = (string)jsonData.GetType().GetProperty("赴美同行人")!.GetValue(jsonData)!;
string usaCmpName = string.Empty;
if (usaCmpNameText.Contains("是"))
{
var usaCmpNameTextSplit = usaCmpNameText.Replace(":", "-").Replace("", "-").Split("-");
if (usaCmpNameTextSplit.Length > 1)
{
usaCmpName = usaCmpNameTextSplit[1];
}
}
//是否丢失过护照
string loseCodeText = (string)jsonData.GetType().GetProperty("是否丢失过护照")!.GetValue(jsonData)!;
string loseCode = string.Empty;
if (loseCodeText.Contains("是"))
{
var loseCodeTextSplit = loseCodeText.Replace(":", "-").Replace("", "-").Split("-");
if (loseCodeTextSplit.Length > 1)
{
usaCmpName = loseCodeTextSplit[1];
}
}
//是否获得过美国签证
string usaVisaText = (string)jsonData.GetType().GetProperty("是否丢失过护照")!.GetValue(jsonData)!;
string usaVisaDateText = (string)jsonData.GetType().GetProperty("获得日期")!.GetValue(jsonData)!;
//DateTime usaVisaDate;
if (!string.IsNullOrEmpty(usaVisaDateText))
{
if (DateTime.TryParse(usaVisaDateText, out DateTime usaVisaDate))
{
visaDetails.ClientInfo.GetUSAVisaDate = usaVisaDate;
}
}
string usaFingerText = (string)jsonData.GetType().GetProperty("是否留过十指指纹")!.GetValue(jsonData)!;
int usaFinger = 0;
if (usaFingerText.Contains('是')) usaFinger = 1;
string usaLoseText = (string)jsonData.GetType().GetProperty("签证是否曾遗失")!.GetValue(jsonData)!;
int usaLose = 0;
if (usaLoseText.Contains("是")) usaLose = 1;
//是否曾抵达过美国
string usaHadArrivalText = (string)jsonData.GetType().GetProperty("是否曾抵达过美国")!.GetValue(jsonData)!;
var (usaHadArrivalf, usaHadArrivalD, usaHadArrivalDays) = TravelHadFlagParser(usaHadArrivalText);
//是否有被美国拒发签证的经历
string usaRejecteVisaTest = (string)jsonData.GetType().GetProperty("是否有被美国拒发签证的经历")!.GetValue(jsonData)!;
var (denied, rejectedDate, rejectedPlace, rejectedType) = VisaDenialParser(usaRejecteVisaTest);
if (denied)
{
visaDetails.ClientInfo.RejectedDate = rejectedDate;
visaDetails.ClientInfo.RejectedPlace = rejectedPlace;
visaDetails.ClientInfo.RejectedVisa = rejectedType;
}
//是否在申请或曾经申请过美国移民签证
string usaImmVisaText = (string)jsonData.GetType().GetProperty("是否在申请或曾经申请过美国移民签证")!.GetValue(jsonData)!;
var (immDenied, immDate, immPlace, immType) = VisaDenialParser(usaImmVisaText);
if (immDenied)
{
visaDetails.ClientInfo.USAImmVisaDate = immDate;
visaDetails.ClientInfo.USAImmVisaPlace = immPlace;
visaDetails.ClientInfo.USAImmVisa = immType;
}
//在美直系
string usaImmedText = (string)jsonData.GetType().GetProperty("是否有直系亲属在美国")!.GetValue(jsonData)!;
var (immedDenied, immedName, immedRel, immedStat) = FourFieldParser(usaImmedText);
if (immedDenied)
{
visaDetails.ClientInfo.USAImmedFamName = immedName;
visaDetails.ClientInfo.USAImmedFamRel = immedRel;
visaDetails.ClientInfo.USAImmedFamStat = immedStat;
}
//在美旁系
string usaUncleText = (string)jsonData.GetType().GetProperty("是否有旁系亲属在美国")!.GetValue(jsonData)!;
var (uncleDenied, uncleName, uncleRel, uncleStat) = FourFieldParser(usaUncleText);
if (immedDenied)
{
visaDetails.ClientInfo.USAUncleFamName = uncleName;
visaDetails.ClientInfo.USAUncleFamRel = uncleName;
visaDetails.ClientInfo.USAUncleFamStat = uncleStat;
}
//服役时间 MilitaryParser
string militaryText = (string)jsonData.GetType().GetProperty("是否曾参过军")!.GetValue(jsonData)!;
var (militaryH, militaryB, militaryR, militaryS, (militaryStart, militaryEnd)) = MilitaryParser(militaryText);
var militarys = new List();
if (militaryH)
{
militarys.Add(new()
{
MilBranch = militaryB,
MilRank = militaryR,
MilSkill = militaryS,
ServeTimeBegin = militaryStart,
ServeTimeEnd = militaryEnd,
});
}
//申请人父母信息 ParentParser
string fthMthText = (string)jsonData.GetType().GetProperty("申请人父母信息")!.GetValue(jsonData)!;
if (!string.IsNullOrEmpty(fthMthText))
{
var (fName, fDob, mName, mDob) = ParentParser(fthMthText);
visaDetails.ClientInfo.FthName = fName;
visaDetails.ClientInfo.FthBirth = fDob;
visaDetails.ClientInfo.MthName = mName;
visaDetails.ClientInfo.MthBirth = mDob;
}
visaDetails.ClientInfo = new()
{
LastName = name.GetLastName(),
FirstName = name.GetFirstName(),
Sex = (string)jsonData.GetType().GetProperty("性别")!.GetValue(jsonData)! == "男" ? 0 : 1,
OldName = (string)jsonData.GetType().GetProperty("曾用名")!.GetValue(jsonData)!,
BirthDay = birthDayDt,
BirthProvince = birthDay1.province,
BirthCity = birthDay1.city,
Address = address.address,
PostCodes = address.zipCode,
Marriage = maritalStatus,
MateName = (string)jsonData.GetType().GetProperty("配偶姓名")!.GetValue(jsonData)!,
MateBirthDay = birthDayDt_mate,
MateBirthCountry = birthDay1_mate.province,
MateBirthCity = birthDay1_mate.city,
USA_DLNo = driveInfo.number,
USA_DLPlace = driveInfo.place,
USA_SSNOrITIN = number,
Resident = CleanPrefix((string)jsonData.GetType().GetProperty("是否是其他国家的永久居民")!.GetValue(jsonData)!),
HasSocialAcc = CleanPrefix((string)jsonData.GetType().GetProperty("近五年内是否使用过任何社交账号")!.GetValue(jsonData)!),
WeddingDate = f,
DivorceDate = t,
DivorceRsn = (string)jsonData.GetType().GetProperty("离婚原因")!.GetValue(jsonData)!,
Job = (string)jsonData.GetType().GetProperty("职务")!.GetValue(jsonData)!,
Wage = (string)jsonData.GetType().GetProperty("月薪")!.GetValue(jsonData)!,
WorkState = (string)jsonData.GetType().GetProperty("工作职责")!.GetValue(jsonData)!,
WorkDate = (string)jsonData.GetType().GetProperty("入职/入学时间(详细到月)")!.GetValue(jsonData)!,
USAAddress = (string)jsonData.GetType().GetProperty("请提供美国详细住址")!.GetValue(jsonData)!,
USAPurpose = (string)jsonData.GetType().GetProperty("赴美目的")!.GetValue(jsonData)!,
CostBearers = (string)jsonData.GetType().GetProperty("费用谁付")!.GetValue(jsonData)!,
USAContact = (string)jsonData.GetType().GetProperty("美国联系人或组织")!.GetValue(jsonData)!,
USAContactTel = usa_phone,
USAContactEmail = usa_email,
USADate = usa_d,
USADays = usa_days,
USAArrivalCity = (string)jsonData.GetType().GetProperty("赴美的到达城市")!.GetValue(jsonData)!,
USADepartCity = (string)jsonData.GetType().GetProperty("赴美的离开城市")!.GetValue(jsonData)!,
USAVisitSites = (string)jsonData.GetType().GetProperty("计划在美国访问的景点")!.GetValue(jsonData)!,
USACmpName = usaCmpName,
USACmpRelation = (string)jsonData.GetType().GetProperty("同行人关系")!.GetValue(jsonData)!,
Tel = (string)jsonData.GetType().GetProperty("家庭电话")!.GetValue(jsonData)!,
ClientPhone = (string)jsonData.GetType().GetProperty("单位电话")!.GetValue(jsonData)!,
Phone = (string)jsonData.GetType().GetProperty("移动电话")!.GetValue(jsonData)!,
Cntry5Y = (string)jsonData.GetType().GetProperty("过去5年内到过的国家")!.GetValue(jsonData)!,
LangSkill = (string)jsonData.GetType().GetProperty("面签时能流利交流的语言")!.GetValue(jsonData)!,
LoseCode = loseCode,
DenyNationRsn = (string)jsonData.GetType().GetProperty("曾被哪些国家拒签/拒签原因")!.GetValue(jsonData)!,
USAVisaCode = (string)jsonData.GetType().GetProperty("签证号码")!.GetValue(jsonData)!,
USAVisaCate = (string)jsonData.GetType().GetProperty("获签类型")!.GetValue(jsonData)!,
//GetUSAVisaDate = usaVisaDate,
USAFinger = usaFinger,
IsLose = usaLose,
USAHadArrival = usaHadArrivalD,
USAHadDays = usaHadArrivalDays,
ArmyState = JsonConvert.SerializeObject(militarys)
};
visaDetails.ClientCerts = new() {
new(){ SdId = 74,CertNo = passportNo,IDCardAddress = passportPlace },
new(){ SdId = 73,CertNo = idNo},
};
visaDetails.ClientCompany = new() { CompanyFullName = clientName, Address = clientAddr };
break;
//中文个人简历模板
case 6:
_logger.LogInformation("【签证上传文件操作信息】【中文个人简历模板】【KIMI-AI-API访问计次】{count} 次", kimiAI_API_Index);
visaDetails.ClientInfo.LastName = (string)jsonData.GetType().GetProperty("姓名(中英文拼音)")!.GetValue(jsonData)!;
visaDetails.ClientInfo.Sex = (string)jsonData.GetType().GetProperty("性别")!.GetValue(jsonData)! == "男" ? 0 : 1;
DateTime.TryParse((string)jsonData.GetType().GetProperty("出生日期")!.GetValue(jsonData)!, out DateTime birthDay11);
visaDetails.ClientInfo.BirthDay = birthDay11;
visaDetails.ClientInfo.BirthProvince = (string)jsonData.GetType().GetProperty("出生地")!.GetValue(jsonData)!;
visaDetails.ClientInfo.Address = (string)jsonData.GetType().GetProperty("家庭地址")!.GetValue(jsonData)!;
visaDetails.ClientInfo.Tel = (string)jsonData.GetType().GetProperty("家庭电话")!.GetValue(jsonData)!;
visaDetails.ClientInfo.TableOpTel = (string)jsonData.GetType().GetProperty("工作电话")!.GetValue(jsonData)!;
visaDetails.ClientInfo.Phone = (string)jsonData.GetType().GetProperty("移动电话")!.GetValue(jsonData)!;
visaDetails.ClientInfo.Email = (string)jsonData.GetType().GetProperty("电子邮件")!.GetValue(jsonData)!;
//学校信息
visaDetails.ClientSchools.Add(new()
{
School = (string)jsonData.GetType().GetProperty("教育学校名称")!.GetValue(jsonData)!,
Education = (string)jsonData.GetType().GetProperty("教育学位")!.GetValue(jsonData)!,
Subject = (string)jsonData.GetType().GetProperty("教育专业")!.GetValue(jsonData)!,
Remark = (string)jsonData.GetType().GetProperty("教育论文题目/研究重点(硕士、博士)")!.GetValue(jsonData)!,
});
//工作信息
visaDetails.ClientCompany = new()
{
CompanyFullName = (string)jsonData.GetType().GetProperty("工作经历雇主")!.GetValue(jsonData)!,
};
visaDetails.ClientInfo.Job = (string)jsonData.GetType().GetProperty("工作经历职位或头衔职责")!.GetValue(jsonData)!;
break;
default:
break;
}
//数据提交
#region 数据提交
_sqlSugar.BeginTran();
// 客户公司表
var compId = UpsertReturnId(visaDetails.ClientCompany, o => o.CompanyFullName);
if (compId < 1)
{
_sqlSugar.RollbackTran();
return Ok(JsonView(false, "公司信息更新失败!"));
}
visaDetails.ClientInfo.CrmCompanyId = compId;
// 客户资料表
var clientId = UpsertReturnId(visaDetails.ClientInfo, o => new { o.LastName, o.FirstName });
if (clientId < 1)
{
_sqlSugar.RollbackTran();
return Ok(JsonView(false, "客户信息更新失败!"));
}
for (int i = 0; i < visaDetails.ClientFamilys.Count(); i++)
{
visaDetails.ClientFamilys[i].DcId = clientId;
}
for (int i = 0; i < visaDetails.ClientCerts.Count(); i++)
{
visaDetails.ClientCerts[i].DcId = clientId;
}
for (int i = 0; i < visaDetails.ClientSchools.Count(); i++)
{
visaDetails.ClientSchools[i].DcId = clientId;
}
// 客户家庭表
foreach (var item in visaDetails.ClientFamilys)
{
var famId = UpsertReturnId(item, o => o.Name);
if (famId < 1)
{
_sqlSugar.RollbackTran();
return Ok(JsonView(false, "客户家庭信息更新失败!"));
}
}
// 客户证件表
foreach (var item in visaDetails.ClientCerts)
{
var certId = UpsertReturnId(item, o => o.CertNo);
if (certId < 1)
{
_sqlSugar.RollbackTran();
return Ok(JsonView(false, "客户证件信息更新失败!"));
}
}
// 客户学历表
foreach (var item in visaDetails.ClientSchools)
{
var schoolId = UpsertReturnId(item, o => o.School);
if (schoolId < 1)
{
_sqlSugar.RollbackTran();
return Ok(JsonView(false, "客户证件信息更新失败!"));
}
}
_sqlSugar.CommitTran();
#endregion
#endregion
return Ok(JsonView(true, jsonString));
}
#region 扩展处理
// 从 Expression> 里取出属性名
static string GetPropName(Expression> expr)
{
if (expr.Body is UnaryExpression ue) expr = Expression.Lambda>(ue.Operand, expr.Parameters);
return ((MemberExpression)expr.Body).Member.Name;
}
///
/// 5.1.4.193 可用:存在更新(非NULL非空串),不存在插入,返回主键ID
///
public int UpsertReturnId(T entity, Expression> whereExpr) where T : class, new()
{
// 1. 空字符串→NULL,让后续忽略
foreach (var pi in typeof(T).GetProperties())
if (pi.PropertyType == typeof(string) &&
pi.GetValue(entity) is string s &&
string.IsNullOrWhiteSpace(s))
pi.SetValue(entity, null);
// 2. 从表达式里拿属性名
string propName = GetPropName(whereExpr);
var propValue = typeof(T).GetProperty(propName)?.GetValue(entity);
// 3. 判断存在
bool exists = _sqlSugar.Queryable().Where(propName, propValue).Any();
// 4. 执行 Upsert
if (exists)
{
_sqlSugar.Updateable(entity)
.WhereColumns(propName) // 指定条件列
.IgnoreColumns(ignoreAllNullColumns: true) // 忽略 NULL
.ExecuteCommand();
}
else
{
_sqlSugar.Insertable(entity).ExecuteReturnIdentity();
}
// 5. 返回主键值(自增/雪花已回填)
var idProp = typeof(T).GetProperties()
.First(p => p.GetCustomAttributes()
.Any(a => a.IsPrimaryKey));
return (int)idProp.GetValue(entity)!;
}
///
/// 地址喊邮编 相关处理
///
public static (string address, string zipCode) SplitAddressZip(string? s)
{
if (string.IsNullOrWhiteSpace(s))
return ("", "");
ReadOnlySpan src = s.AsSpan();
int i = src.IndexOf("邮编".AsSpan());
if (i < 0) // 没有“邮编”字样
return (src.Trim().ToString(), "");
ReadOnlySpan addr = src[..i].TrimEnd();
ReadOnlySpan zip = src[(i + 3)..].Trim(); // 跳过“邮编:”
// 可能只有“邮编:”而没有数字
return (addr.IsEmpty ? "" : addr.ToString(),
zip.IsEmpty ? "" : zip.ToString());
}
///
/// 驾照相 关处理
///
///
///
public static (bool hasLicense, string number, string place) LicenseParser(string? raw)
{
if (string.IsNullOrWhiteSpace(raw))
return (false, "", "");
// 1. 是否持有
bool has = raw.StartsWith("是", System.StringComparison.OrdinalIgnoreCase) ||
raw.StartsWith("Y", System.StringComparison.OrdinalIgnoreCase);
// 2. 去掉前缀,按空格切
ReadOnlySpan s = raw.AsSpan();
int colon = s.IndexOf(':');
ReadOnlySpan after = colon < 0 ? s : s[(colon + 1)..];
after = after.Trim();
int space = after.IndexOf(' ');
ReadOnlySpan num = space < 0 ? after : after[..space];
ReadOnlySpan st = space < 0 ? ReadOnlySpan.Empty : after[(space + 1)..];
return (has, num.ToString().Trim(), st.ToString().Trim());
}
///
/// 美国社会安全号或者纳税ID号 相关处理
///
///
///
public static (bool hasSsnItin, string number) SsnItinParser(string? raw)
{
if (string.IsNullOrWhiteSpace(raw))
return (false, "");
ReadOnlySpan s = raw.AsSpan();
// 1. 是否持有
bool has = s.StartsWith("是", System.StringComparison.Ordinal) ||
s.StartsWith("Y", System.StringComparison.OrdinalIgnoreCase);
// 2. 取号码(去掉前缀和空格)
int colon = s.IndexOf(':');
ReadOnlySpan num = colon < 0
? ReadOnlySpan.Empty
: s[(colon + 1)..].Trim();
return (has, num.ToString());
}
///
/// 取消开始的“是:”或者“是”或者“ :”
///
///
///
public static string CleanPrefix(string? raw)
{
if (string.IsNullOrWhiteSpace(raw)) return "";
// 跳过第一个“是”或“Y”
ReadOnlySpan s = raw.AsSpan();
int start = 0;
if (s.StartsWith("是") || s.StartsWith("Y", StringComparison.OrdinalIgnoreCase))
start = 1;
// 跳过连续 : 或空格
while (start < s.Length && (s[start] == ':' || s[start] == ' '))
start++;
return s[start..].Trim().ToString();
}
///
/// 婚姻起止时间处理
///
///
///
public static (DateTime? fromDate, DateTime? toDate) WeddingParser(string? raw)
{
if (string.IsNullOrWhiteSpace(raw)) return (null, null);
Regex _clean = new(@"[\s~至]+", RegexOptions.Compiled);
// 1. 把所有“空格~至”统一成 '-'
string normalized = _clean.Replace(raw, "-");
// 2. 切两段
string[] parts = normalized.Split('-', StringSplitOptions.RemoveEmptyEntries);
if (parts.Length != 2) return (null, null);
// 3. 解析
bool ff = DateTime.TryParse(parts[0].Trim(), out var from);
bool tf = DateTime.TryParse(parts[1].Trim(), out var to);
return (tf ? from : null, tf ? to : null);
}
///
/// 出行日期和天数处理
///
///
///
public static (DateTime? travelDate, int? days) TravelParser(string? raw)
{
if (string.IsNullOrWhiteSpace(raw)) return (null, null);
// 切成两段:第一段日期,第二段天数
Regex sep = new(@"[^0-9./-]+", RegexOptions.Compiled);
string[] parts = sep.Split(raw.Trim());
if (parts.Length < 2) return (null, null);
bool okDate = DateTime.TryParse(parts[0], out DateTime date);
bool okDays = int.TryParse(parts[1], out int days) && days > 0;
return (okDate ? date : null, okDays ? days : null);
}
///
/// 是否曾抵达过美国
///
///
///
public static (bool hasTravel, string date, string days) TravelHadFlagParser(string? raw)
{
if (string.IsNullOrWhiteSpace(raw)) return (false, string.Empty, string.Empty);
Regex sep = new(@"[^0-9./-]+", RegexOptions.Compiled);
// 1. 是否持有
bool has = raw.AsSpan().TrimStart().StartsWith("是") ||
raw.AsSpan().TrimStart().StartsWith("Y", StringComparison.OrdinalIgnoreCase);
// 2. 用非数字分隔符切成三段:第一段空,第二段日期,第三段天数
string[] parts = sep.Split(raw.Trim());
if (parts.Length < 3) return (has, string.Empty, string.Empty);
return (has, parts[1], parts[2]);
}
///
/// 是否有被美国拒发签证的经历
///
///
///
public static (bool wasDenied, DateTime? date, string place, string visaType) VisaDenialParser(string? raw)
{
if (string.IsNullOrWhiteSpace(raw)) return (false, null, "", "");
bool denied = raw.AsSpan().TrimStart().StartsWith("有") ||
raw.AsSpan().TrimStart().StartsWith("Y", StringComparison.OrdinalIgnoreCase);
var parts = Regex.Split(raw.Trim(), @"[^0-9A-Za-z-]+");
if (parts.Length < 4) return (denied, null, "", "");
DateTime.TryParse(parts[1], out var dt); // ← 这里改为 DateTime
return (denied, dt, parts[2], parts[3]);
}
///
/// 在美直系、旁系 处理
///
///
///
public static (bool flag, string name, string rel, string stat) FourFieldParser(string? raw)
{
if (string.IsNullOrWhiteSpace(raw)) return (false, "", "", "");
var parts = raw.Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length < 4) return (false, "", "", "");
bool flag = parts[0] is "有" or "是" or "Y" or "Yes";
string name = parts[1];
string rel = parts[2];
string stat = parts[3];
return (flag, name, rel, stat);
}
///
/// 服役时间处理
///
///
///
public static (bool hasService, string branch, string rank, string specialty, (DateTime? start, DateTime? end) period) MilitaryParser(string? raw)
{
const string fmt = "yyyy年MM月dd日";
if (string.IsNullOrWhiteSpace(raw))
return (false, "", "", "", (null, null));
var parts = raw.Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length < 5) return (false, "", "", "", (null, null));
bool has = parts[0] is "是" or "Y" or "Yes";
string branch = parts[1];
string rank = parts[2];
string specialty = parts[3];
// 拼回时间字符串
string periodRaw = string.Join(" ", parts[4..]);
var span = periodRaw.AsSpan();
int zhi = span.IndexOf("至");
if (zhi < 0) return (has, branch, rank, specialty, (null, null));
var startStr = span.Slice(0, zhi).Trim();
var endStr = span.Slice(zhi + 1).Trim();
bool okStart = DateTime.TryParseExact(startStr.ToString(), fmt, null, DateTimeStyles.None, out var start);
bool okEnd = DateTime.TryParseExact(endStr.ToString(), fmt, null, DateTimeStyles.None, out var end);
return (has, branch, rank, specialty, (okStart ? start : null, okEnd ? end : null));
}
///
/// 申请人父母信息
///
///
///
public static (string fatherName, DateTime? fatherDob, string motherName, DateTime? motherDob) ParentParser(string? raw)
{
const string fmt = "yyyy年MM月dd日";
if (string.IsNullOrWhiteSpace(raw)) return ("", null, "", null);
// 按空格切,去掉空元素
var parts = raw.Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length < 4) return ("", null, "", null);
// 父亲
string fName = parts[0];
DateTime.TryParseExact(parts[1], fmt, null, DateTimeStyles.None, out var fDob);
// 母亲
string mName = parts[2];
DateTime.TryParseExact(parts[3], fmt, null, DateTimeStyles.None, out var mDob);
return (fName, fDob, mName, mDob);
}
public class VisaDetailsView
{
///
/// 客户资料表
///
public Crm_DeleClient ClientInfo { get; set; }
///
/// 客户家庭表
///
public List ClientFamilys { get; set; }
///
/// 客户公司表
///
public Crm_CustomerCompany ClientCompany { get; set; }
///
/// 客户证件表
///
public List ClientCerts { get; set; }
///
/// 客户学历表
///
public List ClientSchools { get; set; }
}
private int GetSuccessCount(List results)
{
var count = 0;
foreach (var result in results)
{
if (result.Success) count++;
}
return count;
}
#endregion
///
/// 根据团组Id获取签证客户信息List
///
/// 请求dto
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GetCrmByGroupId(ClientByGroupIdDto dto)
{
var groupData = await _groupRepository.GetCrmByGroupId(dto);
if (groupData.Code != 0)
{
return Ok(JsonView(false, groupData.Msg));
}
return Ok(JsonView(groupData.Data));
}
///
/// IOS获取团组签证拍照上传进度01(团组列表)
///
/// 请求dto
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task PostIOSVisaProgress(IOS_VisaDto dto)
{
if (dto == null)
{
return Ok(JsonView(false, "参数为空"));
}
DelegationVisaViewList visaList = _delegationVisaRep.GetDelegationList(dto);
return Ok(JsonView(visaList));
}
///
/// IOS获取团组签证拍照上传进度02(团组签证详情\人员列表\国家)
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task PostIOSVisaProgressContent(IOS_VisaCustomerListDto dto)
{
if (dto == null)
{
return Ok(JsonView(false, "请求错误:"));
}
List list = _delegationVisaRep.GetDelegationProgressList(dto.diId);
return Ok(JsonView(list));
}
///
/// IOS获取团组签证拍照上传进度03(相册)
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task PostIOSVisaProgressImageList(IOS_VisaImageListDto dto)
{
if (dto == null)
{
return Ok(JsonView(false, "请求错误:"));
}
List list = _delegationVisaRep.GetVisaProgressImageList(dto.visaProgressCustomerId, dto.picType);
string url = AppSettingsHelper.Get("VisaProgressImageBaseUrl") + AppSettingsHelper.Get("VisaProgressImageFtpPath");
list.ForEach(s => s.url = url);
return Ok(JsonView(list));
}
///
/// IOS获取团组签证拍照上传进度04(图片上传)
///
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task PostIOSVisaProgressUploadImage(IOS_VisaUploadImageDto dto)
{
//string result = decodeBase64ToImage(dto.base64DataURL, dto.imageName);
//if (!string.IsNullOrEmpty(result))
//{
//}
//else {
// return Ok(JsonView(false, "上传失败"));
//}
var dt1970 = new DateTime(1970, 1, 1, 0, 0, 0, 0);
int sucNum = 0;
try
{
foreach (var item in dto.base64DataList)
{
string imageName = dto.imageName + ((DateTime.Now.Ticks - dt1970.Ticks) / 10000).ToString();
string result = DecodeBase64ToImage(item, imageName);
if (!string.IsNullOrEmpty(result))
{
var pic = new Grp_VisaProgressCustomerPicture
{
CreateUserId = dto.CreateUserId,
PicName = imageName,
PicPath = result,
VisaProgressCustomerId = dto.visaProgressCustomerId
};
int insertResult = await _delegationVisaRep.AddAsync(pic);
if (insertResult > 0)
{
sucNum++;
}
}
}
}
catch (Exception ex)
{
return Ok(JsonView(false, ex.Message));
}
string msg = string.Format(@"成功上传{0}张", sucNum);
return Ok(JsonView(true, msg));
}
private string DecodeBase64ToImage(string base64DataURL, string imgName)
{
string filename = "";//声明一个string类型的相对路径
String base64 = base64DataURL.Substring(base64DataURL.IndexOf(",") + 1); //将‘,’以前的多余字符串删除
System.Drawing.Bitmap bitmap = null;//定义一个Bitmap对象,接收转换完成的图片
try//会有异常抛出,try,catch一下
{
byte[] arr = Convert.FromBase64String(base64);//将纯净资源Base64转换成等效的8位无符号整形数组
var ms = new System.IO.MemoryStream(arr);//转换成无法调整大小的MemoryStream对象
bitmap = new System.Drawing.Bitmap(ms);//将MemoryStream对象转换成Bitmap对象
var fileDir = AppSettingsHelper.Get("VisaProgressImageBasePath");
//文件名称
filename = "VisaProgress_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "_" + imgName + ".jpeg";//所要保存的相对路径及名字
//上传的文件的路径
string filePath = "";
if (!Directory.Exists(fileDir))
{
Directory.CreateDirectory(fileDir);
}
//上传的文件的路径
filePath = fileDir + filename;
//string url = HttpRuntime.AppDomainAppPath.ToString();
//string tmpRootDir = System.Web.HttpContext.Current.Server.MapPath(System.Web.HttpContext.Current.Request.ApplicationPath.ToString()); //获取程序根目录
//string imagesurl2 = tmpRootDir + filename; //转换成绝对路径
bitmap.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg);//保存到服务器路径
//bitmap.Save(filePath + ".bmp", System.Drawing.Imaging.ImageFormat.Bmp);
//bitmap.Save(filePath + ".gif", System.Drawing.Imaging.ImageFormat.Gif);
//bitmap.Save(filePath, System.Drawing.Imaging.ImageFormat.Png);
ms.Close();//关闭当前流,并释放所有与之关联的资源
bitmap.Dispose();
}
catch (Exception e)
{
string massage = e.Message;
Logs("IOS图片上传Error:" + massage);
//filename = e.Message;
}
return filename;//返回相对路径
}
///
/// IOS获取团组签证拍照上传进度05(修改签证状态/通知)
///
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task PostIOSVisaProgressChangeStatus(IOS_VisaChangeStatusDto dto)
{
if (dto == null)
{
return Ok(JsonView(false, "请求错误:"));
}
string msg = "参数错误";
if (dto.diId > 0 && dto.visaStatus > 0 && dto.visaStatus < 4)
{
try
{
//_delegationVisaRep.BeginTran();
var updCount = await _delegationVisaRep._sqlSugar.Updateable()
.SetColumns(it => it.WorkStatus == dto.visaStatus)
.Where(s => s.Id == dto.visaProgressCustomerId)
.ExecuteCommandAsync();
if (updCount > 0 && dto.publishCode == 1)
{
_delegationVisaRep.ChangeDataBase(DBEnum.OA2014DB); //切换到新OA后删除
string sqlDelegation = string.Format(@" Select * From DelegationInfo With(Nolock) Where Id = {0} ", dto.diId);
OA2021_DelegationInfo groupData = _sqlSugar.SqlQueryable(sqlDelegation).First();
//GroupInfoDto grpDto = new GroupInfoDto() { Id = dto.diId };
//var groupData = await _groupRepository.GetGroupInfo(grpDto);
_delegationVisaRep.ChangeDataBase(DBEnum.OA2023DB); //切换到新OA后删除
if (groupData == null)
{
_delegationVisaRep.RollbackTran();
}
string title = string.Format(@"[签证进度更新]");
string content = string.Format(@"测试文本");
bool rst = await _message.AddMsg(new MessageDto()
{
Type = MessageTypeEnum.GroupVisaProgressUpdate,
IssuerId = dto.publisher,
Title = title,
Content = content,
ReleaseTime = DateTime.Now,
UIdList = new List {
234
}
});
if (rst)
{
return Ok(JsonView(true, "发送通知成功"));
}
}
//_delegationVisaRep.CommitTran();
}
catch (Exception)
{
//_delegationVisaRep.RollbackTran();
}
}
return Ok(JsonView(true, msg));
}
#endregion
#endregion
#region 团组任务分配
///
/// 团组任务分配初始化
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GetTaskAssignmen()
{
var groupData = await _taskAssignmentRep.GetTaskAssignmen();
if (groupData.Code != 0)
{
return Ok(JsonView(false, groupData.Msg));
}
return Ok(JsonView(true, groupData.Msg, groupData.Data));
}
///
/// 团组任务分配查询
///
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task TaskAssignmenQuery(TaskAssignmenQueryDto dto)
{
var groupData = await _taskAssignmentRep.TaskAssignmenQuery(dto);
if (groupData.Code != 0)
{
return Ok(JsonView(false, groupData.Msg));
}
return Ok(JsonView(true, groupData.Msg, groupData.Data));
}
///
/// 团组任务分配操作
///
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task GetTaskAssignmenOp(TaskAssignmenDto dto)
{
Result groupData = await _taskAssignmentRep.GetTaskAssignmenOp(dto);
if (groupData.Code != 0)
{
return Ok(JsonView(false, groupData.Msg));
}
return Ok(JsonView(true, groupData.Msg, groupData.Data));
}
///
/// 团组任务分配
/// 批量分配
/// 查询团组
///
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task TaskAllocationGroupSelect(TaskAllocationGroupSelectDto dto)
{
//参数验证
if (dto.PortType < 1 || dto.PortType > 3) return Ok(JsonView(false, MsgTips.Port));
if (!DateTime.TryParse(dto.VisitBeginDt, out _) || !DateTime.TryParse(dto.VisitEndDt, out _))
return Ok(JsonView(false, "团组出访开始/结束日期格式不正确!"));
return Ok(await _taskAssignmentRep.TaskAllocationGroupSelect(dto));
}
///
/// 团组任务分配
/// 批量分配
///
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task TaskAllocationBulkAdd(TaskAllocationBulkAddDto dto)
{
//参数验证
if (dto.UserIds.Length < 1) return Ok(JsonView(false, $"请选择分配人员!"));
if (dto.PermissionTypeIds.Length < 1) return Ok(JsonView(false, $"请选择分配类型!"));
if (dto.GroupIds.Length < 1) return Ok(JsonView(false, "请选择分配团组Id"));
if (dto.CurrUserId < 1) return Ok(JsonView(false, "请传入有效的CurrUserId数组参数"));
return Ok(await _taskAssignmentRep.TaskAllocationBulkAdd(dto));
}
#endregion
#region 团组费用审核
///
/// 费用审核
/// 团组列表 Page
///
/// 团组列表请求dto
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task PostExpenseAuditGroupPageItems(ExpenseAuditGroupPageItemsDto _dto)
{
#region 参数验证
if (_dto.UserId < 1) return Ok(JsonView(false, "员工Id为空"));
if (_dto.PageId < 1) return Ok(JsonView(false, "页面Id为空"));
#region 页面操作权限验证
var pageFunAuthView = await GeneralMethod.PostUserPageFuncDatas(_dto.UserId, _dto.PageId);
if (pageFunAuthView.CheckAuth == 0) return Ok(JsonView(false, "您没有查看权限"));
#endregion
#endregion
if (_dto.PortType == 1 || _dto.PortType == 2 || _dto.PortType == 2) // web/Android/IOS
{
string sqlWhere = string.Empty;
if (_dto.IsSure == 0) //未完成
{
sqlWhere += string.Format(@" And IsSure = 0");
}
else if (_dto.IsSure == 1) //已完成
{
sqlWhere += string.Format(@" And IsSure = 1");
}
if (!string.IsNullOrEmpty(_dto.SearchCriteria))
{
string tj = _dto.SearchCriteria;
sqlWhere += string.Format(@"And (ssd.Name Like '%{0}%' Or TeamName Like '%{1}%' Or ClientName Like '%{2}%' Or ClientName Like '%{3}%' Or su.CnName Like '%{4}%')",
tj, tj, tj, tj, tj);
}
string sql = string.Format(@"Select Row_Number,Id,SalesQuoteNo,TourCode,TeamTypeId, TeamType,
TeamName,ClientName,ClientUnit, TeamLevId,TeamLev,VisitDate,
VisitDays,VisitPNumber,JietuanOperator,IsSure,CreateTime
From (
Select row_number() over(order by gdi.VisitDate Desc) as Row_Number,
gdi.Id,SalesQuoteNo,TourCode,ssd1.Id TeamLevId,ssd1.Name TeamLev,TeamName,
ClientName,ClientUnit,ssd.Id TeamTypeId, ssd.Name TeamType,VisitDate,
VisitDays,VisitPNumber,su.CnName JietuanOperator,IsSure,gdi.CreateTime
From Grp_DelegationInfo gdi
Inner Join Sys_SetData ssd On gdi.TeamDid = ssd.Id
Inner Join Sys_SetData ssd1 On gdi.TeamLevSId = ssd1.Id
Left Join Sys_Users su On gdi.JietuanOperator = su.Id
Where gdi.IsDel = 0 {0}
) temp ", sqlWhere);
RefAsync total = 0;//REF和OUT不支持异步,想要真的异步这是最优解
var _DelegationList = await _sqlSugar.SqlQueryable(sql).ToPageListAsync(_dto.PageIndex, _dto.PageSize, total);//ToPageAsync
var _view = new
{
PageFuncAuth = pageFunAuthView,
Data = _DelegationList
};
return Ok(JsonView(true, "查询成功!", _view, total));
}
else
{
return Ok(JsonView(false, "查询失败"));
}
}
///
/// 获取团组费用审核
///
///
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task PostSearchGrpCreditCardPayment(Search_GrpCreditCardPaymentDto _dto)
{
try
{
#region 参数验证
if (_dto.UserId < 1) return Ok(JsonView(false, "员工Id为空"));
if (_dto.PageId < 1) return Ok(JsonView(false, "页面Id为空"));
if (_dto.DiId < 1) return Ok(JsonView(false, "团组Id为空"));
#region 页面操作权限验证
var pageFunAuthView = await GeneralMethod.PostUserPageFuncDatas(_dto.UserId, _dto.PageId);
if (pageFunAuthView.CheckAuth == 0) return Ok(JsonView(false, "您没有查看权限"));
#endregion
#endregion
var _view = new Grp_CreditCardPaymentView();
var clientNameList = GetSimplClientList(_dto.DiId);
#region 费用清单
var exp = Expressionable.Create();
exp.AndIF(_dto.AuditStatus != -1, it => it.IsAuditGM == _dto.AuditStatus);
exp.AndIF(_dto.Label != -1, it => it.CTable == _dto.Label);
var entityList = _groupRepository.Query(s => s.DIId == _dto.DiId && s.IsDel == 0 && s.CreateUserId > 0).Where(exp.ToExpression()).ToList();
var detailList = new List();
var ccpCurrencyPrices = new List();
/*
* 76://酒店预订
*/
var _HotelReservations = await _groupRepository.Query(s => s.DiId == _dto.DiId && s.IsDel == 0).ToListAsync();
var _HotelReservationsContents = await _groupRepository.Query(s => s.DiId == _dto.DiId && s.IsDel == 0).ToListAsync();
/*
* 79://车/导游地接
*/
var _CarTouristGuideGroundReservations = await _groupRepository.Query(s => s.DiId == _dto.DiId && s.IsDel == 0).ToListAsync();
var _CarTouristGuideGroundReservationsContent = await _groupRepository.Query(s => s.DiId == _dto.DiId && s.IsDel == 0).ToListAsync();
/*
* 80: //签证
*/
var _VisaInfos = await _groupRepository.Query(s => s.DIId == _dto.DiId && s.IsDel == 0).ToListAsync();
/*
*81: //邀请/公务活动
*/
var _InvitationOfficialActivities = await _groupRepository.Query(s => s.DiId == _dto.DiId && s.IsDel == 0).ToListAsync();
/*
* 82: //团组客户保险
*/
var _Customers = await _groupRepository.Query(s => s.DiId == _dto.DiId && s.IsDel == 0).ToListAsync();
/*
* Lable = 85 机票预订
*/
var p_AirTicketReservations = await _groupRepository.Query(s => s.DIId == _dto.DiId && s.IsDel == 0).ToListAsync();
/*
* 85 机票预定
*/
var _AirTicketReservations = await _groupRepository.Query(s => s.DIId == _dto.DiId && s.IsDel == 0).ToListAsync();
/*
* 98 其他款项
*/
var _DecreasePayments = await _groupRepository.Query(s => s.DiId == _dto.DiId && s.IsDel == 0).ToListAsync();
/*
* 285:收款退还
*/
var _PaymentRefundAndOtherMoneys = await _groupRepository.Query(s => s.DiId == _dto.DiId && s.IsDel == 0).ToListAsync();
/*
* 1015: //超支费用
*/
var _GroupExtraCosts = await _groupRepository.Query(s => s.DiId == _dto.DiId && s.IsDel == 0).ToListAsync();
var initDatas = await _groupRepository.Query(s => s.IsDel == 0).ToListAsync();
/*
* 币种信息
*/
var currencyItems = initDatas.Where(s => s.STid == 66).ToList();
/*
* 车/导游地接 费用类型
*/
var carFeeTypeItems = initDatas.Where(s => s.STid == 17).ToList();
/*
* 车/导游地接 费用类型
*/
var carFeeItems = initDatas.Where(s => s.STid == 83).ToList();
var cityData = await _groupRepository.Query(s => s.IsDel == 0).ToListAsync();
/*
* 用户信息
*/
var userItems = await _groupRepository._sqlSugar.Queryable().ToListAsync();
/*
* 费用模块
*/
var sdPriceName = initDatas.Where(s => s.Id == _dto.Label).First();
string priceModule = string.Empty;
if (sdPriceName != null)
{
priceModule = sdPriceName.Name;
}
/*
* 成本信息
*/
var groupCost = _groupRepository.Query(s => s.DiId == _dto.DiId && s.IsDel == 0).First();
decimal _groupRate = 0.0000M;
string _groupCurrencyCode = "-";
if (groupCost != null)
{
_groupRate = groupCost.Rate;
if (int.TryParse(groupCost.Currency, out int _currency))
{
_groupCurrencyCode = currencyItems.Find(it => it.Id == _currency)?.Name ?? "-";
}
else _groupCurrencyCode = groupCost.Currency;
}
string costContentSql = $"Select * From Grp_GroupCost";
var groupCostDetails = _sqlSugar.SqlQueryable(costContentSql).Where(x => x.IsDel == 0 && x.Diid == _dto.DiId).ToList();
//处理日期为空的天数
for (int i = 0; i < groupCostDetails.Count; i++)
if (i != 0)
if (string.IsNullOrEmpty(groupCostDetails[i].Date))
groupCostDetails[i].Date = groupCostDetails[i - 1].Date;
/*
* 处理详情数据
*/
foreach (var entity in entityList)
{
var _detail = new Grp_CreditCardPaymentDetailView
{
Id = entity.Id,
PriceName = priceModule,
PayType = initDatas.Find(it => it.Id == entity.PayDId)?.Name ?? "-"
};
if (_detail.PayType.Equals("现金")) _detail.CardType = "-";
else _detail.CardType = initDatas.Find(it => it.Id == entity.CTDId)?.Name ?? "-";
//处理金额
if (entity.CTable == 1015)
{
var czInfo = _GroupExtraCosts.Find(x => entity.CId == x.Id);
if (czInfo != null)
{
entity.PayMoney = czInfo.Price * czInfo.PriceCount;
entity.RMBPrice = czInfo.Price * czInfo.PriceCount * entity.DayRate;
}
}
/*
* 应付款金额
*/
var sdPaymentCurrency_WaitPay = currencyItems.Where(s => s.Id == entity.PaymentCurrency).FirstOrDefault();
string PaymentCurrency_WaitPay = "Unknown";
string hotelCurrncyCode = "Unknown";
string hotelCurrncyName = "Unknown";
if (sdPaymentCurrency_WaitPay != null)
{
PaymentCurrency_WaitPay = sdPaymentCurrency_WaitPay.Name;
hotelCurrncyCode = sdPaymentCurrency_WaitPay.Name;
hotelCurrncyName = sdPaymentCurrency_WaitPay.Remark;
if (hotelCurrncyCode.Equals("CNY"))
{
entity.DayRate = 1.0000M;
}
}
_detail.WaitPay = entity.PayMoney.ConvertToDecimal1().ToString("#0.00") + " " + PaymentCurrency_WaitPay;
/*
* 此次付款金额
*/
decimal CurrPayStr = 0.00M,
OriginalCurrPay = 0.00M;
if (entity.PayPercentage == 0)
{
if (entity.PayThenMoney != 0)
CurrPayStr = (entity.PayThenMoney * entity.DayRate).ConvertToDecimal1();
}
else
{
if (entity.PayMoney != 0)
{
CurrPayStr = (entity.PayMoney * entity.PayPercentage / 100 * entity.DayRate).ConvertToDecimal1();
}
}
//if (_dto.Label == 79)
//{
// string original = string.Empty;
// if (hotelCurrncyCode.Equals("CNY"))
// {
// OriginalCurrPay = CurrPayStr;
// _detail.CurrPay = CurrPayStr.ToString("#0.00") + " CNY";
// }
// else
// {
// OriginalCurrPay = ((entity.PayMoney / 100) * entity.PayPercentage).ConvertToDecimal1();
// //760 EUR(7600.00 CNY)
// _detail.CurrPay = $"{OriginalCurrPay.ToString("#0.00")} {hotelCurrncyCode}({CurrPayStr.ToString("#0.00")} CNY)";
// }
//}
//else _detail.CurrPay = CurrPayStr.ToString("#0.00") + " CNY";
string original = string.Empty;
if (hotelCurrncyCode.Equals("CNY"))
{
OriginalCurrPay = CurrPayStr;
_detail.CurrPay = CurrPayStr.ToString("#0.00") + " CNY";
}
else
{
OriginalCurrPay = ((entity.PayMoney / 100) * entity.PayPercentage).ConvertToDecimal1();
//760 EUR(7600.00 CNY)
_detail.CurrPay = $"{OriginalCurrPay:#0.00} {hotelCurrncyCode}({CurrPayStr:#0.00} CNY)";
}
/*
* 剩余尾款
*/
decimal BalanceStr = 0;
if (CurrPayStr != 0)
{
if (entity.PayMoney - (CurrPayStr / entity.DayRate) < 0.01M)
BalanceStr = 0;
else
BalanceStr = (entity.PayMoney - CurrPayStr / entity.DayRate).ConvertToDecimal1();
}
_detail.Balance = BalanceStr.ToString("#0.00") + " " + PaymentCurrency_WaitPay;
/*
* Bus名称
*/
_detail.BusName = "待增加";
/*
*费用所属
*/
switch (entity.CTable)
{
case 76://酒店预订
Grp_HotelReservations hotelReservations = _HotelReservations.Where(s => s.Id == entity.CId).FirstOrDefault();
if (hotelReservations != null)
{
DateTime checkIn = Convert.ToDateTime(hotelReservations.CheckInDate),
checkOut = Convert.ToDateTime(hotelReservations.CheckOutDate);
int hotel_days = (int)(checkOut - checkIn).TotalDays;
string roomFeeStr = "", roomFeestr1 = "";
//是否比较房型价格
//bool __isSingle = false, __isDouble = false, __isSuite = false, __isOther = false;
//roomFeeStr += $"
";
roomFeeStr += $"
";
var roomTotal = 0.00M;
if (hotelReservations.SingleRoomPrice > 0)
{
var fee = hotelReservations.SingleRoomPrice * hotelReservations.SingleRoomCount * hotel_days;
roomFeestr1 += $"单间:{hotelReservations.SingleRoomPrice:#0.00} * {hotelReservations.SingleRoomCount}间 * {hotel_days}晚 = {fee:#0.00}
";
//__isSingle = true;
roomTotal += fee;
}
if (hotelReservations.DoubleRoomPrice > 0)
{
var fee = hotelReservations.DoubleRoomPrice * hotelReservations.DoubleRoomCount * hotel_days;
roomFeestr1 += $"双人间:{hotelReservations.DoubleRoomPrice:#0.00} * {hotelReservations.DoubleRoomCount}间 * {hotel_days}晚 = {fee:#0.00}
";
// __isDouble = true;
roomTotal += fee;
}
if (hotelReservations.SuiteRoomPrice > 0)
{
var fee = hotelReservations.SuiteRoomPrice * hotelReservations.SuiteRoomCount * hotel_days;
roomFeestr1 += $"套房:{hotelReservations.SuiteRoomPrice:#0.00} * {hotelReservations.SuiteRoomCount}间 * {hotel_days}晚 = {fee:#0.00}
";
//__isSuite = true;
roomTotal += fee;
}
if (hotelReservations.OtherRoomPrice > 0)
{
var fee = hotelReservations.OtherRoomPrice * hotelReservations.OtherRoomCount * hotel_days;
roomFeestr1 += $"其他:{hotelReservations.OtherRoomPrice:#0.00} * {hotelReservations.OtherRoomCount}间 * {hotel_days}晚 = {fee:#0.00}
";
//__isOther = true;
roomTotal += fee;
}
if (roomFeestr1.Length > 0) roomFeeStr += roomFeestr1 + $"房费总金额:{roomTotal:#0.00}";
else roomFeeStr += " 0.00 * 0";
decimal governmentRentFee = 0.00M, cityTaxFee = 0.00M, breakfastFee = 0.00M, roomFee = 0.00M;
string governmentRentBool = "否", cityTaxBool = "否", breakfastBool = "否", roomBool = "否";
string governmentRentCode = "", governmentRentName = "", cityTaxCode = "", cityTaxName = "", breakfastCode = "", breakfastName = "", roomCode = "", roomName = "";
var _HotelReservationsContents1 = _HotelReservationsContents.Where(it => it.HrId == hotelReservations.Id).ToList();
/*
* 费用类型
* 1:房费
* 2:早餐
* 3:地税
* 4:城市税
*
*/
//地税
var governmentRentData = _HotelReservationsContents1.Find(it => it.PriceType == 3);
if (governmentRentData != null)
{
governmentRentBool = governmentRentData.IsOppay == 1 ? "是" : "否";
governmentRentFee = governmentRentData.Price;
var governmentRentCurrData = currencyItems.Find(s => s.Id == governmentRentData.Currency);
if (governmentRentCurrData != null)
{
governmentRentCode = governmentRentCurrData.Name;
governmentRentName = $"({governmentRentCurrData.Remark})";
}
}
//城市税
var cityTaxData = _HotelReservationsContents1.Find(it => it.PriceType == 4);
if (cityTaxData != null)
{
cityTaxBool = cityTaxData.IsOppay == 1 ? "是" : "否";
cityTaxFee = cityTaxData.Price;
var cityTaxCurrData = currencyItems.Find(s => s.Id == cityTaxData.Currency);
if (cityTaxCurrData != null)
{
cityTaxCode = cityTaxCurrData.Name;
cityTaxName = $"({cityTaxCurrData.Remark})";
}
}
//酒店早餐
var breakfastData = _HotelReservationsContents1.Find(it => it.PriceType == 2);
if (breakfastData != null)
{
breakfastBool = breakfastData.IsOppay == 1 ? "是" : "否";
breakfastFee = breakfastData.Price;
var breakfastCurrData = currencyItems.Find(s => s.Id == breakfastData.Currency);
if (breakfastCurrData != null)
{
breakfastCode = breakfastCurrData.Name;
breakfastName = $"({breakfastCurrData.Remark})";
}
}
//房间费用
var roomData = _HotelReservationsContents1.Find(it => it.PriceType == 1);
if (roomData != null)
{
_detail.PayType = initDatas.Find(it => it.Id == roomData.PayDId)?.Name ?? "-";
if (_detail.PayType.Equals("现金")) _detail.CardType = "-";
else _detail.CardType = initDatas.Find(it => it.Id == roomData.CTDId)?.Name ?? "-";
roomBool = roomData.IsOppay == 1 ? "是" : "否";
roomFee = roomData.Price;
var roomCurrData = currencyItems.Find(s => s.Id == roomData.Currency);
if (roomCurrData != null)
{
roomCode = roomCurrData.Name;
roomName = $"({roomCurrData.Remark})";
}
}
string hotelCostTitalStr = "成本信息
";
string hotelCostStr = "";
decimal hotelCsotTotal = 0.00M;
if (groupCost != null)
{
if (int.TryParse(groupCost.Currency, out int currencyId)) groupCost.Currency = currencyItems.Find(s => s.Id == currencyId)?.Name ?? "-";
hotelCostStr += $"{groupCost.Currency}(汇率:{groupCost.Rate:#0.0000})
";
}
if (checkOut > checkIn) checkOut = checkOut.AddDays(-1);
var hotelCostDetails = groupCostDetails.Where(x => Convert.ToDateTime(x.Date) >= checkIn && Convert.ToDateTime(x.Date) <= checkOut).ToList();
string hotelCost_day = "";
var hotelCostDetails1 = hotelCostDetails.GroupBy(x => x.Date);
foreach (var item in hotelCostDetails1)
{
hotelCsotTotal += item.Sum(x => x.HotelSingleRoomFee) + item.Sum(x => x.HotelDoubleRoomFee) + item.Sum(x => x.HotelSuiteRoomFee) + item.Sum(x => x.HotelSuiteFee);
hotelCost_day += @$"{item.First()?.Date ?? "-"}";
if (item.Sum(x => x.HotelSingleRoomFee) != 0) hotelCost_day += @$" 单间:{item.Sum(x => x.HotelSingleRoomFee):#0.00}";
//else { if (__isSingle) hotelCost_day += @$" 单间:0.00"; }
if (item.Sum(x => x.HotelDoubleRoomFee) != 0) hotelCost_day += @$" 双人间:{item.Sum(x => x.HotelDoubleRoomFee):#0.00}";
//else { if (__isDouble) hotelCost_day += @$" 双人间:0.00"; }
if (item.Sum(x => x.HotelSuiteRoomFee) != 0) hotelCost_day += @$" 小套房/豪华套房:{item.Sum(x => x.HotelSuiteRoomFee):#0.00}";
//else { if (__isSuite) hotelCost_day += @$" 小套房/豪华套房:0.00"; }
if (item.Sum(x => x.HotelSuiteFee) != 0) hotelCost_day += @$" 套房:{item.Sum(x => x.HotelSuiteFee):#0.00}";
//else { if (__isOther) hotelCost_day += @$" 套房:0.00"; }
hotelCost_day += @$"
";
}
string hotelBreakfastStr = "", hotelGovernmentRentStr = "", hotelCityTaxStr = "";
if (breakfastFee > 0) hotelBreakfastStr = $"酒店早餐: {breakfastFee:#0.00} {breakfastCode} {breakfastName} 当时汇率 {breakfastData?.Rate:#0.0000}
是否由地接或其他人代付:{breakfastBool}
";
if (governmentRentFee > 0) hotelGovernmentRentStr = $"地税: {governmentRentFee:#0.00} {governmentRentCode} {governmentRentName} 当时汇率 {governmentRentData?.Rate:#0.0000}
是否由地接或其他人代付:{governmentRentBool}
";
if (cityTaxFee > 0) hotelCityTaxStr = $"城市税: {cityTaxFee:#0.00} {cityTaxCode} {cityTaxName} 当时汇率 {cityTaxData?.Rate:#0.0000)}
是否由地接或其他人代付:{cityTaxBool}
";
string hotelCostTotalStr = "";// $" 成本合计:{hotelCsotTotal.ToString("#0.00")}
";
_detail.PriceMsgContent = $"{hotelCostTitalStr}{hotelCostStr}{hotelCostTotalStr}{hotelCost_day}
" +
$"{hotelReservations.HotelName} [{hotelReservations.CheckInDate} - {hotelReservations.CheckOutDate}]
" +
$"酒店费用总额:{_detail.WaitPay} ({hotelCurrncyName})
" +
$"房间说明: {hotelReservations.Remark}
" +
$"房间费用: {roomCode} {roomName} 当时汇率:{roomData?.Rate.ToString("#0.0000")}{roomFeeStr}
是否由地接或其他人代付:{roomBool}
" +
$"{hotelBreakfastStr}" +
$"{hotelGovernmentRentStr}" +
$"{hotelCityTaxStr}";
_detail.PriceNameContent = hotelReservations.HotelName;
}
break;
case 79://车/导游地接
Grp_CarTouristGuideGroundReservations touristGuideGroundReservations = _CarTouristGuideGroundReservations.Where(s => s.Id == entity.CId).FirstOrDefault();
if (touristGuideGroundReservations != null)
{
if (!string.IsNullOrEmpty(touristGuideGroundReservations.BusName))
{
_detail.BusName = touristGuideGroundReservations.BusName;
}
_detail.PriceNameContent = touristGuideGroundReservations.PriceName;
//bool isInt = int.TryParse(touristGuideGroundReservations.Area, out int cityId);
//if (isInt)
//{
// var cityInfo = cityData.Find(it => it.Id == cityId);
// if (cityInfo != null)
// {
// string nameContent = $@"{cityInfo.Country}-{cityInfo.City}";
// var carFeeItem = carFeeItems.Find(it => it.Id == touristGuideGroundReservations.PriceType);
// if (carFeeItem != null)
// {
// nameContent += $@"({carFeeItem.Name})";
// }
// _detail.PriceNameContent = nameContent;
// }
//}
//else
//{
// _detail.PriceNameContent = touristGuideGroundReservations.Area;
//}
var touristGuideGroundReservationsContents =
_CarTouristGuideGroundReservationsContent.Where(s => s.CTGGRId == touristGuideGroundReservations.Id && s.IsDel == 0 && s.Price != 0).ToList();
var opContent_sb = new StringBuilder();
string contetTitle = $"{touristGuideGroundReservations.PriceName}({touristGuideGroundReservations.ServiceStartTime} - {touristGuideGroundReservations.ServiceEndTime})
";
opContent_sb.AppendLine(contetTitle);
foreach (var item in touristGuideGroundReservationsContents)
{
string typeName = "Unknown";
string carCurrencyCode = "Unknown";
string carCurrencyName = "Unknown";
var carTypeData = carFeeTypeItems.Where(s => s.Id == item.SId && s.IsDel == 0).FirstOrDefault();
if (carTypeData != null) typeName = carTypeData.Name;
var currencyData = currencyItems.Where(s => s.Id == item.Currency && s.IsDel == 0).FirstOrDefault();
if (currencyData != null)
{
carCurrencyCode = currencyData.Name;
carCurrencyName = currencyData.Remark;
}
//op、成本 币种是否一致 (币种一致只比较金额:2025-04-18)
bool IsCurrencyAgreement = false;
if (carCurrencyCode.Equals(_groupCurrencyCode)) IsCurrencyAgreement = true;
string opCostStr = string.Empty;
decimal opCostTypePrice = 0.00M;
#region 处理成本各项费用
var opDate = item.DatePrice?.ToString("yyyy-MM-dd");
var opCost = groupCostDetails.Where(x => x.Date.Equals(opDate)).ToList();
decimal aduitOPFeeCNY = 0.00M, //费用审核 op费用
costOPFeeCNY = 0.00M, //团组成本 op费用
opPayPercentage = entity.PayPercentage == 0.00M ? 1.00M : entity.PayPercentage / 100M; //费用审核 op付款百分比
if (opCost.Count > 0)
{
switch (item.SId)
{
case 91: opCostTypePrice = opCost.Sum(x => x.CarFee); break; //91车费
//case 982: opCostTypePrice = opCost.Sum(x => x.CarFee); break; //982 车超时费 -- 暂无
case 92: opCostTypePrice = opCost.Sum(x => x.GuideFee); break; //92 导游费
case 94: opCostTypePrice = opCost.Sum(x => x.GuideScenicFee); break; //94 导游景点费
case 95: opCostTypePrice = opCost.Sum(x => x.GuideTipFee); break; //95 导游小费
case 983: opCostTypePrice = opCost.Sum(x => x.GuideMealFee); break; //983 导游餐补
case 984: opCostTypePrice = opCost.Sum(x => x.GuideMealFee); break; //984 导游房补
case 985: opCostTypePrice = opCost.Sum(x => x.GuideRoomFee); break; //985 导游交通
//case 96: opCostTypePrice = opCost.Sum(x => x.CarFee); break; //96 接送机费 -- 暂无
//case 97: opCostTypePrice = opCost.Sum(x => x.CarFee); break; //97 其他费用 -- 暂无
case 979: opCostTypePrice = opCost.Sum(x => x.DriverFee); break; //979 司机工资
case 980: opCostTypePrice = opCost.Sum(x => x.DriverTipFee); break; //980 司机小费
case 981: opCostTypePrice = opCost.Sum(x => x.DriverMealFee); break; //981 司机餐补
case 988: opCostTypePrice = opCost.Sum(x => x.ClientBreakfastFee); break; //988 客户早餐费用
case 93: opCostTypePrice = opCost.Sum(x => x.ClientDinnerFee); break; //93 客户午餐费用
case 989: opCostTypePrice = opCost.Sum(x => x.ClientLunchFee); break; //989 客户晚餐费用
case 990: opCostTypePrice = opCost.Sum(x => x.ScenicTicketFee); break; //990 景点门票费
case 991: opCostTypePrice = opCost.Sum(x => x.DrinkSnackFruitFee); break; //991 饮料/零食/水果
//case 91: opCostTypePrice = opCost.Sum(x => x.CarFee); break; //992 住补费用 -- 暂无
case 994: opCostTypePrice = opCost.Sum(x => x.TranslatorFee); break; //994 翻译费
case 1059: opCostTypePrice = opCost.Sum(x => x.GuideOverTimeFee); break; //1059 导游超时费用
//case 91: opCostTypePrice = opCost.Sum(x => x.CarFee); break; //1070 尾款金额
//case 91: opCostTypePrice = opCost.Sum(x => x.CarFee); break; //1071 其他额外费用
//case 91: opCostTypePrice = opCost.Sum(x => x.CarFee); break; //1073 翻译超时费
//case 91: opCostTypePrice = opCost.Sum(x => x.CarFee); break; //1074 早餐超支费用
//case 91: opCostTypePrice = opCost.Sum(x => x.CarFee); break; //1075 午餐超支费用
//case 91: opCostTypePrice = opCost.Sum(x => x.CarFee); break; //1076 晚餐超支费用
}
opCostStr = $" / 成本:{opCostTypePrice:#0.00} {_groupCurrencyCode}(汇率:{_groupRate:#0.0000})";
costOPFeeCNY = opCostTypePrice * _groupRate;
if (!IsCurrencyAgreement) opCostStr += $" ≈ {costOPFeeCNY:#0.00} CNY";
}
#endregion
string opTypeStr = $"{typeName}:{item.Price:#0.00} {carCurrencyCode}(汇率:{entity.DayRate:#0.0000})";
aduitOPFeeCNY = item.Price * entity.DayRate;
if (!IsCurrencyAgreement) opTypeStr += $" ≈ {aduitOPFeeCNY:#0.0000} CNY";
var opContent = $"日期:{item.DatePrice?.ToString("yyyy-MM-dd") ?? "-"}
" +
$"{opTypeStr} {opCostStr}
" +
$"明细:{item.PriceContent ?? "-"}
" +
$"备注:{item.Remark ?? "-"}
";
if (entity.IsAuditGM != 3) //状态 != 自动审核
{
if (IsCurrencyAgreement)
{
if (item.Price > opCostTypePrice)
{
opContent_sb.Append("");
opContent_sb.Append(opContent);
opContent_sb.Append("");
opContent_sb.AppendLine();
}
else
{
opContent_sb.Append(opContent);
opContent_sb.AppendLine();
}
}
else
{
//验证是否超成本 按付款比例计算
if (aduitOPFeeCNY * opPayPercentage > costOPFeeCNY * opPayPercentage)
{
opContent_sb.Append("");
opContent_sb.Append(opContent);
opContent_sb.Append("");
opContent_sb.AppendLine();
}
else
{
opContent_sb.Append(opContent);
opContent_sb.AppendLine();
}
}
}
else
{
opContent_sb.Append(opContent);
opContent_sb.AppendLine();
}
}
_detail.PriceMsgContent = opContent_sb.ToString();
}
break;
case 80: //签证
Grp_VisaInfo visaInfo = _VisaInfos.Where(s => s.Id == entity.CId).FirstOrDefault();
if (visaInfo != null)
{
string visaName = GetClientNameStr1(clientNameList, visaInfo.VisaClient);
_detail.PriceNameContent = visaInfo.VisaDescription;
_detail.PriceMsgContent = $"签证描述:{visaName}
备注:{visaInfo.Remark}";
}
break;
case 81: //邀请/公务活动
Grp_InvitationOfficialActivities _ioa = _InvitationOfficialActivities.Where(s => s.Id == entity.CId).FirstOrDefault();
if (_ioa != null)
{
string inviteCurrName = "Unknown", //邀请费用币种 Name
inviteCurrCode = "Unknown", //邀请费用币种 Code
sendCurrName = "Unknown", //快递费用币种 Name
sendCurrCode = "Unknown", //快递费用币种 Code
eventsCurrName = "Unknown", //公务活动费币种 Name
eventsCurrCode = "Unknown", //公务活动费币种 Code
translateCurrName = "Unknown", //公务翻译费 Name
translateCurrCode = "Unknown"; //公务翻译费 Code
#region 处理费用币种
var inviteCurrData = currencyItems.Where(s => s.Id == _ioa.InviteCurrency && s.IsDel == 0).FirstOrDefault();
if (inviteCurrData != null)
{
inviteCurrName = inviteCurrData.Remark;
inviteCurrCode = inviteCurrData.Name;
}
var sendCurrData = currencyItems.Where(s => s.Id == _ioa.SendCurrency && s.IsDel == 0).FirstOrDefault();
if (sendCurrData != null)
{
sendCurrName = sendCurrData.Remark;
sendCurrCode = sendCurrData.Name;
}
var eventsCurrData = currencyItems.Where(s => s.Id == _ioa.EventsCurrency && s.IsDel == 0).FirstOrDefault();
if (eventsCurrData != null)
{
eventsCurrName = eventsCurrData.Remark;
eventsCurrCode = eventsCurrData.Name;
}
var translateCurrData = currencyItems.Where(s => s.Id == _ioa.TranslateCurrency && s.IsDel == 0).FirstOrDefault();
if (translateCurrData != null)
{
translateCurrName = translateCurrData.Remark;
translateCurrCode = translateCurrData.Name;
}
#endregion
_detail.PriceNameContent = _ioa.InviterArea;
//2025-09-08 商邀费用名称更改:单项费用不等于0,则在名称后面最加费用类型名称。
List priceExpNames = new List();
if (_ioa.InviteCost != 0.00M) priceExpNames.Add("邀请费");
if (_ioa.SendCost != 0.00M) priceExpNames.Add("快递费");
if (_ioa.EventsCost != 0.00M) priceExpNames.Add("公务活动费");
if (_ioa.TranslateCost != 0.00M) priceExpNames.Add("公务翻译费");
if (priceExpNames != null && priceExpNames.Count > 0)
{
_detail.PriceNameContent += $"({string.Join("+", priceExpNames)})";
}
_detail.PriceMsgContent = $@"邀请费用:{_ioa.InviteCost:#0.00} {inviteCurrCode}({inviteCurrName})
" +
$@"快递费用:{_ioa.SendCost:#0.00} {sendCurrCode}({sendCurrName})
" +
$@"公务活动费:{_ioa.EventsCost:#0.00} {eventsCurrCode}({eventsCurrName})
" +
$@"公务翻译费:{_ioa.TranslateCost:#0.00} {translateCurrCode}({translateCurrName})
" +
$@"备注:" + _ioa.Remark + "
";
}
break;
case 82: //团组客户保险
Grp_Customers customers = _Customers.Where(s => s.Id == entity.CId && s.IsDel == 0).FirstOrDefault();
if (customers != null)
{
_detail.PriceNameContent = GetClientNameStr(clientNameList, customers.ClientName);
_detail.PriceMsgContent = "备注:" + customers.Remark + "
";
}
break;
case 85: //机票预订
Grp_AirTicketReservations jpRes = _AirTicketReservations.Where(s => s.Id == entity.CId).FirstOrDefault();
if (jpRes != null)
{
string FlightsDescription = jpRes.FlightsDescription;
string PriceDescription = jpRes.PriceDescription;
_detail.PriceMsgContent = "航班号:" + jpRes.FlightsCode + "
城市A-B:" + jpRes.FlightsCity + "
航班描述:" + FlightsDescription.Replace("\r\n", "
") + "
" + "价格描述:" + PriceDescription;
_detail.PriceNameContent = "(" + jpRes.FlightsCode + ")";
}
break;
case 98://其他款项
Grp_DecreasePayments gdpRes = _DecreasePayments.Where(s => s.Id == entity.CId).FirstOrDefault();
if (gdpRes != null)
{
//var urlBase = $"http://132.232.92.186:24/Office/GrpFile/http://132.232.92.186:24/Office/GrpFile/%E5%9B%A2%E7%BB%84%E5%A2%9E%E5%87%8F%E6%AC%BE%E9%A1%B9%E7%9B%B8%E5%85%B3%E6%96%87%E4%BB%B6/";
//if (!string.IsNullOrEmpty(gdpRes.FilePath))
//{
// _detail.FileUrl = $"{urlBase}{gdpRes.FilePath}";
//}
_detail.PriceMsgContent = "备注:" + gdpRes.Remark;
_detail.PriceNameContent = gdpRes.PriceName;
}
break;
case 285://收款退还
Fin_PaymentRefundAndOtherMoney refundAndOtherMoney = _PaymentRefundAndOtherMoneys.Where(s => s.Id == entity.CId).FirstOrDefault();
if (refundAndOtherMoney != null)
{
_detail.PriceMsgContent = "备注:" + refundAndOtherMoney.Remark;
_detail.PriceNameContent = refundAndOtherMoney.PriceName;
}
break;
case 751://酒店早餐
break;
case 1015://超支费用
Fin_GroupExtraCost groupExtraCost = _GroupExtraCosts.Where(s => s.Id == entity.CId).FirstOrDefault();
if (groupExtraCost != null)
{
_detail.PriceNameContent = groupExtraCost.PriceName;
_detail.PriceMsgContent = "备注:" + groupExtraCost.Remark;
}
break;
default:
break;
}
/*
* 申请人
*/
string operatorName = " - ";
var _opUser = userItems.Where(s => s.Id == entity.CreateUserId).FirstOrDefault();
if (_opUser != null)
{
operatorName = _opUser.CnName;
}
_detail.OperatorName = operatorName;
/*
* 审核人
*/
string auditOperatorName = " - ";
if (entity.IsAuditGM != 0)
{
if (entity.AuditGMOperate == 0) auditOperatorName = " - ";
else if (entity.AuditGMOperate == 4) auditOperatorName = "自动审核";
else
{
var _adUser = userItems.Where(s => s.Id == entity.AuditGMOperate).FirstOrDefault();
if (_adUser != null)
{
auditOperatorName = _adUser.CnName;
}
}
}
_detail.AuditOperatorName = auditOperatorName;
/*
* 超预算比例
*/
string overBudgetStr = "";
if (entity.ExceedBudget == -1) overBudgetStr = sdPriceName.Name + "尚无预算";
else if (entity.ExceedBudget == 0)
{
if (entity.CTable == 76 || entity.CTable == 79)
{
if (entity.IsAuditGM == 3) overBudgetStr = "未超预算";
else overBudgetStr = _feeAuditRep.IsOverBudget(entity.CTable, entity.DIId, entity.CId);
}
else
{
overBudgetStr = "未超预算";
}
}
else overBudgetStr = entity.ExceedBudget.ToString("P");
_detail.OverBudget = overBudgetStr;
decimal auditFee = 0.00M; //已审核金额 人名币
decimal auditedFeeOriginal = 0.00M; ////已审核金额 原始
decimal unAuditFeeCNY = 0.00M; //未审核款项 原始
decimal unAuditFeeOriginal = 0.00M; //未审核款项 人名币
if (entity.IsAuditGM == 1 || entity.IsAuditGM == 3)
{
auditedFeeOriginal = entity.PayMoney;
auditFee = CurrPayStr;
}
else if (entity.IsAuditGM == 0)
{
unAuditFeeCNY = CurrPayStr;
unAuditFeeOriginal = OriginalCurrPay;
OriginalCurrPay = 0.00M;
}
/*
* 费用总计
*/
ccpCurrencyPrices.Add(new CreditCardPaymentCurrencyPriceItem()
{
CurrencyId = entity.PaymentCurrency,
CurrencyName = PaymentCurrency_WaitPay,
AmountPayable = entity.PayMoney,
ThisPayment = OriginalCurrPay,
BalancePayment = BalanceStr,
AuditedFunds = auditFee,
AuditedFundsOriginal = auditedFeeOriginal,
UnAuditFundsCNY = unAuditFeeCNY,
UnAuditFundsOriginal = unAuditFeeOriginal
});
_detail.IsAuditGM = entity.IsAuditGM;
detailList.Add(_detail);
}
#endregion
_view.DetailList = new List(detailList);
/*
* 下方描述处理
*/
var nonDuplicat = ccpCurrencyPrices.Where((x, i) => ccpCurrencyPrices.FindIndex(z => z.CurrencyId == x.CurrencyId) == i).ToList();//Lambda表达式去重
var ccpCurrencyPrice = nonDuplicat.Where(it => it.CurrencyId == 836).FirstOrDefault();
if (ccpCurrencyPrice != null)
{
int CNYIndex = nonDuplicat.IndexOf(ccpCurrencyPrice);
nonDuplicat.MoveItemAtIndexToFront(CNYIndex);
}
else
{
nonDuplicat = nonDuplicat.OrderBy(it => it.CurrencyId).ToList();
}
string amountPayableStr = string.Format(@"应付款总金额: ");
string thisPaymentStr = string.Format(@"此次付款总金额: ");
string balancePaymentStr = string.Format(@"目前剩余尾款总金额: ");
string auditedFundsStr = string.Format(@"已审费用总额: ");
string unAuditedFundsStr = string.Format(@"未审费用总额: ");
foreach (var item in nonDuplicat)
{
var currencyName = item.CurrencyName;
var strs = ccpCurrencyPrices.Where(it => it.CurrencyId == item.CurrencyId).ToList();
if (strs.Count > 0)
{
decimal amountPayable = strs.Sum(it => it.AmountPayable);
decimal thisPayment = ccpCurrencyPrices.Sum(it => it.ThisPayment);
decimal balancePayment = strs.Sum(it => it.BalancePayment);
amountPayableStr += string.Format(@"{0}{1} |", amountPayable.ToString("#0.00"), currencyName);
//单独处理此次付款金额
thisPaymentStr += string.Format(@"{0}{1} |", strs.Sum(x => x.ThisPayment).ToString("#0.00"), currencyName);
balancePaymentStr += string.Format(@"{0}{1} |", balancePayment.ToString("#0.00"), currencyName);
//单独处理已审核费用
//if (item.CurrencyId == 836) //人民币
//{
// decimal auditedFunds = ccpCurrencyPrices.Sum(it => it.AuditedFunds);
// auditedFundsStr += string.Format(@"{0}{1} |", auditedFunds.ToString("#0.00"), currencyName);
//}
//else
//{
// auditedFundsStr += string.Format(@"{0}{1} |", strs.Sum(x => x.AmountPayable), currencyName);
//}
if (currencyName.Equals("CNY"))
{
//已审核费用
auditedFundsStr += string.Format(@"{0}{1} |", strs.Sum(x => x.ThisPayment).ToString("#0.00"), currencyName);
//未审核费用
unAuditedFundsStr += string.Format(@"{0}{1} |", strs.Sum(x => x.UnAuditFundsOriginal).ToString("#0.00"), currencyName);
}
else
{
//已审核费用
auditedFundsStr += string.Format(@"{0}{1}({2}CNY) |", strs.Sum(x => x.ThisPayment).ToString("#0.00"), currencyName, strs.Sum(x => x.AuditedFunds).ToString("#0.00"));
//未审核费用
unAuditedFundsStr += string.Format(@"{0}{1}({2}CNY) |", strs.Sum(x => x.UnAuditFundsOriginal).ToString("#0.00"), currencyName, strs.Sum(x => x.UnAuditFundsCNY).ToString("#0.00"));
}
}
}
_view.TotalStr1 = amountPayableStr[..^1];
_view.TotalStr2 = thisPaymentStr[..^1];
_view.TotalStr3 = balancePaymentStr[..^1];
_view.TotalStr4 = $"{auditedFundsStr[..^1]}
{unAuditedFundsStr[..^1]}";
//_view.TotalStr5 = unAuditedFundsStr.Substring(0, unAuditedFundsStr.Length - 1);
var _view1 = new
{
PageFuncAuth = pageFunAuthView,
Data = _view
};
return Ok(JsonView(_view1));
}
catch (Exception ex)
{
return Ok(JsonView(false, ex.Message));
}
}
///
/// 费用审核
/// 修改团组费用审核状态
///
/// 参数Json字符串
///
[HttpPost]
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
public async Task PostAuditGrpCreditCardPayment(Edit_GrpCreditCardPaymentDto _dto)
{
#region 参数验证
if (_dto.UserId < 1) return Ok(JsonView(false, "员工Id为空"));
if (_dto.PageId < 1) return Ok(JsonView(false, "页面Id为空"));
#endregion
#region 页面操作权限验证
var pageFunAuthView = await GeneralMethod.PostUserPageFuncDatas(_dto.UserId, _dto.PageId);
if (pageFunAuthView.AuditAuth == 0) return Ok(JsonView(false, "您没有审核权限"));
#endregion
List idList = _dto.CreditIdStr.Split(',').ToList();
Grp_CreditCardPayment _detail = _mapper.Map(_dto);
DateTime dtNow = DateTime.Now;
_groupRepository.BeginTran();
int rst = 0;
var creditDatas = _grpScheduleRep._sqlSugar.Queryable().Where(it => it.IsDel == 0 && idList.Contains(it.Id.ToString())).ToList();
var creditTypeDatas = _grpScheduleRep._sqlSugar.Queryable().Where(it => it.IsDel == 0 && it.STid == 16).ToList();
var creditCurrencyDatas = _grpScheduleRep._sqlSugar.Queryable().Where(it => it.IsDel == 0 && it.STid == 66).ToList();
var groupDatas = _grpScheduleRep._sqlSugar.Queryable().Where(it => it.IsDel == 0).ToList();
var msgDatas = new List();
var dic_ccp_user = new Dictionary() { };
foreach (var item in idList)
{
int CreditId = int.Parse(item);
var result = await _grpScheduleRep._sqlSugar.Updateable