<신규개발>

(주요)작업내용 : 성적업로드 일괄업로드 추가
This commit is contained in:
devnet 2024-10-02 01:02:41 +00:00
parent 51379d349d
commit 65853d1e0a
13 changed files with 387 additions and 25 deletions

View File

@ -500,6 +500,7 @@
<Content Include="Content\file\YNICTEManualaxds.pdf" />
<Content Include="Content\file\documentspast.xlsx" />
<Content Include="libman.json" />
<Content Include="Content\file\gradeupload.xlsx" />
<None Include="Properties\PublishProfiles\FolderProfile.pubxml" />
<Content Include="js\Chart.utils.js" />
<Content Include="Spring\ControllersStaging.xml" />
@ -706,6 +707,7 @@
<Content Include="Views\Shared\Partial\ExcelCommentBox.cshtml" />
<Content Include="Views\croom\grade0_1.cshtml" />
<Content Include="Views\croom\gradeall0_1.cshtml" />
<Content Include="Views\croom\gradeupload.cshtml" />
</ItemGroup>
<ItemGroup>
<Folder Include="App_Data\" />

Binary file not shown.

View File

@ -863,8 +863,8 @@ namespace NP.BO.Controllers
if (vm.isexceldown == 1)
{
return ExportExcel(
new String[] { "No", "운영기수", "구분", "고객사", "교육장", "과정명", "시험명", "교육생", "ID", "핸드폰", "교육시작일", "교육종료일", "응시일자(제출일자)", "경과시간", "IP", "응시상태", "총점", "수료여부" },
new String[] { "rno", "sseq", "isrebatename", "asname", "studyplacename", "cname", "exname", "username", "userid", "mobile", "leststr", "leestrExcel", "estarteend", "eseterm", "eip", "estatename", "tpoint", "iscompletename" },
new String[] { "No", "운영기수", "구분", "고객사", "교육장", "과정명", "시험명", "교육생", "ID", "핸드폰", "교육시작일", "교육종료일", "응시일자(제출일자)", "경과시간", "IP", "응시상태", "총점", "수료여부", "점수종류" },
new String[] { "rno", "sseq", "isrebatename", "asname", "studyplacename", "cname", "exname", "username", "userid", "mobile", "leststr", "leestrExcel", "estarteend", "eseterm", "eip", "estatename", "tpoint", "iscompletename", "isbyadminname" },
vm.LectEXes,
"성적처리평가" + DateTime.Now.Year + DateTime.Now.Month + DateTime.Now.Day, null, null, vm.excellog);
}
@ -1472,6 +1472,10 @@ namespace NP.BO.Controllers
}
return View(vm);
}
}
public ActionResult gradeupload(VMCRoom vm)
{
return View(vm);
}
}
}

View File

@ -38,7 +38,7 @@
}
function setScd() {
capp("/acommon/GetScdForMixEdu", { cmno: selectedcmno }, "renderScd");
capp("/acommon/GetScdForMixEdu", { cmno: selectedcmno }, "renderScd", null, null , true);
}
function renderScd() {
var ulScd = $("#ulScd");

View File

@ -37,6 +37,7 @@
<th>총점</th>
<th>관리</th>
<th>수료여부</th>
<th>점수종류</th>
</tr>
</thead>
<tbody class="data" id="tbody1">
@ -98,6 +99,9 @@
{
<td class="@(d.iscomplete == 1 ? "link text-center" : "")">@Html.Raw(d.iscomplete == 1 ? string.Format("{1}", d.lectno, "수료") : d.iscompletename)</td>
}
<td>
@d.isbyadminname
</td>
</tr>
}
</tbody>
@ -115,7 +119,7 @@
</div>
</div>
<div id="thisbox" class="findbox draggable regbox" style="width: 800px; z-index: 1041; top: 60px; bottom: 30px; overflow: auto;">
<h4><i class="fa fa-bars"></i> <span id="pcap">시험 상세결과</span><a href="#" class="btn btn-default btn-xs f-r closethisbox" data-click="checkclose()">닫기</a></h4>
<h4><i class="fa fa-bars"></i> <span id="pcap">시험 상세결과</span><a href="#" class="btn btn-default btn-xs f-r" onclick="checkclose()">닫기</a></h4>
<br />
<h5><i class="fa fa-bars"></i> 개요</h5>
<table class="regtable" id="exsummary">
@ -146,10 +150,10 @@
</div>
<br /><br />
<div class="botfixempty">&nbsp;</div>
<div style="position: fixed; bottom: 30px; left: 200px; width: 800px; height: 50px; background-color: #fff; text-align: center;">
<div class="botfixbutton" style="bottom: 30px; left: 200px; width: 800px; height: 50px; background-color: #fff; text-align: center;">
<a href="#" id="btnpre" class="btn btn-info btn-xs" onclick="nextex(-1)">◀이전</a>
<a href="#" id="btnnext" class="btn btn-info btn-xs" onclick="nextex(1)">다음▶</a>
<a href="#" class="btn btn-default btn-xs closethisbox" data-click="checkclose()">닫기</a>
<a href="#" class="btn btn-default btn-xs" onclick="checkclose()">닫기</a>
</div>
</div>
<style type="text/css">
@ -243,7 +247,7 @@
_lectno = lectno;
_ridx = ridx;
$("#exdata tr").remove();
capp("/acommon/lectex", { lectno: lectno, exno: exno }, "cblectex");
capp("/acommon/lectex", { lectno: lectno, exno: exno }, "cblectex", null, null, true);
}
function cblectex() {
var lectex = capResult.obj.lectex;
@ -341,14 +345,16 @@
}
setTimeout(function () {
bglayer(); $("#thisbox").slideDown("fast", function () { $("#thisbox").scrollTop(0); });
bglayer(); $("#thisbox").slideDown("fast", function () { $("#thisbox").scrollTop(0); $("#thisbox .botfixbutton").css("position", "fixed"); });
bglayer2(false);
}, 10);
}
function checkclose() {
//191223.kfcf-req 점수변경시 페이지 갱신 안되도록 수정
self.close();
bglayer(false);
$("#thisbox .botfixbutton").css("position", "");
$("#thisbox").closest('.findbox').slideUp('fast', function () {
$('#bglayer').hide();
});
}
var _authtype = 1;

View File

@ -0,0 +1,147 @@
@model NP.Model.VMCRoom
@{
}
<form id="mform" method="post" enctype="multipart/form-data" class="form-horizontal">
<section class="panel panel-default" style="border-top: 1px solid #ddd; margin-top: 5px;">
<header class="panel-heading"><strong><i class="fa fa-bars"></i> 일괄등록 (시스템에 등록된 회원만 추가 가능합니다)<span class=""></span></strong></header>
<div class="panel-body">
<div class="form-group">
<label class="col-sm-4 col-md-2 control-label">성적 일괄등록</label>
<div class="col-sm-8 col-md-10">
<input id="uploadfile" type="file" /><br />
<a href="~/Content/file/gradeupload.xlsx" class="btn btn-info">양식다운로드</a>
<a href="#" class="btn btn-primary" onclick="checkfile();">파일검증</a>
</div>
</div>
<div class="text-right">
<a href="#" class="btn btn-danger" onclick="delall();">불량DATA 일괄삭제</a>
<a href="#" class="btn btn-primary" onclick="save();">등록</a>
</div>
</div>
<div class="table-responsive" id="excel2">
<table class="table table-striped b-t b-light">
<thead>
<tr>
<th width="20">No</th>
<th>주민등록번호</th>
<th>교육종료일</th>
<th>점수</th>
<th>교육생명</th>
<th>수강번호</th>
<th>강좌명</th>
<th>평가명</th>
<th>검증내역</th>
<th>삭제</th>
</tr>
</thead>
<tbody class="data" id="tbody"></tbody>
</table>
</div>
</section>
</form>
@section scriptsHeader{
<style type="text/css">
#layertable td {
padding: 2px 4px;
}
tbody th.cm {
padding: 0 10px;
}
tr.error {
color: red;
}
</style>
}
@section scripts{
<script src="~/js/moment.js"></script>
<script>
$(document).ready(function () {
$("#uploadfile").on("change", function () {
if ($(this).val() != "") {
$("#tbody tr").remove();
}
});
$("body").on("click", "#tbody tr td a.btn-danger", function () {
if (confirm("삭제하시겠습니까?")) {
$(this).closest("tr").remove();
}
});
});
function checkfile() {
if ($("#uploadfile").val() == "") {
msg2("파일을 선택해주세요.");
}
else {
var thumbext = $("#uploadfile").val();
thumbext = thumbext.slice(thumbext.indexOf(".") + 1).toLowerCase();
if ("xls,xlsx".indexOf(thumbext) < 0) {
msg("xls,xlsx 확장자만 가능합니다.", 0, true);
}
$("#tbody tr").remove();
var formData = new FormData();
formData.append("uploadfile", $("#uploadfile")[0].files[0]);
formData.append("uploadjob", "gradeuploadbatch");
capfile("/acommon/uploadexcel", formData, "cbcheckfile", true, false, true, true);
}
}
function cbcheckfile() {
if (capResult.code != 1000) {
msg2(capResult.msg);
}
else {
$.each(capResult.obj, function (i, d) {
$("#tbody").append("<tr data-userno=\"" + d.userno + "\" data-cmino=\"" + d.cmino + "\" data-lectno=\"" + d.lectno + "\" data-iscomplete=\"" + d.iscomplete + "\" data-cmno=\"" + d.cmno + "\" data-cname=\"" + d.cname + "\" data-exno=\"" + d.exno + "\" data-exname=\"" + d.exname + "\" data-tpoint=\"" + d.tpoint + "\" class=\"" + (d.value == "정상" ? "data" : "error") + "\">" +
"<td>" + d.rnorvt + "</td>" +
"<td>" + d.userpno + "</td>" +
"<td>" + moment(d.stime).format('YYYY-MM-DD') + "</td>" +
"<td>" + d.tpoint + "</td>" +
"<td>" + d.username + "</td>" +
"<td>" + zerotonull(d.lectno) + "</td>" +
"<td class=\"text-left\">" + d.cname + "</td>" +
"<td>" + d.exname + "</td>" +
"<td>" + d.value + "</td><td class=\"link text-center\"><a href=\"#\" class=\"btn-xxs btn btn-danger\">X</a></td></tr>");
});
}
}
function zerotonull(v) {
return v == 0 ? "" : v;
}
function delall() {
if (confirm("불량DATA를 일괄삭제하시겠습니까?")) {
$("#tbody tr.error").remove();
}
}
function save() {
if ($("#tbody tr.error").length > 0) {
msg("불량DATA가 있어 등록할 수 없습니다.");
}
else if ($("#tbody tr.data").length < 1) {
msg("등록할 데이터가 없습니다.");
}
else if (confirm("성적을 일괄 업로드하시겠습니까?")) {
var lectexs = [];
$.each($("#tbody tr.data"), function (i, r) {
lectexs.push($(r).data());
});
capp("/acommon/gradeuploadbatch", { lectexs: lectexs }, "cbsave");
}
}
function cbsave() {
if (capResult.code == 1000) {
if (capResult.obj > 0) {
msg("총 " + capResult.obj + "건 일괄 등록되었습니다.");
submit("mform", 500);
} else {
msg("일괄 등록된 건이 없습니다.");
submit("mform", 500);
}
} else if (capResult.code == 9999) {
msg(capResult.msg);
} else { msgdev(); }
}
</script>
}

View File

@ -1777,7 +1777,9 @@ $(document).ready(function () {
if (($(this).attr("data-click") || "") != "") {
eval($(this).attr("data-click"));
}
$(this).closest('.findbox').slideUp('fast'); $('#bglayer').hide();
$(this).closest('.findbox').slideUp('fast', function () {
$('#bglayer').hide();
});
}).on("change", ".filebox input.fileitem", function () {
var _ext = $(this).attr("data-ext").toUpperCase();
if ($(this).val() != "" && _ext != "*" && _ext != "") {

View File

@ -10,6 +10,9 @@ using NP.Base.Auth;
using NP.Base.ENUM;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using System.Reflection.Emit;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Information;
using Spring.Validation.Validators;
namespace NP.Base.Controllers
{
@ -1879,6 +1882,99 @@ namespace NP.Base.Controllers
return JsonOK(result);
}
//성적업로드검증
case "gradeuploadbatch":
{
var lects = new Lib.ExcelToEntity(uploadfile).Read<Lect>(2, 1).ToList();
if (lects.Count() < 1)
{
return JsonBack(new JsonRtn() { code = 1, msg = "데이터가 없습니다." });
}
else
{
int intLoop = 1;
int tot = lects.Count();
foreach (var lect in lects)
{
lect.rno = intLoop++;
lect.pagetotalcount = tot;
lect.value = ",정상";
lect.cname = string.Empty;
if (string.IsNullOrEmpty(lect.userpno) || lect.userpno == "-")
{
lect.value += ",주민번호오입력";
}
else
{
var users = Dao.Get<Users>("users.users", new Hashtable() { { "usertype", 1 }, { "status", 1 }, { "userpno", lect.userpno.Replace("-", "") } });
if (users.Count == 1)
{
var user = users.First();
lect.userno = user.userno;
lect.userid = user.userid;
lect.username = user.username;
}
else
{
lect.value += ",교육생불일치";
}
}
if (lect.stime == null)
{
lect.value += ",교육종료일오입력";
}
else if (lect.userno == 0)
{
lect.value += ",강좌불일치";
}
else
{
var lectexs = Dao.Get<LectEX>("lect.lectex.forgradeupload", new Hashtable() { { "userno", lect.userno }, { "stime", lect.stime } });
if (lectexs.Count == 1)
{
var lectex = lectexs.First();
if (lectex.tpoint < lect.tpoint)
{
lect.value += ",평가점수오입력(초과)";
}
else
{
lect.cmno = lectex.cmno;
lect.cname = lectex.cname;
lect.lectno = lectex.lectno;
lect.cmino = lectex.cmino;
lect.iscomplete = lectex.iscomplete;
lect.exno = lectex.exno;
lect.exname = lectex.exname;
}
}
else
{
lect.value += ",강좌불일치";
}
}
if (lect.tpoint < 0 || lect.tpoint > 100)
{
lect.value += ",평가점수오입력";
}
lect.value = lect.value.Substring(1);
if (!lect.value.Equals("정상"))
{
if (lect.value.Contains("정상"))
{
lect.value = lect.value.Replace("정상,", "");
}
lect.value += " 오류";
}
}
}
return JsonBack(new JsonRtn() { code = 1000, obj = lects });
}
}
}
}

View File

@ -12,6 +12,7 @@ using NP.Base.ENUM;
using System.Net.Http;
using XPayClientNet;
using NP.Base.Popbill;
using IBatisNet.DataMapper.Configuration.ResultMapping;
namespace NP.Base.Controllers
{
@ -2043,5 +2044,27 @@ namespace NP.Base.Controllers
}
return JsonOK(Dao.Save("pay.taxcancel", new Hashtable() { { "taxnos", taxnos }, { "taxno", taxno }, { "uno", SUserInfo.UserNo }, { "uip", GetUserIP() } }));
}
/// <summary>
/// 성적업로드
/// </summary>
/// <param name="lects">수강</param>
/// <returns></returns>
[HttpPost]
public JsonResult GradeUploadBatch(IList<LectEX> lectexs)
{
var result = 0;
foreach (var lectex in lectexs)
{
var lectexsNow = Dao.Get<LectEX>("lect.lectex.forgradeupload", new Hashtable() { { "userno", lectex.userno }, { "lectno", lectex.lectno } });
if (lectexsNow.Count == 1 && lectexsNow.First().tpoint >= lectex.tpoint)
{
lectex.uno = SUserInfo.UserNo;
lectex.uip = GetUserIP();
result += Dao.Save("lect.lectex.point.byadmin", lectex) > 0 ? 1 : 0;
}
}
return JsonOK(result, true);
}
}
}

View File

@ -146,8 +146,29 @@ namespace NP.Base.Lib
try
{
property.SetValue(entity, v.GetType() == property.PropertyType ? v :
Convert.ChangeType(row[propName], property.PropertyType));
if (v.GetType() == property.PropertyType)
{
property.SetValue(entity, v);
}
else
{
if (property.PropertyType == typeof(DateTime?))
{
if (DateTime.TryParse(row[propName].ToString(), out DateTime dt))
{
property.SetValue(entity, dt);
}
else
{
property.SetValue(entity, null);
}
}
else
{
var propertyType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
property.SetValue(entity, Convert.ChangeType(row[propName], propertyType));
}
}
}
catch (Exception)
{

View File

@ -1842,5 +1842,6 @@
( l.completetime is null and li.stime is not null
and l.sdate &lt; '2024-08-19 00:00:00' and li.stime is not null and li.stime &lt; '2024-08-22 00:00:00'))
</select>
</statements>
</sqlMap>

View File

@ -1072,7 +1072,7 @@
,p.payoktime,a.sdate,a.edate
,b.exno,b.exname,b.extype <!--#xodus 수정완료 성적처리관련 컬럼 추가-->
,b2.cshape,b2.cname
,c.estart,c.eend,c.eip,c.tpoint,c.recount,c.entercount,c.cblock
,c.estart,c.eend,c.eip,c.tpoint,c.recount,c.entercount,c.cblock,c.isbyadmin
,d.username,d.userid
,e.asname
,f.cmisno,f.estart lestart,f.eend leend,f.sseq
@ -1147,7 +1147,7 @@
from lectex a
where a.lectno=#lectno# and a.exno=#exno#;
update lectex set estart=null,eend=null,eip=null,tpoint=0,recount=recount+1,entercount=0,cblock=0 where lectno=#lectno# and exno=#exno#;
update lectex set estart=null,eend=null,eip=null,tpoint=0,recount=recount+1,entercount=0,cblock=0,isbyadmin=0 where lectno=#lectno# and exno=#exno#;
update lectexq a
inner join cmex b on b.exno=a.exno <!--and b.eqtype=0-->
@ -2704,7 +2704,44 @@
LEFT OUTER JOIN lectinning g ON g.cmino = ci.cmino AND g.lectno = l.lectno
WHERE l.lectno in ($lectnos$)
</select>
<select id="lect.lectex.forgradeupload" parameterClass="hashtable" resultClass="lectex">
select a.cmino, b.lectno, ifnull(b.iscomplete,0) as iscomplete, c.cmno, c.cname, e.exno, e.exname, e.tpoint
from lectinning a
inner join lect b on b.lectno = a.lectno and b.status = 1 and b.ischanged = 0
inner join cm c on c.cmno = b.cmno and c.cshape = 2 and c.isdel = 0
inner join cminning d on d.cmno = b.cmno and d.cmino = a.cmino and d.isscd = 1
inner join cmex e on e.cmno = b.cmno and e.extype = 1 and e.isdel = 0
where a.istatus = 2
<isNotNull property="lectno">and a.lectno = #lectno#</isNotNull>
<isNotNull property="stime">and cast(a.stime as date) = #stime#</isNotNull>
and b.userno = #userno#;
</select>
<update id="lect.lectex.point.byadmin" parameterClass="lectex" >
<include refid="lectexcreate"></include>
update lectex
set <include refid="sql.up"></include>
,tpoint=#tpoint#
,isbyadmin=1
where lectno=#lectno# and exno=#exno#;
update lect l
inner join (
select l.lectno, round(avg(le.tpoint),1) as avgtpoint, sum(le.tpoint) sumpoint, ce.tpoint
from lect l
inner join cmex ce on l.cmno = ce.cmno and ce.extype = 1 and ce.isdel = 0
left outer join lectex le on l.lectno = le.lectno and ce.exno = le.exno
where l.status = 1 and l.lectno = #lectno#
group by l.lectno
)t on l.lectno = t.lectno
inner join cmev cv on l.cmno = cv.cmno
set l.exfpoint = t.avgtpoint
, l.fpoint = round((t.avgtpoint / t.tpoint * 100) * cv.final / 100,1)
, l.udt = now()
, l.uno = #uno#
, l.uip=#uip#
where l.lectno = #lectno#;
</update>
</statements>
</sqlMap>

View File

@ -1447,7 +1447,7 @@ namespace NP.Model
}
}
public int? cmino { get; set; }
public Int64? cmino { get; set; }
public int ischeck { get; set; }
public String completeno { get; set; }
public String post { get; set; }
@ -1510,7 +1510,18 @@ namespace NP.Model
public String rbank { get; set; }
public String btype { get; set; }
public String eino { get; set; }
/// <summary>
/// 주민등록번호
/// </summary>
public String userpno { get; set; }
/// <summary>
/// 시험키
/// </summary>
public int exno { get; set; }
/// <summary>
/// 시험명
/// </summary>
public String exname { get; set; }
}
/// <summary>
/// 자격검정시험
@ -3667,6 +3678,18 @@ namespace NP.Model
}
}
public int ispass { get; set; }
public Int64? cmino { get; set; }
/// <summary>
/// 관리자등록여부
/// </summary>
public int isbyadmin { get; set; }
public string isbyadminname
{
get
{
return isbyadmin == 1 ? "관리자등록" : "수강생응시";
}
}
}
[Serializable]
public class LectEXQ : LectEX