#region 分配考場邏輯
/// <summary>
/// wjc
/// 2015-4-3 16:53:57
/// 分配考場邏輯
/// 需要注意的有3點:1.考場機位數不夠怎么辦? 機位數不夠不能分配考場,退出程序并提示用戶
/// 2.同一個考場同一時間可以考多個科目,目的是節約場次
/// 3.同一個學生考試時間不能沖突,即同一個學生,不能在同一時間內既考語文又考數學
/// </summary>
/// <param name="examId"></param>
/// <returns></returns>
object startGive(string examId)
{
string institutionId = jc.User.Info.Prop1;
int count = (from q in ExamInstution.CreateContext()
where q.InstitutionId == institutionId && q.ExamId == examId
select q).Count();
if (count > 0)
{
return new { code = -1, msg = "考場已經提交,不能分配考場,若要重新分配考場,請聯系省校教務處!" };
}
ReserveExam exam = ReserveExam.Get(examId);
if (exam == null)
{
return new { code = -1, msg = "考試不存在,分配考場失敗,請刷新頁面重試" };
}
//獲取考試-學生-科目關聯
List<ReserveStuExam> stuExamList = (from q in ReserveStuExam.CreateContext()
where q.ExamId == examId && q.InstitutionId == institutionId
orderby q.CourseId descending
select q).ToList();
if (stuExamList.Count == 0)
{
return new { code = -2, msg = "還沒有學生參加考試無法分配考場" };
}
//獲取所有的考場輪次
List<ExamPlaceRound> placeRoundList = (from q in ExamPlaceRound.CreateContext()
where q.ExamId == examId && q.InstitutionId == institutionId
select q).ToList();
List<ExamPlace> placeList = (from q in ExamPlace.CreateContext()
where q.ExamId == examId && q.InstitutionId == institutionId
select q).ToList();
List<ExamRound> roundList = (from q in ExamRound.CreateContext()
where q.ExamId == examId && q.InstitutionId == institutionId
select q).ToList();
if (placeRoundList.Count == 0)
{
return new { code = -3, msg = "還沒有設置考場輪次,無法分配考場" };
}
//判斷考場夠不夠用,若不夠用,直接返回
int studentCourseCount = stuExamList.Count();
int roundCount = getPlaceRoundCount(examId);//機位數
if (stuExamList.Count > roundCount)//備用機位和考場分配沒有牽連
{
return new { code = -4, msg = "考場場次不夠,無法分配考場" };
}
//從這里開始分配考場
//需要注意的是,考場的一個輪次同時可以考多個科目,目的是節約場次,所以不用對科目進行限制
ILinqContext<StuPlace> cx = StuPlace.CreateContext();
bool flag = false;//分配考場結束標記
List<ReserveStuExam> stuexam_list = new List<ReserveStuExam>();//該list用于批量更新考場分配狀態
foreach (ExamPlaceRound placeRound in placeRoundList)
{
if (flag) { break; }
string placeId = placeRound.PlaceId;
string roundId = placeRound.RoundId;
ExamPlace place = (from q in placeList where q.Id == placeId select q).FirstOrDefault();
if (place == null)
{
return new { code = -6, msg = "考場不存在,分配考場失敗" };
}
ExamRound examRound = (from q in roundList where q.Id == roundId select q).FirstOrDefault();
if (examRound == null)
{
return new { code = -7, msg = "考場輪次不存在,分配考場失敗" };
}
int placeCount = place.PlaceCount;
for (int i = 0; i < placeCount; i++)
{
if (stuExamList.Count == 0)
{
flag = true;
break;
}
//這里取考場輪次不會重復的學生,如果不存在,直接退出本次循環
List<ReserveStuExam> roundStuList = (from q in stuExamList
where string.IsNullOrEmpty(q.RoundIds) || !q.RoundIds.Contains(roundId)
select q).ToList();
if (roundStuList.Count == 0)
{
break;
}
ReserveStuExam stuExam = roundStuList[0];
stuexam_list.Add(stuExam);
//插入考場分配表中去
StuPlace stuPlace = new StuPlace();
stuPlace.Id = StringUtil.UniqueId();
stuPlace.CourseId = stuExam.CourseId;
stuPlace.CreatorId = jc.User.Info.Id;
stuPlace.DateCreated = DateTime.Now;
stuPlace.StartTime = examRound.StartTime;
stuPlace.EndTime = examRound.EndTime;
stuPlace.UserId = stuExam.UserId;
stuPlace.RoundId = examRound.Id;
stuPlace.ExamId = examId;
stuPlace.PlaceId = place.Id;
stuPlace.InstitutionId = stuExam.InstitutionId;
stuPlace.SeatNumber = i + 1;
cx.Add(stuPlace, true);
stuExamList.Remove(stuExam);//將分配好的學生從列表中刪除
//更新stuexamlist,這里并沒有訪問數據庫,只是標記某些學生在該輪次中不能再被分配考場
updateStuExamList(stuExamList, stuExam.UserId, examRound.Id);
}
}
if (stuExamList.Count > 0)
{
return new { code = -9, msg = "考場場次不足,考場分配失敗,請增加考場場次后再重新分配" };
}
//插入數據前,先刪除歷史數據
StuPlace.Where("examid={0}", examId).Delete();
cx.SubmitChanges();
//更新學生科目關聯表,更新考場分配狀態
updateReplaceState(stuexam_list);
return new { code = 1, msg = "分配考場成功" };
}
void updateStuExamList(List<ReserveStuExam> stuExamList, string userId, string roundId)
{
List<ReserveStuExam> reserveList = (from q in stuExamList where q.UserId == userId select q).ToList();
foreach (ReserveStuExam stuExam in reserveList)
{
stuExam.RoundIds += roundId + ",";
}
}
/// <summary>
/// wjc
/// 2015-4-7 14:36:37
/// 更新考場分配狀態
/// </summary>
void updateReplaceState(List<ReserveStuExam> list)
{
Array ids = (from q in list select q.Id).ToArray();
string formatIds = StringUtil.CollectionToCommaDelimitedString(ids, "'");
ReserveStuExam.Where("id in ({0})", formatIds).Set("HaveRoom", true).Update();
}
/// <summary>
/// wjc
/// 2015-4-9 17:32:18
/// 獲取考場輪次所有的機位數
/// </summary>
/// <param name="examid"></param>
/// <returns></returns>
public int getPlaceRoundCount(string examId)
{
string institutionId = jc.User.Info.Prop1;
List<ExamPlace> placeList = (from q in ExamPlace.CreateContext()
where q.InstitutionId == institutionId && q.ExamId == examId
select q).ToList();
List<ExamPlaceRound> roundList = (from q in ExamPlaceRound.CreateContext()
where q.InstitutionId == institutionId && q.ExamId == examId
select q).ToList();
int count = 0;
foreach (ExamPlace place in placeList)
{
int roundCount = (from q in roundList where q.PlaceId == place.Id select q).Count();
count += roundCount * place.PlaceCount;
}
return count;
}
#endregion
#region
導出考場編排情況
///
<summary>
///
wjc
///
導出考場分配情況,將一次性導出整個教學點本次考試的考場編排情況
///
2015-4-9 10:05:29
///
具體邏輯:
///
①系統生成多個excel
///
②將多個excel文件保存到temp文件夾里面去
///
③壓縮temp文件夾,并導出出來
///
</summary>
///
<param name="nv"></param>
///
<returns></returns>
object
startExportPlace(NameValueCollection nv)
{
string
examId = nv[
"
examId
"
];
string
institutionId =
jc.User.Info.Prop1;
List
<StuPlace> stuPlaceList = (
from
q
in
StuPlace.CreateContext()
where
q.InstitutionId == institutionId && q.ExamId ==
examId
select
q).ToList();
if
(stuPlaceList.Count ==
0
)
{
return
new
{ code = -
1
, msg =
"
考場未分配,不能導出考場編排情況。
"
};
}
try
{
createXlsToFolder(stuPlaceList, examId);
comprssXlsFoler();
}
catch
(Exception ex)
{
logger.Error(
"
導出考場編排情況失敗,失敗原因
"
+
ex.Message);
return
new
{ code = -
1
, msg =
"
導出考場編排情況失敗
"
};
}
string
filePath = ServerUtil.MapPath(StringUtil.urldecode(jc.url(
string
.Format(
"
/downmodel/考場編排結果.zip
"
))));
string
fileName =
"
考場編排結果.zip
"
;
//
客戶端保存的文件名
var
file =
new
FileInfo(filePath);
//
得到文件
if
(file.Exists)
//
判斷文件是否存在
{
jc.Context.Response.Clear();
//
清空Response對象
/*
設置瀏覽器請求頭信息
*/
jc.Context.Response.AddHeader(
"
Content-Disposition
"
,
"
attachment;filename=
"
+ HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));
//
指定文件
jc.Context.Response.AddHeader(
"
Content-Length
"
, file.Length.ToString());
//
指定文件大小
jc.Context.Response.ContentType =
"
application/application/octet-stream
"
;
//
指定輸出方式
jc.Context.Response.WriteFile(file.FullName);
//
寫出文件
jc.Context.Response.Flush();
//
輸出緩沖區(刷新Response對象)
jc.Context.Response.Clear();
//
清空Response對象
File.Delete(filePath);
//
刪除壓縮包文件
jc.Context.Response.End();
//
結束Response對象
}
return
new
{ code =
1
, msg =
"
下載成功
"
};
}
///
<summary>
///
wjc
///
2015-4-13 9:27:07
///
生成excel到temp文件夾
///
</summary>
///
<param name="stuPlaceList"></param>
///
<param name="examId"></param>
void
createXlsToFolder(List<StuPlace> stuPlaceList,
string
examId)
{
var
roundList = (
from
q
in
stuPlaceList
select
new
{ roundId = q.RoundId, placeId =
q.PlaceId }).ToList().Distinct().ToList();
string
institutionId =
jc.User.Info.Prop1;
//
TODO這里是增量,后期可能會很大,最好的解決辦法是再關聯表中加學生姓名
List<ReserveStu> stuList = (
from
q
in
ReserveStu.CreateContext()
where
q.InstitutionId ==
institutionId
select
q).ToList();
List
<ExamPlace> placeList = (
from
q
in
ExamPlace.CreateContext()
where
q.ExamId == examId && q.InstitutionId ==
institutionId
select
q).ToList();
List
<ReserveCourseExam> courseList = (
from
q
in
ReserveCourseExam.CreateContext()
//
where q.ExamId == examId TODO這個是需要的,因為select2有bug所以暫時注釋
select
q).ToList();
//
為壓縮文件準備的temp文件夾,壓縮成功后將刪除
string
tempFolderName = ServerUtil.MapPath(StringUtil.urldecode(jc.url(
"
/downmodel/stuplace_temp
"
)));
if
(!
Directory.Exists(tempFolderName))
{
Directory.CreateDirectory(tempFolderName);
}
foreach
(
var
roundPlace
in
roundList)
{
List
<StuPlace> stuplace_list = (
from
q
in
stuPlaceList
where
q.RoundId == roundPlace.roundId && q.PlaceId ==
roundPlace.placeId
orderby
q.SeatNumber ascending
select
q).ToList();
if
(stuplace_list.Count ==
0
)
{
continue
; }
string
startTime = stuplace_list[
0
].StartTime.ToString();
string
endTime = stuplace_list[
0
].EndTime.ToString();
string
placeName = (
from
q
in
placeList
where
q.Id ==
roundPlace.placeId
select
q.Name).FirstOrDefault();
string
xlsPath = ServerUtil.MapPath(StringUtil.urldecode(jc.url(
"
/downmodel/導出考場編排模板.xls
"
)));
FileStream file
=
new
FileStream(xlsPath, FileMode.Open, FileAccess.ReadWrite);
HSSFWorkbook book
=
new
HSSFWorkbook(file);
HSSFSheet sheet
= (HSSFSheet)book.GetSheetAt(
0
);
sheet.GetRow(
0
).GetCell(
0
).SetCellValue(
"
考試時間:
"
+ startTime +
"
~
"
+
endTime);
//
這里需要注意的是第一行為簽到單的頭部,第二行為簽到單的列名稱,第三行才是真正有價值的信息
for
(
int
i =
0
; i < stuplace_list.Count; i++
)
{
StuPlace sp
=
stuplace_list[i];
string
studentId =
sp.UserId;
ReserveStu stu
= (
from
q
in
stuList
where
q.Id == studentId
select
q).FirstOrDefault();
string
courseId =
sp.CourseId;
string
courseName = (
from
q
in
courseList
where
q.Id == courseId
select
q.CourseName).FirstOrDefault();
if
(stu ==
null
) {
continue
; }
//
理論上不會存在這種情況
string
stuName =
stu.DisplayName;
string
stuNum =
stu.LicenseNumber;
string
seatNum =
sp.SeatNumber.ToString();
sheet.CreateRow(i
+
2
);
sheet.GetRow(i
+
2
).CreateCell(
0
);
sheet.GetRow(i
+
2
).CreateCell(
1
);
sheet.GetRow(i
+
2
).CreateCell(
2
);
sheet.GetRow(i
+
2
).CreateCell(
3
);
sheet.GetRow(i
+
2
).GetCell(
0
).SetCellValue(stuName);
sheet.GetRow(i
+
2
).GetCell(
1
).SetCellValue(stuNum);
sheet.GetRow(i
+
2
).GetCell(
2
).SetCellValue(seatNum);
sheet.GetRow(i
+
2
).GetCell(
3
).SetCellValue(courseName);
}
string
startPlaceTime = stuplace_list[
0
].StartTime.ToString(
"
yyyyMMddHHmmss
"
);;
string
endPlaceTime = stuplace_list[
0
].EndTime.ToString(
"
yyyyMMddHHmmss
"
);;
string
xlsName = placeName + startPlaceTime +
endPlaceTime;
string
saveXlsPath = ServerUtil.MapPath(StringUtil.urldecode(jc.url(
string
.Format(
"
/downmodel/stuplace_temp/{0}.xls
"
, xlsName))));
FileStream saveXlsStream
=
new
FileStream(saveXlsPath, FileMode.Create);
book.Write(saveXlsStream);
file.Close();
saveXlsStream.Close();
}
}
///
<summary>
///
wjc
///
2015-4-10 9:08:43
///
壓縮excel所在的文件夾
///
</summary>
void
comprssXlsFoler()
{
string
dirPath = ServerUtil.MapPath(StringUtil.urldecode(jc.url(
"
/downmodel/stuplace_temp
"
)));
string
zipName = ServerUtil.MapPath(StringUtil.urldecode(jc.url(
string
.Format(
"
/downmodel/考場編排結果.zip
"
))));
using
(ZipOutputStream zipOutPutStream =
new
ZipOutputStream(File.Create(zipName)))
{
zipOutPutStream.SetLevel(
5
);
Crc32 crc
=
new
Crc32();
Dictionary
<
string
, DateTime> fileList =
GetAllFies(dirPath);
foreach
(KeyValuePair<
string
, DateTime> item
in
fileList)
{
FileStream fs
=
File.OpenRead(item.Key.ToString());
byte
[] buffer =
new
byte
[fs.Length];
fs.Read(buffer,
0
, buffer.Length);
ZipEntry entry
=
new
ZipEntry(item.Key.Substring(dirPath.Length));
entry.DateTime
=
item.Value;
entry.Size
=
fs.Length;
fs.Close();
crc.Reset();
crc.Update(buffer);
entry.Crc
=
crc.Value;
zipOutPutStream.PutNextEntry(entry);
zipOutPutStream.Write(buffer,
0
, buffer.Length);
}
Directory.Delete(dirPath,
true
);
//
文件壓縮成功后,刪除temp文件夾
}
}
///
<summary>
///
wjc
///
獲取文件下所有文件
///
2015-4-13 9:22:29
///
</summary>
///
<param name="dir"></param>
///
<returns></returns>
Dictionary<
string
, DateTime> GetAllFies(
string
dir)
{
Dictionary
<
string
, DateTime> filesList =
new
Dictionary<
string
, DateTime>
();
DirectoryInfo fileDire
=
new
DirectoryInfo(dir);
if
(!
fileDire.Exists)
{
throw
new
System.IO.FileNotFoundException(
"
目錄:
"
+ fileDire.FullName +
"
沒有找到!
"
);
}
foreach
(FileInfo file
in
fileDire.GetFiles(
"
*.*
"
))
{
filesList.Add(file.FullName, file.LastWriteTime);
}
return
filesList;
}
#endregion
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

