936 lines
40 KiB
C#
936 lines
40 KiB
C#
using LumenWorks.Framework.IO.Csv;
|
||
using Ninject;
|
||
using NPOI.SS.UserModel;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Data;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Web;
|
||
using WX.CRM.Common;
|
||
using WX.CRM.IBLL.Base;
|
||
using WX.CRM.IBLL.Util;
|
||
using WX.CRM.Model;
|
||
using WX.CRM.Model.Entity;
|
||
using WX.CRM.Model.Enum;
|
||
using WX.CRM.WebHelper.Infrastructure;
|
||
|
||
namespace WX.CRM.WebHelper.ExcelImport
|
||
{
|
||
/*
|
||
* 一、数据结构
|
||
* BAS_excelimportLog:excel导入文件日志
|
||
* BAS_EXCELIMPORTTYPE:excel数据导入类别
|
||
* BAS_EXCELIMPORTDICT:excel数据导入字典
|
||
|
||
* 二、处理逻辑
|
||
* 1、第一步界面:指定上传类型,选择excel上传
|
||
* 2、传类型代码,调用工厂方法CreateUploadTool(excelDataType),返回对应数据类型的ComUploadTool子类实现,调用xxxUploadTool对象的CreateDataTable()返回DataTable数据
|
||
* 3、第二界面,前端分页显示DataTable的数据预览界面,此处可选择放弃导入,或导入
|
||
* 4、点导入后,调用xxxUploadTool对象的SaveToDatabase(),失败后记录失败日志,提示错误信息,并由用户选择“重试”或“放弃”;
|
||
* 5、成功后进入第三界面显示上一步的执行结果,点击“生成业务数据”按钮,调用xxxUploadTool对象的SyncBusinessData();
|
||
* 失败后记录失败日志,提示错误信息,并由用户选择“重试”或“放弃”;成功则提示"此次导入xxx文件数据成功!"。
|
||
|
||
|
||
*三、ComUploadTool的伪码实现
|
||
1*/
|
||
public abstract class ComUploadTool
|
||
{
|
||
|
||
#region method
|
||
|
||
public string userLoginLogId { get; set; }
|
||
public string deptCode { get; set; }
|
||
|
||
public ComUploadTool()
|
||
{
|
||
ExcelType = EnumExcelType.qh;//默认是渤海数据
|
||
excelImportLog = NinjectControllerFactory.ninjectKernel.Get<IBAS_EXCELIMPORTLOG>();
|
||
excelImportLog_Q = NinjectControllerFactory.ninjectKernel.Get<IBAS_EXCELIMPORTLOG_Q>();
|
||
import = NinjectControllerFactory.ninjectKernel.Get<IExcelImport>();
|
||
//Customer = WebHelper.Infrastructure.NinjectControllerFactory.ninjectKernel.Get<IBLL.Fxh.IFXH_CUSTOMER_Q>();
|
||
|
||
//_monthlystatement_q = WebHelper.Infrastructure.NinjectControllerFactory.ninjectKernel.Get<IBLL.Fxh.IFXH_MONTHLYSTATEMENT_Q>();
|
||
//gjsMonthlYstateMent_q = WebHelper.Infrastructure.NinjectControllerFactory.ninjectKernel.Get<IBLL.Gjs.IGJS_MONTHLYSTATEMENT_Q>();
|
||
_cacheQ = NinjectControllerFactory.ninjectKernel.Get<ICACHE_Q>();
|
||
_excelImportDict = NinjectControllerFactory.ninjectKernel.Get<IBAS_EXCELIMPORTDICT>();
|
||
_sequences = NinjectControllerFactory.ninjectKernel.Get<ISEQUENCES>();
|
||
}
|
||
public IExcelImport import;
|
||
public IBAS_EXCELIMPORTLOG excelImportLog;
|
||
public IBAS_EXCELIMPORTLOG_Q excelImportLog_Q;
|
||
//public IFXH_CUSTOMER_Q Customer;
|
||
//public IFXH_MONTHLYSTATEMENT_Q _monthlystatement_q;
|
||
//public IGJS_MONTHLYSTATEMENT_Q gjsMonthlYstateMent_q;
|
||
public ICACHE_Q _cacheQ;
|
||
|
||
public ISEQUENCES _sequences;
|
||
|
||
public IBAS_EXCELIMPORTDICT _excelImportDict;
|
||
/// <summary>
|
||
/// excel类型转换
|
||
/// </summary>
|
||
/// <param name="cell"></param>
|
||
/// <param name="type"></param>
|
||
/// <returns></returns>
|
||
public object GetObjectValue(ICell cell, string type)
|
||
{
|
||
string cellStr = cell.ToString().Trim();
|
||
if (cellStr.ToUpper() == "NONE")
|
||
return DBNull.Value;
|
||
object obj = new object();
|
||
switch (type)
|
||
{
|
||
case "System.String": obj = cellStr; break;
|
||
case "System.Decimal": obj = cellStr.GetDecimal(0); break;
|
||
case "System.Boolean": obj = Convert.ToBoolean(cellStr); break;
|
||
case "System.DateTime": obj = cellStr.GetObjectByDateTime(); break;
|
||
default: obj = cellStr; break;
|
||
}
|
||
return obj;
|
||
}
|
||
/// <summary>
|
||
/// 获取规则信息
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public string GetTradeRule()
|
||
{
|
||
string rule = _cacheQ.GetValue_Parameter(Model.Enum.Parameter.Sys_ExlceImport_PhoneRule);
|
||
if (string.IsNullOrEmpty(rule))
|
||
{
|
||
rule = "222666666";
|
||
}
|
||
return rule;
|
||
}
|
||
/// <summary>
|
||
/// =true就跳过验证导入正确机构的数据
|
||
/// =false验证不通过就不导入
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public string GetSkipOran()
|
||
{
|
||
string rule = _cacheQ.GetValue_Parameter(Model.Enum.Parameter.Sys_ExcelImport_SkipOran);
|
||
if (string.IsNullOrEmpty(rule))//默认是为false
|
||
rule = "false";
|
||
return rule;
|
||
}
|
||
public abstract EnumExcelDataType ExcelDataType { get; }
|
||
public EnumExcelType ExcelType { get; set; }
|
||
/// <summary>
|
||
/// 机构
|
||
/// </summary>
|
||
public string[] Organ { get; set; }
|
||
|
||
/// <summary>
|
||
/// excel类型转换
|
||
/// </summary>
|
||
/// <param name="cell"></param>
|
||
/// <param name="type"></param>
|
||
/// <returns></returns>
|
||
public object GetObjectValue(object cell, string type)
|
||
{
|
||
string cellStr = cell.ToString().Trim();
|
||
if (cellStr.ToUpper() == "NONE")
|
||
return DBNull.Value;
|
||
object obj = new object();
|
||
switch (type)
|
||
{
|
||
case "System.String": obj = cellStr; break;
|
||
case "System.Decimal":
|
||
obj = cellStr.GetDecimal(0);
|
||
break;
|
||
case "System.Boolean": obj = Convert.ToBoolean(cellStr); break;
|
||
case "System.DateTime":
|
||
obj = cellStr.GetObjectByDateTime();
|
||
break;
|
||
default: obj = cellStr; break;
|
||
}
|
||
return obj;
|
||
}
|
||
#endregion
|
||
|
||
#region 缓存
|
||
|
||
|
||
public DataTable LoadFromCache(ref ValidationErrors errMsg)
|
||
{
|
||
string cachename = userLoginLogId + ExcelDataType.ToString();
|
||
DataTable tab = CacheHelper.Get<DataTable>(cachename);
|
||
if (tab == null || tab.Rows.Count == 0)
|
||
errMsg.Add("上传的文件已经过期或者没有数据,请确认重新导入!");
|
||
return tab;
|
||
}
|
||
public void SaveToCache(DataTable dtData)
|
||
{
|
||
string cachename = userLoginLogId + ExcelDataType.ToString();
|
||
CacheHelper.Remove(cachename);
|
||
CacheHelper.Set<DataTable>(cachename, dtData, DateTime.Now.AddMinutes(10));
|
||
}
|
||
public void RemoveCacheData()
|
||
{
|
||
string cachename = userLoginLogId + ExcelDataType;
|
||
CacheHelper.Remove(cachename);
|
||
}
|
||
#endregion
|
||
|
||
#region CreateDataTable (生成待批量入库的DataTable)
|
||
/// <summary>
|
||
/// 生成待批量入库的DataTable
|
||
/// </summary>
|
||
/// <param name="file">上传的文件对象</param>
|
||
/// <param name="datatype">数据文件类型,枚举</param>
|
||
/// <param name="errMsg">错误信息</param>
|
||
/// <returns></returns>
|
||
public virtual DataTable CreateDataTable(HttpRequestBase Request, out ValidationErrors errMsg, decimal isNew)
|
||
{
|
||
string fileConrolName = "uploadFile";
|
||
if (isNew == 1)
|
||
{
|
||
fileConrolName = "uploadFile2";
|
||
}
|
||
HttpPostedFileBase file = Request.Files[fileConrolName];
|
||
string filename = file.FileName;
|
||
string suffix = filename.Substring(filename.LastIndexOf(".") + 1).ToLower();
|
||
errMsg = new ValidationErrors();
|
||
if (suffix == "xls" || suffix == "xlsx")
|
||
{
|
||
return ExcelToDataTable(Request, ref errMsg, fileConrolName, isNew);//excel 读取生成Datatable
|
||
}
|
||
else if (suffix == "csv")
|
||
{
|
||
return CsvToDataTable(Request, ref errMsg, fileConrolName, isNew);//Csv 读取生成Datatable
|
||
}
|
||
else
|
||
{
|
||
errMsg.Add("上传文件格式不正确!");
|
||
return new DataTable();
|
||
}
|
||
|
||
|
||
}
|
||
public virtual DataTable ExcelToDataTable(HttpRequestBase Request, ref ValidationErrors errMsg, string fileConrolName, decimal isNew)
|
||
{
|
||
//1、缓存中读取此datatype对应的数据字典,创建datatable
|
||
//2、根据数据字典的关键字,找出每一列对应的excel中字段的序号
|
||
//3、循环生成每一条datarow记录
|
||
#region
|
||
//DataTable tab = new DataTable();
|
||
//HttpPostedFileBase file = Request.Files[fileConrolName];
|
||
//Dictionary<string, int> excelDic = new Dictionary<string, int>();//存储excel 的列 和对应索引
|
||
//IWorkbook workbook = null;
|
||
//try
|
||
//{
|
||
// string filename = file.FileName;
|
||
// string suffix = filename.Substring(filename.LastIndexOf(".") + 1).ToLower();
|
||
// if (suffix == "xls")
|
||
// workbook = new HSSFWorkbook(file.InputStream);
|
||
// else if (suffix == "xlsx")
|
||
// workbook = new XSSFWorkbook(file.InputStream);
|
||
// List<BAS_EXCELIMPORTDICT> modelList = DataCacheHelper.GetCache().GetList_ExcelImportDict(ExcelDataType, isNew);//字典
|
||
// ISheet sheet = workbook.GetSheetAt(0);
|
||
|
||
// //====================表头=====================
|
||
// IRow headerRow = sheet.GetRow(10);
|
||
// int first = 0;
|
||
// foreach (var item in modelList)
|
||
// {
|
||
// int tempIndex = -1;
|
||
// for (int i = headerRow.FirstCellNum; i < int.MaxValue; i++)
|
||
// {
|
||
// if (headerRow.GetCell(i) == null || headerRow.GetCell(i).StringCellValue.Trim() == "") // 如果遇到第一个空列,则不再继续向后读取
|
||
// break;
|
||
// string cellValue = headerRow.GetCell(i).StringCellValue;
|
||
// if (first == 0)
|
||
// excelDic.Add(cellValue, i);
|
||
// if (item.EXCEL_COLNAME == cellValue)
|
||
// {
|
||
// item.ColumnIndex = i;
|
||
// }
|
||
// else if (cellValue.IndexOf(item.EXCEL_COLNAME) > -1)
|
||
// {
|
||
// tempIndex = i;//模糊匹配数据
|
||
// }
|
||
// else
|
||
// {
|
||
// continue;
|
||
// }
|
||
// }
|
||
// first++;
|
||
// if (item.ColumnIndex == -1)
|
||
// item.ColumnIndex = tempIndex;
|
||
// DataColumn column = new DataColumn();
|
||
// column.Caption = item.EXCEL_COLNAME;
|
||
// column.ColumnName = item.DB_COLNAME;
|
||
// if (!string.IsNullOrEmpty(item.COLTYPE))
|
||
// column.DataType = Type.GetType(item.COLTYPE);
|
||
// tab.Columns.Add(column);
|
||
// //确定列的索引
|
||
// }
|
||
// //================excel格式错误 找不到的列========
|
||
// List<BAS_EXCELIMPORTDICT> noColumnIndexList = modelList.Where(m => m.ISPRIMARY == 1 && m.ColumnIndex == -1).ToList();
|
||
// if (noColumnIndexList.Count > 0)
|
||
// {
|
||
|
||
// string erromessage = "excel中找不到列:";
|
||
// foreach (var model in noColumnIndexList)
|
||
// {
|
||
// erromessage += "[" + model.EXCEL_COLNAME + "]";
|
||
// }
|
||
// errMsg.Add(erromessage);
|
||
// return tab;
|
||
// }
|
||
// //=========================数据========================
|
||
// System.Collections.IEnumerator rows = sheet.GetRowEnumerator();
|
||
// int x = 0;
|
||
// while (rows.MoveNext())
|
||
// {
|
||
// if (x == 0)
|
||
// {
|
||
// x++;
|
||
// continue;//头部不加入数据
|
||
// }
|
||
// IRow row = (IRow)rows.Current;
|
||
// //if (row.Cells.Count < modelList.Count)
|
||
// // continue;
|
||
// DataRow dataRow = tab.NewRow();
|
||
// for (int i = row.FirstCellNum; i < modelList.Count; i++)
|
||
// {
|
||
// object colvalue = new object();
|
||
// if (modelList[i].ColumnIndex != -1 && row.Cells.Count > modelList[i].ColumnIndex)
|
||
// colvalue = GetObjectValue(row.GetCell(modelList[i].ColumnIndex), modelList[i].COLTYPE);//根据引获取值
|
||
// else
|
||
// colvalue = DBNull.Value;
|
||
// if (modelList[i].ColumnIndex == -1)
|
||
// colvalue = DBNull.Value;
|
||
|
||
|
||
|
||
// if (!string.IsNullOrWhiteSpace(modelList[i].VALUEFUNCTION))
|
||
// {
|
||
// if (modelList[i].VALUEFUNCTION == "CREATERESID")//--------------创建客户ID
|
||
// {
|
||
// colvalue = CreateResId(colvalue.ToString());
|
||
// }
|
||
// else if (modelList[i].VALUEFUNCTION == "CUSTOMFORMATCOLNUM")//--特殊格式化函数
|
||
// {
|
||
// colvalue = CustomFormatColnum(modelList, row, modelList[i], excelDic);
|
||
// }
|
||
// else if (modelList[i].VALUEFUNCTION == "FORMDATAFORMAT")//---从上传界面获取的 数据
|
||
// {
|
||
// colvalue = FormDataFormat(Request, modelList[i]);
|
||
// }
|
||
// }
|
||
// dataRow[i] = colvalue;
|
||
// }
|
||
// tab.Rows.Add(dataRow);
|
||
|
||
// }
|
||
// DealWhithData(ref tab);//溢出datatable不必要的数据
|
||
// //RemoveCacheData();//先移除缓存
|
||
// //SaveToCache(tab);
|
||
// return tab;
|
||
//}
|
||
//catch (Exception ex) { errMsg.Add(ex.ToString()); return tab; }
|
||
#endregion
|
||
var tab = new DataTable();
|
||
HttpPostedFileBase file = Request.Files[fileConrolName];
|
||
IWorkbook workbook = null;
|
||
try
|
||
{
|
||
workbook = WorkbookFactory.Create(file.InputStream);
|
||
var excelImportType = DataCacheHelper.GetCache().GetModel_ExcelImportType(ExcelDataType);//导入excel类型
|
||
var headerStartRow = int.Parse(excelImportType.HEADERSTARTROW.ToString());
|
||
var dataStartRow = int.Parse(excelImportType.DATASTARTROW.ToString());
|
||
var tableNameRow = int.Parse(excelImportType.TABLENAMEROW.ToString());
|
||
var sheet = workbook.GetSheetAt(0);
|
||
////====================获取表名比较=============
|
||
//var tableName = sheet.GetRow(tableNameRow).GetCell(0).ToString().Trim();
|
||
//if (tableName != excelImportType.TYPENAME)
|
||
//{
|
||
// errMsg.Add("excel类型错误,请确认是否导错excel!");
|
||
// return tab;
|
||
//}
|
||
//====================表头=====================
|
||
var headerRow = sheet.GetRow(headerStartRow);
|
||
for (int i = headerRow.FirstCellNum; i < headerRow.LastCellNum; i++)
|
||
{
|
||
var cellValue = headerRow.GetCell(i).StringCellValue;
|
||
var column = new DataColumn
|
||
{
|
||
Caption = cellValue,
|
||
ColumnName = cellValue,
|
||
DataType = Type.GetType("System.String")
|
||
};
|
||
tab.Columns.Add(column);
|
||
}
|
||
|
||
//=========================数据========================
|
||
var rows = sheet.GetRowEnumerator();
|
||
var x = sheet.FirstRowNum;
|
||
IRow row = null;
|
||
while (rows.MoveNext())
|
||
{
|
||
if (x < dataStartRow)
|
||
{
|
||
x++;
|
||
continue;//头部不加入数据
|
||
}
|
||
row = (IRow)rows.Current;
|
||
if (string.IsNullOrWhiteSpace(row.GetCell(0).ToString()))
|
||
continue;
|
||
var dataRow = tab.NewRow();
|
||
for (var i = row.FirstCellNum; i < row.LastCellNum; i++)
|
||
{
|
||
var cell = row.GetCell(i);
|
||
if (cell == null)
|
||
{
|
||
dataRow[i] = DBNull.Value;
|
||
}
|
||
else
|
||
{
|
||
dataRow[i] = cell.ToString();
|
||
}
|
||
}
|
||
tab.Rows.Add(dataRow);
|
||
|
||
}
|
||
|
||
return tab;
|
||
}
|
||
catch (Exception ex) { errMsg.Add(ex.ToString()); return tab; }
|
||
|
||
}
|
||
public virtual DataTable CsvToDataTable(HttpRequestBase Request, ref ValidationErrors errMsg, string fileConrolName, decimal isNew)
|
||
{
|
||
//1、缓存中读取此datatype对应的数据字典,创建datatable
|
||
//2、根据数据字典的关键字,找出每一列对应的excel中字段的序号
|
||
//3、循环生成每一条datarow记录
|
||
errMsg = new ValidationErrors();
|
||
DataTable tab = new DataTable();
|
||
HttpPostedFileBase file = Request.Files[fileConrolName];
|
||
Dictionary<string, int> excelDic = new Dictionary<string, int>();//存储excel 的列 和对应索引
|
||
try
|
||
{
|
||
using (CsvReader csv = new CsvReader(new StreamReader(file.InputStream, Encoding.GetEncoding("gb2312")), true))
|
||
{
|
||
csv.MissingFieldAction = MissingFieldAction.ReplaceByEmpty;
|
||
int fieldCount = csv.FieldCount;
|
||
string[] headers = csv.GetFieldHeaders();
|
||
List<BAS_EXCELIMPORTDICT> modelList = DataCacheHelper.GetCache().GetList_ExcelImportDict(ExcelDataType, isNew);//字典
|
||
//--------------------------表头--------------------------
|
||
for (int i = 0; i < headers.Length; i++)
|
||
{
|
||
string head = headers[i].Trim();
|
||
excelDic.Add(head, i);
|
||
}
|
||
foreach (BAS_EXCELIMPORTDICT model in modelList)
|
||
{
|
||
for (int i = 0; i < headers.Length; i++)
|
||
{
|
||
string head = headers[i].Trim();
|
||
if (head == model.EXCEL_COLNAME.Trim())
|
||
{
|
||
model.ColumnIndex = i;
|
||
break;
|
||
}
|
||
else if (head.Contains(model.EXCEL_COLNAME.Trim()))
|
||
{
|
||
model.ColumnIndex = i;
|
||
continue;
|
||
}
|
||
}
|
||
DataColumn column = new DataColumn();
|
||
column.Caption = model.EXCEL_COLNAME;
|
||
column.ColumnName = model.DB_COLNAME;
|
||
if (!string.IsNullOrEmpty(model.COLTYPE))
|
||
column.DataType = Type.GetType(model.COLTYPE);
|
||
tab.Columns.Add(column);
|
||
}
|
||
List<BAS_EXCELIMPORTDICT> noColumnIndexList = modelList.Where(m => m.ISPRIMARY == 1 && m.ColumnIndex == -1).ToList();
|
||
if (noColumnIndexList.Count > 0)
|
||
{
|
||
|
||
string erromessage = "excel中找不到列:";
|
||
foreach (var model in noColumnIndexList)
|
||
{
|
||
erromessage += "[" + model.EXCEL_COLNAME + "]";
|
||
}
|
||
errMsg.Add(erromessage);
|
||
return tab;
|
||
}
|
||
|
||
//--------------------------数据--------------------------
|
||
while (csv.ReadNextRecord())
|
||
{
|
||
DataRow dataRow = tab.NewRow();
|
||
for (int i = 0; i < modelList.Count; i++)
|
||
{
|
||
BAS_EXCELIMPORTDICT model = modelList[i];
|
||
object colvalue = new object();
|
||
if (model.ColumnIndex != -1)
|
||
{
|
||
var cell = csv[model.ColumnIndex].Trim();
|
||
if (model.VALUEFUNCTION == null || model.VALUEFUNCTION != "CUSTOMFORMATCOLNUM")
|
||
colvalue = GetObjectValue(cell, model.COLTYPE);//根据引获取值
|
||
else
|
||
colvalue = cell;
|
||
}
|
||
if (model.ColumnIndex == -1)
|
||
colvalue = DBNull.Value;
|
||
|
||
if (!string.IsNullOrWhiteSpace(model.VALUEFUNCTION))
|
||
{
|
||
if (model.VALUEFUNCTION == "CREATERESID")//--------------创建客户ID
|
||
{
|
||
colvalue = CreateResId(colvalue.ToString());
|
||
}
|
||
else if (model.VALUEFUNCTION == "CUSTOMFORMATCOLNUM")//--特殊格式化函数
|
||
{
|
||
colvalue = CustomFormatColnum(modelList, csv, model, excelDic);
|
||
}
|
||
else if (model.VALUEFUNCTION == "FORMDATAFORMAT")//---从上传界面获取的 数据
|
||
{
|
||
colvalue = FormDataFormat(Request, model);
|
||
}
|
||
}
|
||
|
||
dataRow[i] = colvalue;
|
||
}
|
||
|
||
tab.Rows.Add(dataRow);
|
||
}
|
||
DealWhithData(ref tab);//溢出datatable不必要的数据
|
||
//RemoveCacheData();//先移除缓存
|
||
//SaveToCache(tab);
|
||
return tab;
|
||
}
|
||
}
|
||
catch (Exception ex) { errMsg.Add(ex.ToString()); return tab; }
|
||
}
|
||
#endregion
|
||
|
||
#region SaveToDatabase (将上一步生成的DataTable入库)
|
||
/// <summary>
|
||
/// 将上一步生成的DataTable入库
|
||
/// 状态:70无效、100文件已导入、110已计算、200生成数据成功
|
||
/// </summary>
|
||
/// <param name="dbData">数据dataTable</param>
|
||
/// <param name="errMsg">错误信息</param>
|
||
/// <returns></returns>
|
||
public bool SaveToDatabase(DataTable dbData, decimal userId, string fileName, out ValidationErrors OutErrMsg, ref decimal importId)
|
||
{
|
||
//1、生成一条上传文件主记录,状态为70,插入主记录
|
||
//2、成功则调用插入中间表明细的方法
|
||
// bool bok = SaveImportDetail(主记录对象);
|
||
//3、bok为false,须删除主记录,否则更新主记录状态为100
|
||
ValidationErrors errMsg = new ValidationErrors();
|
||
OutErrMsg = new ValidationErrors();
|
||
if (importId == 0)//没有日志记录
|
||
{
|
||
//===========================插入导入记录=============================
|
||
BAS_EXCELIMPORTLOG model = new BAS_EXCELIMPORTLOG();
|
||
model.CTIME = DateTime.Now;
|
||
model.CREATEUSER = userId;
|
||
model.DONEREMARK = "";
|
||
model.DONESTATUS = 70;
|
||
model.FILENAME = fileName;
|
||
model.EXCELTYPE = ExcelDataType.ToString();
|
||
importId = excelImportLog.Create(ref errMsg, model);
|
||
string msg = string.Empty;
|
||
if (importId < 1)
|
||
{
|
||
OutErrMsg.Add("插入日志失败!");
|
||
return false;
|
||
}
|
||
//===================================插入中间表明细======================
|
||
bool bok = SaveImportDetail(dbData, importId, ref errMsg);
|
||
if (bok == false)
|
||
{
|
||
excelImportLog.Delete(ref errMsg, importId);//删除 日志记录
|
||
LogHelper.Error("插入中间表错误:" + errMsg.Error);//--记录错误日志
|
||
OutErrMsg.Add("Excel批量入库失败!");
|
||
importId = 0;
|
||
return false;
|
||
}
|
||
else
|
||
{
|
||
excelImportLog.UpdateDoneStatus(ref errMsg, importId, 100);//修改 日志记录状态
|
||
}
|
||
RemoveCacheData();//成功后清除缓存
|
||
}
|
||
//================================中间表有特殊字段需计算====================
|
||
if (ComputeColnumBeforeGen(ref errMsg, importId))
|
||
{
|
||
excelImportLog.UpdateDoneStatus(ref errMsg, importId, 110);//修改 日志记录状态
|
||
|
||
}
|
||
else
|
||
{
|
||
LogHelper.Error("中间表计算错误:" + errMsg.Error);//--记录错误日志
|
||
OutErrMsg.Add("Excel批量入库成功!但是计算失败!");
|
||
}
|
||
|
||
return (errMsg.Count > 0 ? false : true);
|
||
}
|
||
#endregion
|
||
|
||
#region SyncBusinessData(生成业务数据)
|
||
/// <summary>
|
||
/// 生成业务数据
|
||
/// </summary>
|
||
/// <param name="errMsg">错误信息</param>
|
||
/// <param name="importId">导入ID</param>
|
||
/// <returns></returns>
|
||
public bool SyncBusinessData(out ValidationErrors outErrMsg, decimal importId)
|
||
{
|
||
ValidationErrors errMsg = new ValidationErrors();
|
||
outErrMsg = new ValidationErrors();
|
||
BAS_EXCELIMPORTLOG model = excelImportLog_Q.GetModel(importId);
|
||
if (model == null)
|
||
{
|
||
outErrMsg.Add("找不到批次号!");
|
||
return false;
|
||
}
|
||
if (model.EXCELTYPE == "100")
|
||
{
|
||
if (ComputeColnumBeforeGen(ref errMsg, importId))//if(主记录的状态为100),需调用ComputeColnumBeforeGen()
|
||
{
|
||
excelImportLog.UpdateDoneStatus(ref errMsg, importId, 110);//修改 日志记录状态
|
||
}
|
||
else
|
||
{
|
||
outErrMsg.Add("计算出现错误!");
|
||
LogHelper.Error("生成业务表,计算错误:" + errMsg.Error);//--记录错误日志
|
||
return false;
|
||
}
|
||
}
|
||
bool result = GenerateBusinessData(ref errMsg, importId);//生成业务数据
|
||
if (result)
|
||
excelImportLog.UpdateDoneStatus(ref errMsg, importId, 200);//成功则将主记录状态置为200
|
||
else
|
||
{
|
||
LogHelper.Error("生成业务表错误:" + errMsg.Error);//--记录错误日志
|
||
outErrMsg.Add("生成业务表错误!");
|
||
}
|
||
return result;
|
||
}
|
||
|
||
|
||
#endregion
|
||
|
||
#region 验证数据
|
||
/// <summary>
|
||
/// 验证错误数据
|
||
/// </summary>
|
||
/// <param name="message">这个是自定义的信息提示(提示前提,outMsg没有数据)</param>
|
||
/// <param name="outMsg">outMsg有数据证明是报错</param>
|
||
/// <returns></returns>
|
||
public DataTable CheckErroData(out string message, ref ValidationErrors outMsg)
|
||
{
|
||
ValidationErrors errMsg = new ValidationErrors();
|
||
DataTable tab = this.LoadFromCache(ref outMsg);//获取缓存数据
|
||
message = "";
|
||
DataTable errTab = null;
|
||
try
|
||
{
|
||
errTab = CheckErroDataTable(tab, out message, ref errMsg);
|
||
}
|
||
catch (Exception ex) { errMsg.Add(ex.ToString()); }
|
||
finally
|
||
{
|
||
if (errMsg.Count > 0)
|
||
{
|
||
LogHelper.Error("验证出现错误:" + errMsg.Error);//--记录错误日志
|
||
outMsg.Add("验证出现错误!");
|
||
}
|
||
else if (errTab != null && errTab.Rows.Count > 0)
|
||
{
|
||
RemoveCacheData();//--移除正确的数据
|
||
SaveToCache(errTab);//--替换成错误的数据
|
||
}
|
||
}
|
||
return errTab;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 子类可重写的实现
|
||
/// <summary>
|
||
/// 获取错误的datable数据(续子类重写)
|
||
/// </summary>
|
||
/// <param name="tab">错误数据的Datatable,如果没有(Datatable.Count=0 和message="" 和 errMsg.Count==0)=>数据验证通过</param>
|
||
/// <param name="message">自定义的提示信息</param>
|
||
/// <param name="errMsg">报错信息</param>
|
||
/// <returns></returns>
|
||
protected virtual DataTable CheckErroDataTable(DataTable tab, out string message, ref ValidationErrors errMsg)
|
||
{
|
||
DataTable errTab = tab.Clone();
|
||
message = string.Empty;
|
||
return errTab;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 批量入库(子类可以对DataTable做特殊入库操作)
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
protected virtual bool SaveImportDetail(DataTable dbData, decimal importId, ref ValidationErrors errMsg)
|
||
{
|
||
//从缓存里读取BAS_EXCELIMPORTTYPE的相应记录的表名,调用批量入库的函数
|
||
BAS_EXCELIMPORTTYPE model = DataCacheHelper.GetCache().GetModel_ExcelImportType(ExcelDataType);
|
||
return import.FxhOracleBulkInsert(ref errMsg, model.DB_TABLENAME, importId, dbData);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 数据计算(如在生成业务表数据前,中间表有特殊字段需计算,子类重写此方法)
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
protected virtual bool ComputeColnumBeforeGen(ref ValidationErrors errMsg, decimal importId)
|
||
{
|
||
return import.ComputeColnumBeforeGen(ref errMsg, ExcelDataType, importId);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 单元格数据格式化(供子类重写的格式化计算函数)
|
||
/// </summary>
|
||
/// <param name="dictList">表字典</param>
|
||
/// <param name="excelRow">这行excel数据</param>
|
||
/// <param name="dictModel">该单元格字典对象</param>
|
||
/// <param name="dictModel">存储excel 的列 和对应索引</param>
|
||
/// <returns></returns>
|
||
protected virtual object CustomFormatColnum(List<BAS_EXCELIMPORTDICT> dictList, IRow excelRow, BAS_EXCELIMPORTDICT dictModel, Dictionary<string, int> excelDic)
|
||
{
|
||
if (dictModel.ColumnIndex == -1)
|
||
return DBNull.Value;
|
||
return excelRow.Cells[dictModel.ColumnIndex];
|
||
}
|
||
/// <summary>
|
||
/// 单元格数据格式化(供子类重写的格式化计算函数)
|
||
/// </summary>
|
||
/// <param name="dictList">表字典</param>
|
||
/// <param name="excelRow">这行excel数据</param>
|
||
/// <param name="dictModel">该单元格字典对象</param>
|
||
/// <param name="dictModel">存储excel 的列 和对应索引</param>
|
||
/// <returns></returns>
|
||
protected virtual object CustomFormatColnum(List<BAS_EXCELIMPORTDICT> dictList, CsvReader rowReader, BAS_EXCELIMPORTDICT dictModel, Dictionary<string, int> excelDic)
|
||
{
|
||
if (dictModel.ColumnIndex == -1)
|
||
return DBNull.Value;
|
||
return rowReader[dictModel.ColumnIndex];
|
||
}
|
||
/// <summary>
|
||
/// 获取 form表单数据(子类继承)
|
||
/// </summary>
|
||
/// <param name="Request">request对象</param>
|
||
/// <param name="dictModel">该单元格字段对象</param>
|
||
/// <returns></returns>
|
||
public virtual object FormDataFormat(HttpRequestBase Request, BAS_EXCELIMPORTDICT dictModel)
|
||
{
|
||
return new object();
|
||
}
|
||
/// <summary>
|
||
/// 生成业务表(中间表数据生成到业务表)
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
protected virtual bool GenerateBusinessData(ref ValidationErrors errMsg, decimal importId)
|
||
{
|
||
return import.GenerateBusinessData(ref errMsg, ExcelDataType, importId);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 移除需要过滤掉的数据信息
|
||
/// </summary>
|
||
protected virtual void DealWhithData(ref DataTable tab)
|
||
{
|
||
|
||
}
|
||
#endregion
|
||
|
||
#region 公共调用函数
|
||
/// <summary>
|
||
/// 创建客户ID
|
||
/// </summary>
|
||
/// <param name="number">电话号码</param>
|
||
/// <returns></returns>
|
||
protected string CreateResId(string number)
|
||
{
|
||
return ResUtil.CreateResId(number);
|
||
}
|
||
/// <summary>
|
||
/// 营业部交易商样本 验证
|
||
/// </summary>
|
||
/// <param name="message">自定义信息提示</param>
|
||
/// <param name="tab">Datatable数据</param>
|
||
/// <returns></returns>
|
||
protected bool DeptTradeCodeCheck(ref string message, DataTable tab)
|
||
{
|
||
//if (!tab.Columns.Contains("TRADECODE"))
|
||
// return true;
|
||
//string tradecode = "''";
|
||
//if (ExcelType == EnumExcelType.gjs)//贵金属
|
||
//{
|
||
// List<GJS_DEPTTRADECODE> list = DataCacheHelper.GetCache().GetList_GjsDeptTradecode(deptCode);
|
||
// foreach (GJS_DEPTTRADECODE model in list)
|
||
// {
|
||
// tradecode += ",'" + model.TRADECODE + "'";
|
||
// }
|
||
//}
|
||
//else if (ExcelType == EnumExcelType.fxh)//渤海
|
||
//{
|
||
// List<FXH_DEPTTRADECODE> list = DataCacheHelper.GetCache().GetList_FxhDeptTradecode(deptCode);
|
||
// foreach (FXH_DEPTTRADECODE model in list)
|
||
// {
|
||
// tradecode += ",'" + model.TRADECODE + "'";
|
||
// }
|
||
//}
|
||
//DataRow[] row = tab.Select("TRADECODE in (" + tradecode + ")");
|
||
//if (row.Length > 0)
|
||
//{
|
||
// message = "存在非本营业部交易商代码!";
|
||
// return false;
|
||
//}
|
||
//else
|
||
return true;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 验证是否月结
|
||
/// </summary>
|
||
/// <param name="date"></param>
|
||
/// <returns>false未月结,ture 已月结 </returns>
|
||
protected bool MonthlyStatement(string date)
|
||
{
|
||
//DateTime dt;
|
||
|
||
//if (DateTime.TryParse(date, out dt))
|
||
//{
|
||
// decimal monthcode = Convert.ToDecimal(dt.Year.ToString() + dt.Month.ToString());
|
||
// if (ExcelType == EnumExcelType.fxh)
|
||
// {
|
||
// var monthModel = _monthlystatement_q.getMonthlyStatement(monthcode);
|
||
// if (monthModel == null)
|
||
// {
|
||
// return false;
|
||
// }
|
||
// }
|
||
// else if (ExcelType == EnumExcelType.gjs)
|
||
// {
|
||
// var monthModel = gjsMonthlYstateMent_q.getMonthlyStatement(monthcode);
|
||
// if (monthModel == null)
|
||
// {
|
||
// return false;
|
||
// }
|
||
// }
|
||
// return true;
|
||
//}
|
||
|
||
return false;
|
||
}
|
||
/// <summary>
|
||
/// 导入字段的检查,如果没变化返回true
|
||
/// </summary>
|
||
/// <param name="list"></param>
|
||
/// <returns></returns>
|
||
public bool DataTableColumnCheck()
|
||
{
|
||
try
|
||
{
|
||
var outMsg = new ValidationErrors();
|
||
var tab = this.LoadFromCache(ref outMsg);
|
||
var excelImportType = DataCacheHelper.GetCache().GetModel_ExcelImportType(ExcelDataType);
|
||
var excelImportDict = DataCacheHelper.GetCache().GetList_ExcelImportDict(ExcelDataType);
|
||
|
||
if (excelImportDict.Count <= 0)
|
||
{
|
||
//新的还没有数据,把字段写入字典表并新建表
|
||
GenExcelImportDict(tab);
|
||
GenDataTable(excelImportType.DB_TABLENAME, tab);
|
||
}
|
||
else
|
||
{
|
||
//对比字段是否有改变,有的话更新字典表,备份中间表并新建中间表
|
||
var excelColumn = new List<string>();
|
||
foreach (var item in tab.Columns)
|
||
{
|
||
excelColumn.Add(item.ToString());
|
||
}
|
||
var dicColumn = excelImportDict.Select(p => p.DB_COLNAME).ToList();
|
||
var minusColumn = excelColumn.Union(dicColumn).Except(excelColumn.Intersect(dicColumn));
|
||
//如果有值,说明存在差异
|
||
if (minusColumn.Any())
|
||
{
|
||
DeleteExcelImportDict();
|
||
GenExcelImportDict(tab);
|
||
BackDataTable(excelImportType.DB_TABLENAME);
|
||
GenDataTable(excelImportType.DB_TABLENAME, tab);
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
LogHelper.Error(e);
|
||
return false;
|
||
}
|
||
|
||
}
|
||
|
||
private void GenDataTable(string tableName, DataTable dt)
|
||
{
|
||
var columns = "pkid number, importid number, ";
|
||
foreach (var item in dt.Columns)
|
||
{
|
||
columns += item.ToString().Replace('(', '_').Replace(')', ' ') + " varchar2(200),";
|
||
}
|
||
columns = columns.TrimEnd(',');
|
||
//LogHelper.Info(columns);
|
||
import.GenDataTable(tableName, columns);
|
||
}
|
||
|
||
private void GenExcelImportDict(DataTable dt)
|
||
{
|
||
var list = new List<BAS_EXCELIMPORTDICT>();
|
||
foreach (var item in dt.Columns)
|
||
{
|
||
list.Add(new BAS_EXCELIMPORTDICT()
|
||
{
|
||
PKID = _sequences.Seq_base_get(PKIDType.LargeTable, ConStringHelper.QhCrmConn),
|
||
TYPEID = ExcelDataType.ToString(),
|
||
DB_COLNAME = item.ToString(),
|
||
EXCEL_COLNAME = item.ToString(),
|
||
COLTYPE = "varchar2(200)",
|
||
CTIME = DateTime.Now
|
||
});
|
||
}
|
||
_excelImportDict.AddList(list);
|
||
}
|
||
|
||
private void DeleteExcelImportDict()
|
||
{
|
||
_excelImportDict.Delete(p => p.TYPEID == ExcelDataType.ToString());
|
||
}
|
||
|
||
private void BackDataTable(string tableName)
|
||
{
|
||
var tableOldName = tableName;
|
||
var tableNewName = tableName + DateTime.Now.ToString("HHmmss");
|
||
import.BackDataTable(tableOldName, tableNewName);
|
||
}
|
||
|
||
|
||
#endregion
|
||
}
|
||
|
||
/*
|
||
*四、各种excel表的导入要做的事
|
||
*1、定义数据类别,数据字典
|
||
*2、从ComUploadTool基类继承实现一个待定类型的子类xxxUploadTool
|
||
*3、如非标准格式的表格,须重写xxxUploadTool中的CreateDataTable函数,覆盖基类的默认生成;如是标准的单表格式,则不需重写此方法,
|
||
* 只需看字典中的字段有没有VALUEFUNCTION是CUSTOMFORMATCOLNUM()的,有的话就要重写此函数。
|
||
*4、如需将DataTable做特殊入库操作,需重写SaveImportDetail()方法,否则不需要
|
||
*5、如在生成业务表数据前一些计算字段要在中间表生成的,需重写ComputeColnumBeforeGen()方法实现
|
||
*6、GenerateBusinessData为生成业务数据的抽象方法,必须由各子类去实现。
|
||
*/
|
||
}
|