using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.IO;
using System.Collections.Specialized;
using System.Threading;
using System.Collections.Concurrent;
using System.Diagnostics;
using SqlSugar;
using Newtonsoft.Json;
using HXX.Scanner.Database;
using HXX.Scanner.Common;
using HXX.Scanner.Biz.Socket;
namespace HXX.Scanner.Biz
{
///
/// 文件上传类
///
public class upf
{
///
/// 文件基本信息,来自数据库
///
public tb_file_info entity { get; set; }
///
/// 文件当初状态,判断是否允许做上传的动作
///
public ResponseEntity result { get; set; }
///
/// seqNumber
///
//public int seqNumber { get; set; }
///
/// upload type
///
public upload_type_enum upload_type { get; set; }
}
///
/// 文件上传业务
///
public class http_manager
{
public http_manager()
{
////测试状态禁止上传
//if (config_environment.scan_type == ScanType.Test_Panel_1_Side || config_environment.scan_type == ScanType.Test_Panel_2_Sides)
//{
// return;
//}
//else
//{
// url_upload = config_environment.web_parameter.uploadUrl + config_manager.Get("uploadFileUrl");
//}
url_upload = config_environment.web_parameter.uploadUrl;
}
///
/// url
///
private string url_upload;
///
/// 上传失败的处理方法
///
public static del_on_net_broken on_net_broken;
///
/// 上传结果通知
///
public static del_http_notify on_http_notify;
///
/// 上传结果通知2
///
public static del_http_notify2 on_http_notify2;
///
/// 文件上传队列
///
private static ConcurrentQueue queue = new ConcurrentQueue();
//public void Upload(tb_file_info _entity, ResponseEntity _result)
//{
// var e_q = new upf() { entity = _entity, result = _result, seqNumber = 0 };
// queue.Enqueue(e_q);
//}
private static readonly object lockObj = new object();
public static List ready_list = new List();
///
/// 检查队列是否为空
///
///
public static bool check_is_queue_empty()
{
//return false;
return queue.IsEmpty;
}
///
/// 进上传队列
///
///
public void Upload(upf e_q)
{
queue.Enqueue(e_q);
}
//public static void start_http_upload()
//{
// Task.Run(() =>
// {
// while (true)
// {
// if (!queue.IsEmpty)
// {
// queue.TryDequeue(out upf eq);
// if (eq != null)
// {
// new http_manager().Upload_1(eq.entity, eq.result, eq.seqNumber);
// }
// }
// else
// {
// Thread.Sleep(100);
// }
// }
// });
//}
///
/// 队列上传线程
///
public static void start_http_upload()
{
Task.Run(() =>
{
while (true)
{
if (!queue.IsEmpty)
{
//队列不空,取一个待上传实体
queue.TryDequeue(out upf eq);
if (eq != null)
{
//真实上传业务
//开始计时
Stopwatch sw = new Stopwatch();
sw.Start();
while (true)
{
//判断图片转换和保存数据库操作是否完成
if ((eq.upload_type == upload_type_enum.normal && eq.result != null && eq.result.Status == 1)
|| eq.upload_type == upload_type_enum.reUpload)
{
//告诉网页端开始上传
//if (eq.entity.fi_zipId == 1)
//{
// var response = new response_uploading() { batchNumber = eq.entity.fi_batchSeq, subjectCode = eq.entity.fi_subjectCode };
// on_http_notify2(JsonConvert.SerializeObject(response));
//}
//http上传
eq.result = new http_manager().Upload_1(eq);
break;
}
else
{
//数据操作超时
if (sw.ElapsedMilliseconds > 10000)
{
eq.result.Status = 0;
eq.result.Message = "保存图片超时";
sw.Stop();
break;
}
else
{
Thread.Sleep(100);
}
}
}
//真实上传业务
//test
//if (testflag)
//{
// eq.result.Status = 1;
//}
//else
//{
// eq.result.Status = 0;
//}
//testflag = !testflag;
//test
//AfterUpload(eq);
}
}
else
{
Thread.Sleep(100);
}
}
});
}
private static void AfterUpload(upf eq)
{
//Thread.Sleep(1000);
try
{
if (eq.result.Status == 1 || eq.result.Status == 200 )
{
entity_server_upload server_response = null;
try
{
server_response = JsonConvert.DeserializeObject(eq.result.Data.data_string);
}
catch (Exception ee)
{
LogManager_Lock.WriteLog(ee.Message);
}
var db_list = new biz_db().get_by_sn(eq.entity.fi_SN);
foreach (var entity in db_list)
{
var fileName = Path.GetFileName(entity.fi_full_name);
var path = Path.GetDirectoryName(entity.fi_full_name);
path = path.Replace("ready", "complete");
fileName = Path.Combine(path, fileName);
try
{
if (File.Exists(fileName))
{
File.Delete(fileName);
}
//把上传成功的文件,从ready移动到complete中
File.Move(entity.fi_full_name, fileName);
}
catch (Exception e1)
{
LogManager_Lock.WriteLog(e1.Message);
response_error error = new response_error(e1.Message);
on_http_notify2(JsonConvert.SerializeObject(error));
}
var url = get_url_from_server_response(entity, server_response);
//上传成功,更新数据库标志
new biz_db().update_upload_flag_by_id(entity.fi_id, 1, url);
new biz_db().update_file_name(entity.fi_id, fileName);
}
}
else if (eq.result.Status == -1)
{
return;
}
else
{
new biz_db().update_upload_flag_by_SN(eq.entity.fi_SN.Value, -1);
}
//socket发送结果
if (eq.upload_type == upload_type_enum.normal)
{
notify_nomral(eq);
}
else
{
notify_reUpload(eq);
}
}
catch (Exception ee)
{
LogManager_Lock.WriteLog(eq.result.Message);
response_error error = new response_error(ee.Message);
on_http_notify2(JsonConvert.SerializeObject(error));
}
}
private static string get_url_from_server_response(tb_file_info db_entity, entity_server_upload server_response)
{
string result = string.Empty;
try
{
var data = server_response.data.Where(x => x.Contains("_" + db_entity.fi_zipId + ".")).FirstOrDefault();
if (!string.IsNullOrEmpty(data))
{
result = data;
}
}
catch (Exception ee)
{
LogManager.WriteLog(ee.Message);
}
return result;
}
private static void notify_nomral(upf eq)
{
var entity = eq.entity;
var qty = new biz_db().get_upload_count_by_batchNumber(eq.entity.fi_batchSeq, eq.entity.fi_subjectCode);
var response1 = new response_uploadNumber() { number = qty.qty_success, batchNumber = eq.entity.fi_batchSeq };
//var response2 = new response_fainNumber() { number = qty.qty_fail, batchNumber = eq.entity.fi_batchSeq };
on_http_notify(eq);
on_http_notify2(JsonConvert.SerializeObject(response1));
//on_http_notify2(JsonConvert.SerializeObject(response2));
//if (queue.IsEmpty)
//{
// var response_finish = new response_uploadFinish() { subjectCode = entity.fi_subjectCode, batchNumber = entity.fi_batchSeq };
// var upload_count = new biz_db().get_upload_count_by_batchNumber(entity.fi_batchSeq, entity.fi_subjectCode);
// response_finish.scanNumber = new biz_db().get_count_by_batchNumber(entity.fi_batchSeq, entity.fi_subjectCode);
// response_finish.uploadNumber = upload_count.qty_success;
// response_finish.failedNumber = upload_count.qty_fail;
// on_http_notify2(JsonConvert.SerializeObject(response_finish));
//}
}
public static void notify_scan_finish()
{
Task.Run(() =>
{
if (config_environment.scan_type2 == ScanType.Formal)
{
while (!queue.IsEmpty)
{
Thread.Sleep(100);
}
var response_finish = new response_uploadFinish();
try
{
response_finish.subjectCode = config_environment.web_parameter.subjectCode;
response_finish.batchNumber = config_environment.web_parameter.batchNumber;
var upload_count = new biz_db().get_upload_count_by_batchNumber(config_environment.web_parameter.batchNumber, config_environment.web_parameter.subjectCode);
response_finish.scanNumber = new biz_db().get_count_by_batchNumber(config_environment.web_parameter.batchNumber, config_environment.web_parameter.subjectCode);
response_finish.uploadNumber = upload_count.qty_success;
response_finish.failedNumber = upload_count.qty_fail;
}
catch (Exception ee)
{
response_finish.code = 500;
response_finish.msg = ee.Message;
LogManager.WriteLog(ee.Message);
}
on_http_notify2(JsonConvert.SerializeObject(response_finish));
}
});
}
private static void notify_reUpload(upf eq)
{
var response1 = new response_reUpload_single_finish();
response1.fileIndex = get_ids_whenUpload(eq.entity.fi_SN);
response1.batchNumber = eq.entity.fi_batchSeq;
response1.subjectCode = eq.entity.fi_subjectCode;
if (eq.result.Status == 1 || eq.result.Status == -1 || eq.result.Status == 200)
{
response1.uploadState = 0;
}
else
{
response1.uploadState = 1;
}
on_http_notify2(JsonConvert.SerializeObject(response1));
if (queue.IsEmpty)
{
var response_finish = new response_reUpload_all_finish() { subjectCode = eq.entity.fi_subjectCode, batchNumber = eq.entity.fi_batchSeq, number = biz_reUpload.current_list.Count(x => x.fi_side == 1) };
string id_list = string.Empty;
foreach (var record in biz_reUpload.current_list)
{
id_list += "," + record.fi_id;
}
if (id_list.Length > 0)
{
id_list = id_list.Substring(1);
}
response_finish.failedNumber = new biz_db().get_not_upload_status(id_list);
on_http_notify(eq);
on_http_notify2(JsonConvert.SerializeObject(response_finish));
}
}
///
/// 单任务上传
///
///
///
///
///
//private ResponseEntity Upload_1(tb_file_info entity, ResponseEntity result, int seqNumber)
private ResponseEntity Upload_1(upf eq)
{
if (eq.entity != null)
{
if (eq.upload_type == upload_type_enum.normal && eq.result.Status == 1)
{
try
{
//根据实体获取json
var content = get_json(eq.entity);
eq.result = content.Item1;
if (eq.result.Status == 1)
{
//多线程上传防重复数据
if (!ready_list.Exists(x => x == eq.entity.fi_SN.Value))
{
ready_list.Add(eq.entity.fi_SN.Value);
eq.result = upload_try(eq, eq.result.Message, content.Item2);
}
}
else if (eq.result.Status == -1)
{
//双面的第一面,等待第二面到来再传
return eq.result;
}
}
catch (Exception ee)
{
eq.result.Status = 0;
eq.result.Message = ee.Message;
}
//biz_scanFinish.Work(eq.entity, eq.result);
}
else if (eq.upload_type == upload_type_enum.reUpload)
{
try
{
//根据实体获取json
var content = get_json(eq.entity);
eq.result = content.Item1;
if (eq.result.Status == 1)
{
eq.result = upload_try(eq, eq.result.Message, content.Item2);
}
else if (eq.result.Status == -1)
{
//双面的第一面,等待第二面到来再传
return eq.result;
}
else
{
var response3 = new response_reUpload_error()
{
batchNumber = eq.entity.fi_batchSeq,
subjectCode = eq.entity.fi_subjectCode,
code = 500,
msg = eq.result.Message,
};
on_http_notify2(JsonConvert.SerializeObject(response3));
}
}
catch (Exception ee)
{
eq.result.Status = 0;
eq.result.Message = ee.Message;
LogManager.WriteLog(ee.Message);
}
}
}
return eq.result;
}
private string get_seqNumbers_whenUpload(long? sn)
{
string result = "";
var list = new biz_db().get_by_sn(sn);
if (list[0].fi_schema != list.Count)
{
throw new Exception("Paper Schema does not match Paper Count");
}
foreach (var record in list)
{
result += "," + record.fi_zipId;
}
if (result.Length > 0)
{
result = result.Substring(1);
}
return result;
}
private static string get_ids_whenUpload(long? sn)
{
string result = "";
var list = new biz_db().get_by_sn(sn);
foreach (var record in list)
{
result += "," + record.fi_id;
}
if (result.Length > 0)
{
result = result.Substring(1);
}
return result;
}
///
/// 3次上传尝试
///
///
///
///
private ResponseEntity upload_try(upf eq, string json, List file_list)
{
var result = new ResponseEntity();
//////////
var entity = JsonConvert.DeserializeObject(json);
/////////
NameValueCollection param_list = new NameValueCollection();
//new
param_list.Add("seqNumbers", get_seqNumbers_whenUpload(eq.entity.fi_SN));
param_list.Add("paperSchema", eq.entity.fi_schema.ToString());
//new
//old
param_list.Add("seqNumber", eq.entity.fi_zipId.ToString());
param_list.Add("schema", eq.entity.fi_schema.ToString());
//old
param_list.Add("jsonParam", config_environment.web_parameter.jsonParam);
//修改为多线程上传
ThreadPool_manager.EnqueueTask(new Action(() =>
{
upload_thread(eq, param_list, file_list);
}));
result.Status = 1;
result.Message = "ok";
return result;
}
private void upload_thread(upf eq, NameValueCollection param_list, List file_list)
{
try
{
int try_count = 0;
Stopwatch sw = new Stopwatch();
while (try_count < 3)
{
try_count++;
sw.Restart();
eq.result = upload_try2(param_list, file_list);
sw.Stop();
write_operation_log(try_count, sw, file_list, eq.result);
if (eq.result.Status == 1)
{
break;
}
else
{
Thread.Sleep(100);
}
}
//lock (lockObj)
{
AfterUpload(eq);
}
}
catch (Exception ee)
{
LogManager_Lock.WriteLog(ee);
}
}
private void write_operation_log(int try_count, Stopwatch sw, List file_list, ResponseEntity result)
{
StringBuilder sb = new StringBuilder();
sb.Append("第" + try_count + "次上传" + Environment.NewLine);
sb.Append("服务器返回:" + result.Status + Environment.NewLine);
sb.Append("花费时间: " + sw.ElapsedMilliseconds + "ms" + Environment.NewLine + Environment.NewLine);
sb.Append("文件列表:" + Environment.NewLine);
foreach (var f in file_list)
{
sb.Append(f + Environment.NewLine);
}
LogManager_Lock.WriteLog(sb.ToString());
}
///
/// 具体上传逻辑
///
///
///
///
private ResponseEntity upload_try2(NameValueCollection param_list, List file_list)
{
ResponseEntity result = new ResponseEntity();
try
{
var response_string = http_helper.HttpUploadFile2(url_upload, file_list, "files", "multipart/form-data", config_environment.web_parameter.token, param_list);
try
{
result.Data = JsonConvert.DeserializeObject(response_string);
}
catch (Exception ee2)
{
if (ee2.Message.StartsWith("Unexpected character"))
{
result.Data = new response_http_uploadImg2() { code = 200 };
}
else
{
throw ee2;
}
}
result.Data.data_string = response_string;
if (result.Data.code == 200)
{
result.Status = 1;
result.Message = "ok";
}
else
{
result.Status = result.Data.code;
result.Message = result.Data.msg;
LogManager_Lock.WriteLog(response_string);
}
}
catch (Exception ee)
{
LogManager_Lock.WriteLog(ee);
if (ee.Message.Contains("未能解析此远程名称"))
{
on_net_broken();
}
else if (ee.Message.Contains("超时") || ee.Message.Contains("timeout"))
{
result.Status = -2;
result.Message = "http上传超时";
}
else
{
result.Status = 0;
result.Message = "http上传文件失败:" + ee.Message;
}
}
return result;
}
///
/// 根据实体获取json
///
///
///
///
private Tuple, List> get_json(tb_file_info entity)
{
ResponseEntity result_entity = new ResponseEntity();
List result_path = new List();
try
{
List file_list = new List();
//单面
if (entity.fi_schema == 1)
{
file_list.Add(entity);
}
//双面
else
{
file_list = new biz_db().get_by_sn(entity.fi_SN);
if (file_list.Count < 2)
{
var ss = entity.fi_side;
var ss2 = entity.fi_full_name;
result_entity.Status = -1;
result_entity.Message = "第1面,等待第2面再传";
return new Tuple, List>(result_entity, result_path);
}
if (file_list.Count(x => x.fi_upload_flag == 1) == file_list.Count)
{
result_entity.Status = -1;
result_entity.Message = "已全部上传";
return new Tuple, List>(result_entity, result_path);
}
}
if (file_list.Count == 1 || file_list.Count == 2)
{
bool flag = true;
foreach (var f in file_list)
{
if (!File.Exists(f.fi_full_name))
{
flag = false;
break;
}
}
if (flag)
{
var req = new request_http_uploadImg();
req.token = config_environment.web_parameter.token;
req.fileCount = file_list.Count;
req.isTest = file_list[0].fi_isTest;
req.fileMetaInfo = new List();
req.zipId = file_list[0].fi_zipId;
req.examId = file_list[0].fi_examId;
req.examPaperId = file_list[0].fi_examPaperId;
//req.seqNumber = file_list[0].fi_schema;
//req.seqNumber = file_manager.get_seqNumber();
//req.seqNumber = seqNumber;
req.schoolId = config_environment.web_parameter.schoolId;
req.accountId = file_list[0].fi_accountId.ToString();
//req.completedAmount = new biz_db().get_count_by_seq(config_environment.web_parameter.batchNumber, req.zipId);
req.completedAmount = new biz_db().get_count_by_seq(file_list[0].fi_batchSeq, req.zipId, config_environment.web_parameter.paperSchema);
//req.batchNumber = file_list[0].fi_batchNumber;
req.batchNumber = entity.fi_batchSeq;
req.schema = entity.fi_schema == null ? "1" : entity.fi_schema.ToString();
foreach (var f in file_list)
{
var sub = new subRequest_http_uploadImg();
sub.fileName = f.fi_name;
req.fileMetaInfo.Add(sub);
result_path.Add(f.fi_full_name);
}
result_entity.Status = 1;
result_entity.Message = JsonConvert.SerializeObject(req);
}
else
{
result_entity.Status = 0;
result_entity.Message = "未能找到用于上传的文件";
}
}
else
{
result_entity.Status = 0;
result_entity.Message = "db错误,未能找到用于上传的文件记录";
}
}
catch (Exception ee)
{
LogManager.WriteLog(ee);
result_entity.Status = 0;
result_entity.Message = ee.Message;
}
return new Tuple, List>(result_entity, result_path);
}
}
}