@@ -1,4 +1,4 @@ | |||||
function GetQueryString(name) { | |||||
function GetQueryString(name) { | |||||
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); | var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); | ||||
var r = window.location.search.substr(1).match(reg);//search,查询?后面的参数,并匹配正则 | var r = window.location.search.substr(1).match(reg);//search,查询?后面的参数,并匹配正则 | ||||
if (r != null) return unescape(r[2]); return null; | if (r != null) return unescape(r[2]); return null; | ||||
@@ -665,7 +665,7 @@ namespace Learun.Application.Web.Areas.EducationalAdministration.Controllers | |||||
FinaChargesStandardList = FinaChargesStandardList, | FinaChargesStandardList = FinaChargesStandardList, | ||||
StuInfoFreshFamilyList = stuInfoFreshFamily, | StuInfoFreshFamilyList = stuInfoFreshFamily, | ||||
PayFeeTotal = PayFeeTotal, | PayFeeTotal = PayFeeTotal, | ||||
YJAmount = FeeOrderList.Sum(x => x.SJAmount) | |||||
YJAmount = FinaChargesStandardList.Sum(x => x.PayedMoney) | |||||
}; | }; | ||||
return Success(jsonData); | return Success(jsonData); | ||||
} | } | ||||
@@ -1321,9 +1321,6 @@ namespace Learun.Application.Web.Areas.EducationalAdministration.Controllers | |||||
if (!string.IsNullOrEmpty(imgUrl)) | if (!string.IsNullOrEmpty(imgUrl)) | ||||
{ | { | ||||
// model.PayFeeDetail = entity.PayFeeDetail; | |||||
// model.PayMoney = entity.PayMoney; | |||||
model.LoanMoney = entity.LoanMoney; | |||||
model.orderid = orderid; | model.orderid = orderid; | ||||
stuInfoFreshIBLL.SaveFeeData(keyValue, model, list); | stuInfoFreshIBLL.SaveFeeData(keyValue, model, list); | ||||
} | } | ||||
@@ -115,6 +115,7 @@ var bootstrap = function ($, learun) { | |||||
var detail = ""; | var detail = ""; | ||||
var ifisnull = false; | var ifisnull = false; | ||||
$('.paydetail').each(function (i, item) { | $('.paydetail').each(function (i, item) { | ||||
$(this).attr('disabled', 'disabled'); | |||||
var value = 0; | var value = 0; | ||||
if (!!$(this).val()) { | if (!!$(this).val()) { | ||||
value = parseFloat($(this).val()); | value = parseFloat($(this).val()); | ||||
@@ -142,8 +143,6 @@ var bootstrap = function ($, learun) { | |||||
param.PayMoney = $('#PayMoney').html(); | param.PayMoney = $('#PayMoney').html(); | ||||
learun.loading(true, '正在生成付款信息请稍等...'); | learun.loading(true, '正在生成付款信息请稍等...'); | ||||
$("#confirmPayFee").hide(); | $("#confirmPayFee").hide(); | ||||
console.log(JSON.stringify(param)); | |||||
console.log(JSON.stringify(list)); | |||||
learun.httpAsyncPost(top.$.rootUrl + '/EducationalAdministration/StuInfoBasic_PayFee/PayFeeQRCode?keyValue=' + keyValue, { strEntity: JSON.stringify(param), detailList: JSON.stringify(list) }, function (res) { | learun.httpAsyncPost(top.$.rootUrl + '/EducationalAdministration/StuInfoBasic_PayFee/PayFeeQRCode?keyValue=' + keyValue, { strEntity: JSON.stringify(param), detailList: JSON.stringify(list) }, function (res) { | ||||
learun.loading(false); | learun.loading(false); | ||||
$('#qrcodeImg').attr('src', res.info); | $('#qrcodeImg').attr('src', res.info); | ||||
@@ -52,7 +52,7 @@ var bootstrap = function ($, learun) { | |||||
title: '二维码缴费', | title: '二维码缴费', | ||||
url: top.$.rootUrl + '/EducationalAdministration/StuInfoBasic_PayFee/PayFeeForm?keyValue=' + keyValue, | url: top.$.rootUrl + '/EducationalAdministration/StuInfoBasic_PayFee/PayFeeForm?keyValue=' + keyValue, | ||||
width: 800, | width: 800, | ||||
height: 650, | |||||
height: 690, | |||||
btn: null | btn: null | ||||
}); | }); | ||||
} | } | ||||
@@ -108,7 +108,7 @@ var bootstrap = function ($, learun) { | |||||
{ | { | ||||
label: "性别", name: "GenderNo", width: 80, align: "left", | label: "性别", name: "GenderNo", width: 80, align: "left", | ||||
formatter: function (cellvalue) { | formatter: function (cellvalue) { | ||||
return cellvalue == true ? "男" : "女"; | |||||
return cellvalue === true ? "男" : "女"; | |||||
} | } | ||||
}, | }, | ||||
{ label: "身份证号", name: "IdentityCardNo", width: 150, align: "left" }, | { label: "身份证号", name: "IdentityCardNo", width: 150, align: "left" }, | ||||
@@ -102,7 +102,7 @@ var bootstrap = function ($, learun) { | |||||
$.each(data['FinaChargesStandardList'], function (i, item) { | $.each(data['FinaChargesStandardList'], function (i, item) { | ||||
html += '<tr><td class=\"tableLeft\">' + item.ChargeItemName + '</td><td>' + item.Standard + '元</td><td><input id="' + item.ChargeItemCode + '" data-amount="' + item.Standard + '" data-name="' + item.ChargeItemName + '" type="number" class="form-control paydetail" value="' + item.SJAmount + '" /></td></tr>'; | html += '<tr><td class=\"tableLeft\">' + item.ChargeItemName + '</td><td>' + item.Standard + '元</td><td><input id="' + item.ChargeItemCode + '" data-amount="' + item.Standard + '" data-name="' + item.ChargeItemName + '" type="number" class="form-control paydetail" value="' + item.SJAmount + '" /></td></tr>'; | ||||
}); | }); | ||||
html += '<tr><td class=\"tableLeft\">应缴合计</td><td>' + data['PayFeeTotal'] + '元</td><td><span id="PayMoney"></span></td></tr>'; | |||||
html += '<tr><td class=\"tableLeft\">应缴合计</td><td>' + data['PayFeeTotal'] + '元</td><td><span id="PayMoney">' + PayFeeTotal+'</span></td></tr>'; | |||||
html += '<tr><td class=\"tableLeft\"> </td><td colspan="2"> </td></tr>'; | html += '<tr><td class=\"tableLeft\"> </td><td colspan="2"> </td></tr>'; | ||||
html += '<tr><td class=\"tableLeft\">已缴金额</td><td colspan="2">' + YJAmount + '</td></tr>'; | html += '<tr><td class=\"tableLeft\">已缴金额</td><td colspan="2">' + YJAmount + '</td></tr>'; | ||||
$('#PayFeeDetail').html(html); | $('#PayFeeDetail').html(html); | ||||
@@ -114,6 +114,7 @@ var bootstrap = function ($, learun) { | |||||
var detail = ""; | var detail = ""; | ||||
var ifisnull = false; | var ifisnull = false; | ||||
$('.paydetail').each(function (i, item) { | $('.paydetail').each(function (i, item) { | ||||
$(this).attr('disabled', 'disabled'); | |||||
var value = 0; | var value = 0; | ||||
if (!!$(this).val()) { | if (!!$(this).val()) { | ||||
value = parseFloat($(this).val()); | value = parseFloat($(this).val()); | ||||
@@ -53,7 +53,7 @@ var bootstrap = function ($, learun) { | |||||
title: '二维码缴费', | title: '二维码缴费', | ||||
url: top.$.rootUrl + '/EducationalAdministration/StuInfoFresh/PayFeeForm?keyValue=' + keyValue, | url: top.$.rootUrl + '/EducationalAdministration/StuInfoFresh/PayFeeForm?keyValue=' + keyValue, | ||||
width: 800, | width: 800, | ||||
height: 650, | |||||
height: 690, | |||||
btn: null | btn: null | ||||
}); | }); | ||||
} | } | ||||
@@ -302,8 +302,14 @@ var bootstrap = function ($, learun) { | |||||
{ label: '学号', name: 'StuNo', width: 100, align: "left" }, | { label: '学号', name: 'StuNo', width: 100, align: "left" }, | ||||
{ label: '姓名', name: 'StuName', width: 100, align: "left" }, | { label: '姓名', name: 'StuName', width: 100, align: "left" }, | ||||
{ | { | ||||
label: '线上缴费状态', name: 'PayFeeStatus', width: 100, align: "left", formatter: function (value) { | |||||
return value == 1 ? "<span class=\"label label-success\">已缴费</span>" : "<span class=\"label label-warning\">未缴费</span>"; | |||||
label: '线上缴费状态', name: 'PayFeeStatus', width: 100, align: "left", formatterAsync: function (callback, value, row, op, $cell) { | |||||
learun.clientdata.getAsync('dataItem', { | |||||
key: value, | |||||
code: 'PayStatus', | |||||
callback: function (_data) { | |||||
callback(_data.text); | |||||
} | |||||
}); | |||||
} | } | ||||
}, | }, | ||||
{ label: '线上缴费时间', name: 'PayFeeDate', width: 130, align: "left" }, | { label: '线上缴费时间', name: 'PayFeeDate', width: 130, align: "left" }, | ||||
@@ -15,14 +15,14 @@ | |||||
<div class="lr-layout-wrap lr-layout-wrap-notitle" style="padding-top:10px;"> | <div class="lr-layout-wrap lr-layout-wrap-notitle" style="padding-top:10px;"> | ||||
<div class="lr-layout-body"> | <div class="lr-layout-body"> | ||||
<ul class="lr-left-list" id="lr_left_list"> | <ul class="lr-left-list" id="lr_left_list"> | ||||
<li data-value="1">基本信息</li> | |||||
<li data-value="1" class="active">基本信息</li> | |||||
@*<li data-value="2">联系方式</li>*@ | @*<li data-value="2">联系方式</li>*@ | ||||
<li data-value="3">我的头像</li> | <li data-value="3">我的头像</li> | ||||
<li data-value="4">修改密码</li> | <li data-value="4">修改密码</li> | ||||
<li data-value="5">我的日志</li> | <li data-value="5">我的日志</li> | ||||
@if (ViewBag.UserType == "学生") | @if (ViewBag.UserType == "学生") | ||||
{ | { | ||||
<li data-value="6">选修流程</li> | |||||
@*<li data-value="6">选修流程</li>*@ | |||||
} | } | ||||
<li data-value="7">语言设置</li> | <li data-value="7">语言设置</li> | ||||
</ul> | </ul> | ||||
@@ -190,6 +190,7 @@ | |||||
}, | }, | ||||
filters: { | filters: { | ||||
sex: function (value) { | sex: function (value) { | ||||
console.log(value); | |||||
return value ? "男生" : "女生"; | return value ? "男生" : "女生"; | ||||
}, | }, | ||||
@@ -686,7 +687,7 @@ | |||||
</div> | </div> | ||||
@if (ViewBag.UserType == "学生") | @if (ViewBag.UserType == "学生") | ||||
{ | { | ||||
<div class="lr-layout-wrap-item " id="lr_layout_item6" style="padding: 10;"> | |||||
@*<div class="lr-layout-wrap-item " id="lr_layout_item6" style="padding: 10;"> | |||||
<center><h3> 西昌民族幼儿师范高等专科学校</h3></center> | <center><h3> 西昌民族幼儿师范高等专科学校</h3></center> | ||||
<center> | <center> | ||||
<h3> | <h3> | ||||
@@ -710,7 +711,7 @@ | |||||
3、选择课只开放三天,三天后自动关闭选课功能,每门选修课记2个选修学分,如果修不够选修学分将会无法毕业。<br /> | 3、选择课只开放三天,三天后自动关闭选课功能,每门选修课记2个选修学分,如果修不够选修学分将会无法毕业。<br /> | ||||
</p> | </p> | ||||
</div> | </div> | ||||
</div> | |||||
</div>*@ | |||||
} | } | ||||
@if (ViewBag.UserType == "学生" || ViewBag.UserType == "教师") | @if (ViewBag.UserType == "学生" || ViewBag.UserType == "教师") | ||||
@@ -742,8 +743,8 @@ | |||||
$("#headUrl").attr("src", "/LR_OrganizationModule/User/GetImg?userId=" + loginInfo.userId); | $("#headUrl").attr("src", "/LR_OrganizationModule/User/GetImg?userId=" + loginInfo.userId); | ||||
if ('@ViewBag.UserType' == '学生') { | if ('@ViewBag.UserType' == '学生') { | ||||
$("#lr_left_list").children('li').eq(4).addClass("active"); | |||||
$('.lr-layout-wrap-item').eq(5).addClass("active"); | |||||
$("#lr_left_list").children('li').eq(0).addClass("active"); | |||||
$('.lr-layout-wrap-item').eq(0).addClass("active"); | |||||
} else { | } else { | ||||
$("#lr_left_list").children('li').eq(0).addClass("active"); | $("#lr_left_list").children('li').eq(0).addClass("active"); | ||||
@@ -154,7 +154,7 @@ | |||||
<add key="ACIp" value="192.168.90.2"/> | <add key="ACIp" value="192.168.90.2"/> | ||||
<add key="ACIp2" value="192.168.200.252"/> | <add key="ACIp2" value="192.168.200.252"/> | ||||
<!-- 是否强制验证强密码 --> | <!-- 是否强制验证强密码 --> | ||||
<add key="verifypwd" value="true"/> | |||||
<add key="verifypwd" value="false"/> | |||||
<!--疫情防控组角色Id--> | <!--疫情防控组角色Id--> | ||||
<add key="EpidemicControlTeamRoleId" value="87f38e4e-b0a6-472c-b01a-2620b8f1ec46" /> | <add key="EpidemicControlTeamRoleId" value="87f38e4e-b0a6-472c-b01a-2620b8f1ec46" /> | ||||
<!--注册教师生成编号 金隅:jy;西昌:xc;大厂:dc--> | <!--注册教师生成编号 金隅:jy;西昌:xc;大厂:dc--> | ||||
@@ -156,6 +156,9 @@ | |||||
<Reference Include="System.Web.Services" /> | <Reference Include="System.Web.Services" /> | ||||
<Reference Include="System.EnterpriseServices" /> | <Reference Include="System.EnterpriseServices" /> | ||||
<Reference Include="System.Xml.Linq" /> | <Reference Include="System.Xml.Linq" /> | ||||
<Reference Include="ThoughtWorks.QRCode, Version=1.0.4778.30637, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\packages\ThoughtWorks.QRCode.1.1.0\lib\ThoughtWorks.QRCode.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="WebGrease, Version=1.5.2.14234, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> | <Reference Include="WebGrease, Version=1.5.2.14234, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> | ||||
<HintPath>..\packages\WebGrease.1.5.2\lib\WebGrease.dll</HintPath> | <HintPath>..\packages\WebGrease.1.5.2\lib\WebGrease.dll</HintPath> | ||||
</Reference> | </Reference> | ||||
@@ -192,6 +195,8 @@ | |||||
<ItemGroup> | <ItemGroup> | ||||
<Compile Include="Bootstraper.cs" /> | <Compile Include="Bootstraper.cs" /> | ||||
<Compile Include="Modules\AnnexesApiWx.cs" /> | <Compile Include="Modules\AnnexesApiWx.cs" /> | ||||
<Compile Include="Modules\StuFreshPayFeeApi.cs" /> | |||||
<Compile Include="Modules\StuPayFeeApi.cs" /> | |||||
<Compile Include="Modules\BaseNoLoginApi.cs" /> | <Compile Include="Modules\BaseNoLoginApi.cs" /> | ||||
<Compile Include="Modules\ArrangeLessonTermAttemperApi.cs" /> | <Compile Include="Modules\ArrangeLessonTermAttemperApi.cs" /> | ||||
<Compile Include="Modules\DataSourceNoLoginApi.cs" /> | <Compile Include="Modules\DataSourceNoLoginApi.cs" /> | ||||
@@ -7,136 +7,135 @@ using System.IO; | |||||
namespace Learun.Application.WebApi.Modules | namespace Learun.Application.WebApi.Modules | ||||
{ | { | ||||
public class AnnexesApiWx : BaseApi | |||||
{ | |||||
public AnnexesApiWx() | |||||
: base("/learun/adms/annexes") | |||||
public class AnnexesApiWx : BaseApi | |||||
{ | { | ||||
Get["/wxlist"] = WxGetList; | |||||
Get["/wxdown"] = WxDownload; | |||||
Get["/wxfileinfo"] = WxFileInfo; | |||||
Post["/wxupload"] = WxUpload; | |||||
Post["/wxdelete"] = WxDeleteFile; | |||||
public AnnexesApiWx() | |||||
: base("/learun/adms/annexes") | |||||
{ | |||||
Get["/wxlist"] = WxGetList; | |||||
Get["/wxdown"] = WxDownload; | |||||
Get["/wxfileinfo"] = WxFileInfo; | |||||
Post["/wxupload"] = WxUpload; | |||||
Post["/wxdelete"] = WxDeleteFile; | |||||
} | |||||
private AnnexesFileIBLL annexesFileIBLL = new AnnexesFileBLL(); | |||||
/// <summary> | |||||
/// 获取附件列表 | |||||
/// </summary> | |||||
/// <param name="_"></param> | |||||
/// <returns></returns> | |||||
public Response WxGetList(dynamic _) | |||||
{ | |||||
var keyValue = this.GetReqData(); | |||||
var list = annexesFileIBLL.GetList(keyValue); | |||||
return Success(list); | |||||
} | |||||
/// <summary> | |||||
/// 上传附件图片文件 | |||||
/// <summary> | |||||
/// <returns></returns> | |||||
public Response WxUpload(dynamic _) | |||||
{ | |||||
var files = (List<HttpFile>)this.Context.Request.Files; | |||||
string folderId = Request.Form["folderId"]; | |||||
string filePath = Config.GetValue("AnnexesFile"); | |||||
string uploadDate = DateTime.Now.ToString("yyyyMMdd"); | |||||
string fileEextension = Path.GetExtension(files[0].Name); | |||||
string fileType = fileEextension.Replace(".", ""); | |||||
string fileGuid = Guid.NewGuid().ToString(); | |||||
string virtualPath = string.Format("{0}/{1}/{2}/{3}{4}", filePath, userInfo.userId, uploadDate, fileGuid, fileEextension); | |||||
//创建文件夹 | |||||
string path = Path.GetDirectoryName(virtualPath); | |||||
Directory.CreateDirectory(path); | |||||
AnnexesFileEntity fileAnnexesEntity = new AnnexesFileEntity(); | |||||
if (!System.IO.File.Exists(virtualPath)) | |||||
{ | |||||
byte[] bytes = new byte[files[0].Value.Length]; | |||||
files[0].Value.Read(bytes, 0, bytes.Length); | |||||
FileInfo file = new FileInfo(virtualPath); | |||||
FileStream fs = file.Create(); | |||||
fs.Write(bytes, 0, bytes.Length); | |||||
fs.Close(); | |||||
//文件信息写入数据库 | |||||
fileAnnexesEntity.F_Id = fileGuid; | |||||
fileAnnexesEntity.F_FileName = files[0].Name; | |||||
fileAnnexesEntity.F_FilePath = virtualPath; | |||||
fileAnnexesEntity.F_FileSize = files[0].Value.Length.ToString(); | |||||
fileAnnexesEntity.F_FileExtensions = fileEextension; | |||||
fileAnnexesEntity.F_FileType = fileType; | |||||
fileAnnexesEntity.F_CreateUserId = userInfo.userId; | |||||
fileAnnexesEntity.F_CreateUserName = userInfo.realName; | |||||
annexesFileIBLL.SaveEntity(folderId, fileAnnexesEntity); | |||||
} | |||||
return SuccessString(folderId); | |||||
} | |||||
/// <summary> | |||||
/// 获取文件信息 | |||||
/// </summary> | |||||
/// <param name="_"></param> | |||||
/// <returns></returns> | |||||
public Response WxFileInfo(dynamic _) | |||||
{ | |||||
var fileId = this.GetReqData(); | |||||
var fileEntity = annexesFileIBLL.GetEntity(fileId); | |||||
return Success(fileEntity); | |||||
} | |||||
/// <summary> | |||||
/// 删除文件 | |||||
/// </summary> | |||||
/// <param name="_"></param> | |||||
/// <returns></returns> | |||||
public Response WxDeleteFile(dynamic _) | |||||
{ | |||||
var fileId = this.GetReqData(); | |||||
AnnexesFileEntity fileInfoEntity = annexesFileIBLL.GetEntity(fileId); | |||||
annexesFileIBLL.DeleteEntity(fileId); | |||||
//删除文件 | |||||
if (System.IO.File.Exists(fileInfoEntity.F_FilePath)) | |||||
{ | |||||
System.IO.File.Delete(fileInfoEntity.F_FilePath); | |||||
} | |||||
return Success("删除成功"); | |||||
} | |||||
/// <summary> | |||||
/// 下载文件,微信小程序用 | |||||
/// | |||||
/// 微信小程序可以预览图片、文档 | |||||
/// 支持的图片格式:.jpg .png .webp .gif | |||||
/// 支持的文档格式:.doc(x) .xls(x) .ppt(x) .pdf | |||||
/// | |||||
/// 对于其他格式的文件,微信小程序官方未提供打开或预览的 API,文件对用户来说不可访问 | |||||
/// </summary> | |||||
/// <param name="_"></param> | |||||
/// <returns></returns> | |||||
public Response WxDownload(dynamic _) | |||||
{ | |||||
string name = this.GetReqData(); | |||||
string fileId = name.Split('.')[0]; | |||||
var fileEntity = annexesFileIBLL.GetEntity(fileId); | |||||
string filepath = fileEntity.F_FilePath; | |||||
if (!FileDownHelper.FileExists(filepath)) | |||||
{ | |||||
return 404; | |||||
} | |||||
FileDownHelper.DownLoadWx(filepath, fileEntity.F_FileType); | |||||
return Success(""); | |||||
} | |||||
} | } | ||||
private AnnexesFileIBLL annexesFileIBLL = new AnnexesFileBLL(); | |||||
/// <summary> | |||||
/// 获取附件列表 | |||||
/// </summary> | |||||
/// <param name="_"></param> | |||||
/// <returns></returns> | |||||
public Response WxGetList(dynamic _) | |||||
{ | |||||
var keyValue = this.GetReqData(); | |||||
var list = annexesFileIBLL.GetList(keyValue); | |||||
return Success(list); | |||||
} | |||||
/// <summary> | |||||
/// 上传附件图片文件 | |||||
/// <summary> | |||||
/// <returns></returns> | |||||
public Response WxUpload(dynamic _) | |||||
{ | |||||
var files = (List<HttpFile>)this.Context.Request.Files; | |||||
var folderId = this.GetReqData(); | |||||
string filePath = Config.GetValue("AnnexesFile"); | |||||
string uploadDate = DateTime.Now.ToString("yyyyMMdd"); | |||||
string fileEextension = Path.GetExtension(files[0].Name); | |||||
string fileType = fileEextension.Replace(".", ""); | |||||
string fileGuid = Guid.NewGuid().ToString(); | |||||
string virtualPath = string.Format("{0}/{1}/{2}/{3}{4}", filePath, userInfo.userId, uploadDate, fileGuid, fileEextension); | |||||
//创建文件夹 | |||||
string path = Path.GetDirectoryName(virtualPath); | |||||
Directory.CreateDirectory(path); | |||||
AnnexesFileEntity fileAnnexesEntity = new AnnexesFileEntity(); | |||||
if (!System.IO.File.Exists(virtualPath)) | |||||
{ | |||||
byte[] bytes = new byte[files[0].Value.Length]; | |||||
files[0].Value.Read(bytes, 0, bytes.Length); | |||||
FileInfo file = new FileInfo(virtualPath); | |||||
FileStream fs = file.Create(); | |||||
fs.Write(bytes, 0, bytes.Length); | |||||
fs.Close(); | |||||
//文件信息写入数据库 | |||||
fileAnnexesEntity.F_Id = fileGuid; | |||||
fileAnnexesEntity.F_FileName = files[0].Name; | |||||
fileAnnexesEntity.F_FilePath = virtualPath; | |||||
fileAnnexesEntity.F_FileSize = files[0].Value.Length.ToString(); | |||||
fileAnnexesEntity.F_FileExtensions = fileEextension; | |||||
fileAnnexesEntity.F_FileType = fileType; | |||||
fileAnnexesEntity.F_CreateUserId = userInfo.userId; | |||||
fileAnnexesEntity.F_CreateUserName = userInfo.realName; | |||||
annexesFileIBLL.SaveEntity(folderId, fileAnnexesEntity); | |||||
} | |||||
return SuccessString(fileGuid); | |||||
} | |||||
/// <summary> | |||||
/// 获取文件信息 | |||||
/// </summary> | |||||
/// <param name="_"></param> | |||||
/// <returns></returns> | |||||
public Response WxFileInfo(dynamic _) | |||||
{ | |||||
var fileId = this.GetReqData(); | |||||
var fileEntity = annexesFileIBLL.GetEntity(fileId); | |||||
return Success(fileEntity); | |||||
} | |||||
/// <summary> | |||||
/// 删除文件 | |||||
/// </summary> | |||||
/// <param name="_"></param> | |||||
/// <returns></returns> | |||||
public Response WxDeleteFile(dynamic _) | |||||
{ | |||||
var fileId = this.GetReqData(); | |||||
AnnexesFileEntity fileInfoEntity = annexesFileIBLL.GetEntity(fileId); | |||||
annexesFileIBLL.DeleteEntity(fileId); | |||||
//删除文件 | |||||
if (System.IO.File.Exists(fileInfoEntity.F_FilePath)) | |||||
{ | |||||
System.IO.File.Delete(fileInfoEntity.F_FilePath); | |||||
} | |||||
return Success("删除成功"); | |||||
} | |||||
/// <summary> | |||||
/// 下载文件,微信小程序用 | |||||
/// | |||||
/// 微信小程序可以预览图片、文档 | |||||
/// 支持的图片格式:.jpg .png .webp .gif | |||||
/// 支持的文档格式:.doc(x) .xls(x) .ppt(x) .pdf | |||||
/// | |||||
/// 对于其他格式的文件,微信小程序官方未提供打开或预览的 API,文件对用户来说不可访问 | |||||
/// </summary> | |||||
/// <param name="_"></param> | |||||
/// <returns></returns> | |||||
public Response WxDownload(dynamic _) | |||||
{ | |||||
string name = this.GetReqData(); | |||||
string fileId = name.Split('.')[0]; | |||||
var fileEntity = annexesFileIBLL.GetEntity(fileId); | |||||
string filepath = fileEntity.F_FilePath; | |||||
if (!FileDownHelper.FileExists(filepath)) | |||||
{ | |||||
return 404; | |||||
} | |||||
FileDownHelper.DownLoadWx(filepath, fileEntity.F_FileType); | |||||
return Success(""); | |||||
} | |||||
} | |||||
} | } |
@@ -21,12 +21,28 @@ namespace Learun.Application.WebApi.Modules | |||||
{ | { | ||||
Get["/scheme"] = GetScheme; | Get["/scheme"] = GetScheme; | ||||
Get["/data"] = GetData; | Get["/data"] = GetData; | ||||
Get["/folderkey"] = GetFolderkey; | |||||
Post["/save"] = Save; | Post["/save"] = Save; | ||||
Post["/delete"] = DeleteForm; | Post["/delete"] = DeleteForm; | ||||
} | } | ||||
private FormSchemeIBLL formSchemeIBLL = new FormSchemeBLL(); | private FormSchemeIBLL formSchemeIBLL = new FormSchemeBLL(); | ||||
private Response GetFolderkey(dynamic _) | |||||
{ | |||||
List<FolderKeyReq> req = this.GetReqData<List<FolderKeyReq>>();// 获取模板请求数据 | |||||
Dictionary<string, string> dic = new Dictionary<string, string>(); | |||||
foreach (var item in req) | |||||
{ | |||||
if (!string.IsNullOrEmpty(item.processIdName)) | |||||
{ | |||||
var data = formSchemeIBLL.GetFolderKey(item.schemeInfoId, item.processIdName, item.keyValue);// | |||||
dic = data; | |||||
} | |||||
} | |||||
return Success(dic); | |||||
} | |||||
/// <summary> | /// <summary> | ||||
/// 获取表单模板数据 | /// 获取表单模板数据 | ||||
/// </summary> | /// </summary> | ||||
@@ -104,6 +120,35 @@ namespace Learun.Application.WebApi.Modules | |||||
} | } | ||||
#region 请求参数 | #region 请求参数 | ||||
private class FolderKeyReq | |||||
{ | |||||
/// <summary> | |||||
/// 表单请求Id | |||||
/// </summary> | |||||
public string id { get; set; } | |||||
/// <summary> | |||||
/// 当前自定义表单版本号 | |||||
/// </summary> | |||||
public string ver { get; set; } | |||||
/// <summary> | |||||
/// 流程模板id | |||||
/// </summary> | |||||
public string schemeInfoId { get; set; } | |||||
/// <summary> | |||||
/// 关联字段名称 | |||||
/// </summary> | |||||
public string processIdName { get; set; } | |||||
/// <summary> | |||||
/// 数据主键值 | |||||
/// </summary> | |||||
public string keyValue { get; set; } | |||||
/// <summary> | |||||
/// 表单数据 | |||||
/// </summary> | |||||
public string formData { get; set; } | |||||
} | |||||
private class SchemeReq { | private class SchemeReq { | ||||
/// <summary> | /// <summary> | ||||
/// 表单请求Id | /// 表单请求Id | ||||
@@ -0,0 +1,219 @@ | |||||
using System; | |||||
using Learun.Application.Organization; | |||||
using Learun.Application.TwoDevelopment.EducationalAdministration; | |||||
using Learun.Application.TwoDevelopment.EvaluationTeach; | |||||
using Learun.Util; | |||||
using Nancy; | |||||
using System.Collections.Generic; | |||||
using System.Drawing; | |||||
using System.IO; | |||||
using System.Linq; | |||||
using System.Security.Cryptography; | |||||
using System.Text; | |||||
using System.Web; | |||||
using System.Web.Mvc; | |||||
using Learun.Application.Base.SystemModule; | |||||
using Learun.Application.TwoDevelopment.Ask; | |||||
using Learun.Application.TwoDevelopment.ReceiveSendFeeManagement; | |||||
using Newtonsoft.Json; | |||||
using ThoughtWorks.QRCode.Codec; | |||||
namespace Learun.Application.WebApi.Modules | |||||
{ | |||||
/// <summary> | |||||
/// 版 本 Learun-ADMS V7.0.0 数字化智慧校园 | |||||
/// Copyright (c) 2013-2018 北京泉江科技有限公司 | |||||
/// 创建人:数字化智慧校园-框架开发组 | |||||
/// 日 期:2018.01.04 | |||||
/// 描 述:部门管理 | |||||
/// </summary> | |||||
public class StuFreshPayFeeApi : BaseApi | |||||
{ | |||||
public StuFreshPayFeeApi() | |||||
: base("/learun/freshpayfee") | |||||
{ | |||||
Get["/getpayfeelist"] = GetPayfeeList;// 获取缴费列表 | |||||
Get["/getpayfeeinfo"] = GetPayfeeInfo;//获取缴费明细 | |||||
Post["/generateqrcode"] = PayFeeQRCode;//生成缴费二维码 | |||||
Get["/getinvoice"] = GetInvoice;//获取发票 | |||||
} | |||||
private StuInfoFreshIBLL stuInfoFreshIBLL = new StuInfoFreshBLL(); | |||||
private FinaChargesStandardIBLL finaChargesStandardIBLL = new FinaChargesStandardBLL(); | |||||
public Response GetInvoice(dynamic _) | |||||
{ | |||||
string keyValue = Request.Query["keyValue"]; | |||||
var list = stuInfoFreshIBLL.GetStuEnrollFeeOrder(keyValue, true); | |||||
return Success(list); | |||||
} | |||||
public Response GetPayfeeList(dynamic _) | |||||
{ | |||||
ReqPageParam parameter = this.GetReqData<ReqPageParam>(); | |||||
var data = stuInfoFreshIBLL.GetPageList(parameter.pagination, parameter.queryJson); | |||||
var jsonData = new | |||||
{ | |||||
rows = data, | |||||
total = parameter.pagination.total, | |||||
page = parameter.pagination.page, | |||||
records = parameter.pagination.records | |||||
}; | |||||
return Success(jsonData); | |||||
} | |||||
public Response GetPayfeeInfo(dynamic _) | |||||
{ | |||||
string keyValue = Request.Query["keyValue"]; | |||||
int jiaoFeiYear = DateTime.Now.Year; | |||||
var StuInfoFreshData = stuInfoFreshIBLL.GetStuInfoFreshEntity(keyValue); | |||||
var stuInfoFreshFamily = stuInfoFreshIBLL.GetStuInfoFreshFamilyList(keyValue); | |||||
//当前年度缴费记录 | |||||
var FeeOrderList = stuInfoFreshIBLL.GetFeeOrderList(StuInfoFreshData.StuNo, jiaoFeiYear); | |||||
var FinaChargesStandardList = new List<FinaChargesStandardEntity>(); | |||||
FinaChargesStandardList = finaChargesStandardIBLL.GetFinaChargesStandardListByYongYou(StuInfoFreshData.StuNo, jiaoFeiYear).ToList(); | |||||
var PayFeeTotal = FinaChargesStandardList.Select(x => x.Standard).Sum(); | |||||
var jsonData = new | |||||
{ | |||||
StuInfoFreshData = StuInfoFreshData, | |||||
FinaChargesStandardList = FinaChargesStandardList, | |||||
StuInfoFreshFamilyList = stuInfoFreshFamily, | |||||
PayFeeTotal = PayFeeTotal, | |||||
YJAmount = FeeOrderList.Sum(x => x.SJAmount) | |||||
}; | |||||
return Success(jsonData); | |||||
} | |||||
public class PayfeeRequest | |||||
{ | |||||
public string strEntity { get; set; } | |||||
public string detailList { get; set; } | |||||
} | |||||
/// <summary> | |||||
/// 生成缴费二维码 | |||||
/// </summary> | |||||
/// <returns></returns> | |||||
public Response PayFeeQRCode(dynamic _) | |||||
{ | |||||
string keyValue = Request.Query["keyValue"]; | |||||
PayfeeRequest parameter = this.GetReqData<PayfeeRequest>(); | |||||
StuInfoFreshEntity entity = parameter.strEntity.ToObject<StuInfoFreshEntity>(); | |||||
List<StuEnrollFeeOrderDetailEntity> list = parameter.detailList.ToObject<List<StuEnrollFeeOrderDetailEntity>>(); | |||||
var model = stuInfoFreshIBLL.GetStuInfoFreshEntity(keyValue); | |||||
var imgUrl = ""; | |||||
Random ran = new Random(); | |||||
string merchantid = "105000082201406";//商户号 | |||||
string posid = "043724806";//商户柜台代码 | |||||
string branchid = "510000000";//分行代码 | |||||
string orderid = DateTime.Now.ToString("yyyyMMddhhmmss") + ran.Next(0, 100000); | |||||
string payment = entity.PayMoney.ToString(); | |||||
string curcode = "01"; | |||||
string txcode = "530550"; | |||||
string remark1 = model.StuNo; | |||||
string remark2 = "20" + model.Grade; | |||||
string returntype = "3"; | |||||
string timeout = DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"); | |||||
string pub32tr2 = "40d987faa793a0a27e7a86ef020111"; | |||||
string bankURL = "https://ibsbjstar.ccb.com.cn/CCBIS/ccbMain?CCB_IBSVersion=V6"; | |||||
string tmp = "MERCHANTID=" + merchantid + "&POSID=" + posid + "&BRANCHID=" + branchid + "&ORDERID=" + orderid; | |||||
tmp += "&PAYMENT=" + payment + "&CURCODE=" + curcode + "&TXCODE=" + txcode + "&REMARK1=" + remark1; | |||||
tmp += "&REMARK2=" + remark2 + "&RETURNTYPE=" + returntype + "&TIMEOUT=" + timeout; | |||||
MD5 md5 = MD5.Create(); | |||||
string tmp1 = tmp; | |||||
tmp += "&PUB=" + pub32tr2; | |||||
byte[] buffer = Encoding.Default.GetBytes(tmp); | |||||
byte[] md5Buffer = md5.ComputeHash(buffer); | |||||
string strMd5 = ""; | |||||
//hdnOrderId.Value = orderid; | |||||
foreach (byte item in md5Buffer) | |||||
{ | |||||
strMd5 += item.ToString("x2"); | |||||
} | |||||
string url = bankURL + "&" + tmp1 + "&MAC=" + strMd5; | |||||
string reJson = HttpMethods.Post(url); | |||||
LogEntity logEntity = new LogEntity(); | |||||
logEntity.F_CategoryId = 121; | |||||
logEntity.F_ExecuteResultJson = reJson; | |||||
logEntity.WriteLog(); | |||||
//HttpConnect conn = new HttpConnect(); | |||||
//string reJson = conn.Post(url, ""); | |||||
JsonBean MemberInfoList = JsonConvert.DeserializeObject<JsonBean>(reJson); | |||||
if (MemberInfoList.SUCCESS.Equals("true")) | |||||
{ | |||||
string imgCode = HttpMethods.Post(MemberInfoList.PAYURL); | |||||
logEntity.F_CategoryId = 121; | |||||
logEntity.F_ExecuteResultJson = imgCode; | |||||
logEntity.WriteLog(); | |||||
MemberInfoList = JsonConvert.DeserializeObject<JsonBean>(imgCode); | |||||
if (MemberInfoList.SUCCESS.Equals("true")) | |||||
{ | |||||
imgUrl = CreateQRImg(MemberInfoList.QRURL, orderid); | |||||
} | |||||
} | |||||
if (!string.IsNullOrEmpty(imgUrl)) | |||||
{ | |||||
// model.PayFeeDetail = entity.PayFeeDetail; | |||||
// model.PayMoney = entity.PayMoney; | |||||
model.LoanMoney = entity.LoanMoney; | |||||
model.orderid = orderid; | |||||
stuInfoFreshIBLL.SaveFeeData(keyValue, model, list); | |||||
} | |||||
return Success(imgUrl); | |||||
} | |||||
public class JsonBean | |||||
{ | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
public string SUCCESS { get; set; } | |||||
public string PAYURL { get; set; } | |||||
public string QRURL { get; set; } | |||||
} | |||||
/// <summary> | |||||
/// 生成并保存二维码图片的方法 | |||||
/// </summary> | |||||
/// <param name="str">输入的内容</param> | |||||
public string CreateQRImg(string str, string orderId) | |||||
{ | |||||
string QRCodeFile = Config.GetValue("QRCodeFile"); | |||||
Random ran = new Random(); | |||||
Bitmap bt; | |||||
str = HttpUtility.UrlDecode(str); | |||||
string enCodeString = str; | |||||
//生成设置编码实例 | |||||
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder(); | |||||
//设置二维码的规模,默认4 | |||||
qrCodeEncoder.QRCodeScale = 3; | |||||
//设置二维码的版本,默认7 | |||||
qrCodeEncoder.QRCodeVersion = 7; | |||||
//设置错误校验级别,默认中等 | |||||
qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M; | |||||
//生成二维码图片 | |||||
bt = qrCodeEncoder.Encode(enCodeString, Encoding.UTF8); | |||||
//二维码图片的名称 | |||||
string filename = orderId; | |||||
if (!DirFileHelper.IsExistFile(QRCodeFile + "/Content/images/QRCode/")) | |||||
{ | |||||
Directory.CreateDirectory(QRCodeFile + "/Content/images/QRCode/"); | |||||
} | |||||
var path = QRCodeFile + "/Content/images/QRCode/" + filename + ".jpg"; | |||||
//保存二维码图片在photos路径下 | |||||
try | |||||
{ | |||||
bt.Save(path); | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
return ""; | |||||
} | |||||
//图片控件要显示的二维码图片路径 | |||||
return QRCodeFile + "/Content/images/QRCode/" + filename + ".jpg"; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,215 @@ | |||||
using System; | |||||
using Learun.Application.Organization; | |||||
using Learun.Application.TwoDevelopment.EducationalAdministration; | |||||
using Learun.Application.TwoDevelopment.EvaluationTeach; | |||||
using Learun.Util; | |||||
using Nancy; | |||||
using System.Collections.Generic; | |||||
using System.Drawing; | |||||
using System.IO; | |||||
using System.Linq; | |||||
using System.Security.Cryptography; | |||||
using System.Text; | |||||
using System.Web; | |||||
using System.Web.Mvc; | |||||
using Learun.Application.Base.SystemModule; | |||||
using Learun.Application.TwoDevelopment.Ask; | |||||
using Learun.Application.TwoDevelopment.ReceiveSendFeeManagement; | |||||
using Newtonsoft.Json; | |||||
using ThoughtWorks.QRCode.Codec; | |||||
namespace Learun.Application.WebApi.Modules | |||||
{ | |||||
/// <summary> | |||||
/// 版 本 Learun-ADMS V7.0.0 数字化智慧校园 | |||||
/// Copyright (c) 2013-2018 北京泉江科技有限公司 | |||||
/// 创建人:数字化智慧校园-框架开发组 | |||||
/// 日 期:2018.01.04 | |||||
/// 描 述:部门管理 | |||||
/// </summary> | |||||
public class StuPayFeeApi : BaseApi | |||||
{ | |||||
public StuPayFeeApi() | |||||
: base("/learun/payfee") | |||||
{ | |||||
Get["/getpayfeelist"] = GetPayfeeList;// 获取缴费列表 | |||||
Get["/getpayfeeinfo"] = GetPayfeeInfo;//获取缴费明细 | |||||
Post["/generateqrcode"] = PayFeeQRCode;//生成缴费二维码 | |||||
Get["/getinvoice"] = GetInvoice;//获取发票 | |||||
} | |||||
private StuInfoBasic_PayFeeIBLL stuInfoBasic_PayFeeIBLL = new StuInfoBasic_PayFeeBLL(); | |||||
private StuInfoBasicIBLL stuInfoBasicIbll = new StuInfoBasicBLL(); | |||||
private StuInfoFreshIBLL stuInfoFreshIBLL = new StuInfoFreshBLL(); | |||||
private FinaChargesStandardIBLL finaChargesStandardIBLL = new FinaChargesStandardBLL(); | |||||
public Response GetInvoice(dynamic _) | |||||
{ | |||||
string keyValue = Request.Query["keyValue"]; | |||||
var list = stuInfoFreshIBLL.GetStuEnrollFeeOrder(keyValue, false); | |||||
return Success(list); | |||||
} | |||||
public Response GetPayfeeList(dynamic _) | |||||
{ | |||||
ReqPageParam parameter = this.GetReqData<ReqPageParam>(); | |||||
var data = stuInfoBasic_PayFeeIBLL.GetPageList(parameter.pagination, parameter.queryJson); | |||||
var jsonData = new | |||||
{ | |||||
rows = data, | |||||
total = parameter.pagination.total, | |||||
page = parameter.pagination.page, | |||||
records = parameter.pagination.records | |||||
}; | |||||
return Success(jsonData); | |||||
} | |||||
public Response GetPayfeeInfo(dynamic _) | |||||
{ | |||||
string keyValue = Request.Query["keyValue"]; | |||||
var stuInfoBasic_PayFeeEntity = stuInfoBasic_PayFeeIBLL.GetStuInfoBasic_PayFeeEntity(keyValue); | |||||
var StuInfoFreshData = stuInfoBasicIbll.GetStuInfoBasicEntityByStuNo(stuInfoBasic_PayFeeEntity.StuNo); | |||||
//当前年度缴费记录 | |||||
var FinaChargesStandardList = new List<FinaChargesStandardEntity>(); | |||||
FinaChargesStandardList = finaChargesStandardIBLL.GetFinaChargesStandardListByYongYou(StuInfoFreshData.StuNo, stuInfoBasic_PayFeeEntity.PayYear.Value).ToList(); | |||||
var PayFeeTotal = FinaChargesStandardList.Select(x => x.SJAmount).Sum(); | |||||
var jsonData = new | |||||
{ | |||||
StuInfoFreshData = StuInfoFreshData, | |||||
FinaChargesStandardList = FinaChargesStandardList, | |||||
PayFeeTotal = PayFeeTotal, | |||||
YJAmount = FinaChargesStandardList.Sum(x => x.PayedMoney) | |||||
}; | |||||
return Success(jsonData); | |||||
} | |||||
public class PayfeeRequest | |||||
{ | |||||
public string strEntity { get; set; } | |||||
public string detailList { get; set; } | |||||
} | |||||
/// <summary> | |||||
/// 生成缴费二维码 | |||||
/// </summary> | |||||
/// <returns></returns> | |||||
public Response PayFeeQRCode(dynamic _) | |||||
{ | |||||
string keyValue = Request.Query["keyValue"]; | |||||
PayfeeRequest parameter = this.GetReqData<PayfeeRequest>(); | |||||
StuInfoFreshEntity entity = parameter.strEntity.ToObject<StuInfoFreshEntity>(); | |||||
List<StuEnrollFeeOrderDetailEntity> list = parameter.detailList.ToObject<List<StuEnrollFeeOrderDetailEntity>>(); | |||||
var model = stuInfoBasic_PayFeeIBLL.GetStuInfoBasic_PayFeeEntity(keyValue); | |||||
var imgUrl = ""; | |||||
Random ran = new Random(); | |||||
string merchantid = "105000082201406";//商户号 | |||||
string posid = "043724806";//商户柜台代码 | |||||
string branchid = "510000000";//分行代码 | |||||
string orderid = DateTime.Now.ToString("yyyyMMddhhmmss") + ran.Next(0, 100000); | |||||
string payment = entity.PayMoney.ToString(); | |||||
string curcode = "01"; | |||||
string txcode = "530550"; | |||||
string remark1 = model.StuNo; | |||||
string remark2 = model.PayYear.ToString(); | |||||
string returntype = "3"; | |||||
string timeout = DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"); | |||||
string pub32tr2 = "40d987faa793a0a27e7a86ef020111"; | |||||
string bankURL = "https://ibsbjstar.ccb.com.cn/CCBIS/ccbMain?CCB_IBSVersion=V6"; | |||||
string tmp = "MERCHANTID=" + merchantid + "&POSID=" + posid + "&BRANCHID=" + branchid + "&ORDERID=" + orderid; | |||||
tmp += "&PAYMENT=" + payment + "&CURCODE=" + curcode + "&TXCODE=" + txcode + "&REMARK1=" + remark1; | |||||
tmp += "&REMARK2=" + remark2 + "&RETURNTYPE=" + returntype + "&TIMEOUT=" + timeout; | |||||
MD5 md5 = MD5.Create(); | |||||
string tmp1 = tmp; | |||||
tmp += "&PUB=" + pub32tr2; | |||||
byte[] buffer = Encoding.Default.GetBytes(tmp); | |||||
byte[] md5Buffer = md5.ComputeHash(buffer); | |||||
string strMd5 = ""; | |||||
//hdnOrderId.Value = orderid; | |||||
foreach (byte item in md5Buffer) | |||||
{ | |||||
strMd5 += item.ToString("x2"); | |||||
} | |||||
string url = bankURL + "&" + tmp1 + "&MAC=" + strMd5; | |||||
string reJson = HttpMethods.Post(url); | |||||
LogEntity logEntity = new LogEntity(); | |||||
logEntity.F_CategoryId = 121; | |||||
logEntity.F_ExecuteResultJson = reJson; | |||||
logEntity.WriteLog(); | |||||
//HttpConnect conn = new HttpConnect(); | |||||
//string reJson = conn.Post(url, ""); | |||||
JsonBean MemberInfoList = JsonConvert.DeserializeObject<JsonBean>(reJson); | |||||
if (MemberInfoList.SUCCESS.Equals("true")) | |||||
{ | |||||
string imgCode = HttpMethods.Post(MemberInfoList.PAYURL); | |||||
logEntity.F_CategoryId = 121; | |||||
logEntity.F_ExecuteResultJson = imgCode; | |||||
logEntity.WriteLog(); | |||||
MemberInfoList = JsonConvert.DeserializeObject<JsonBean>(imgCode); | |||||
if (MemberInfoList.SUCCESS.Equals("true")) | |||||
{ | |||||
imgUrl = CreateQRImg(MemberInfoList.QRURL, orderid); | |||||
} | |||||
} | |||||
if (!string.IsNullOrEmpty(imgUrl)) | |||||
{ | |||||
model.orderid = orderid; | |||||
stuInfoFreshIBLL.SaveFeeData(keyValue, model, list); | |||||
} | |||||
return Success(imgUrl); | |||||
} | |||||
public class JsonBean | |||||
{ | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
public string SUCCESS { get; set; } | |||||
public string PAYURL { get; set; } | |||||
public string QRURL { get; set; } | |||||
} | |||||
/// <summary> | |||||
/// 生成并保存二维码图片的方法 | |||||
/// </summary> | |||||
/// <param name="str">输入的内容</param> | |||||
public string CreateQRImg(string str, string orderId) | |||||
{ | |||||
string QRCodeFile = Config.GetValue("QRCodeFile"); | |||||
Random ran = new Random(); | |||||
Bitmap bt; | |||||
str = HttpUtility.UrlDecode(str); | |||||
string enCodeString = str; | |||||
//生成设置编码实例 | |||||
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder(); | |||||
//设置二维码的规模,默认4 | |||||
qrCodeEncoder.QRCodeScale = 3; | |||||
//设置二维码的版本,默认7 | |||||
qrCodeEncoder.QRCodeVersion = 7; | |||||
//设置错误校验级别,默认中等 | |||||
qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M; | |||||
//生成二维码图片 | |||||
bt = qrCodeEncoder.Encode(enCodeString, Encoding.UTF8); | |||||
//二维码图片的名称 | |||||
string filename = orderId; | |||||
if (!DirFileHelper.IsExistFile(QRCodeFile+"/Content/images/QRCode/")) | |||||
{ | |||||
Directory.CreateDirectory(QRCodeFile + "/Content/images/QRCode/"); | |||||
} | |||||
var path = QRCodeFile + "/Content/images/QRCode/" + filename + ".jpg"; | |||||
//保存二维码图片在photos路径下 | |||||
try | |||||
{ | |||||
bt.Save(path); | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
return ""; | |||||
} | |||||
//图片控件要显示的二维码图片路径 | |||||
return QRCodeFile + "/Content/images/QRCode/" + filename + ".jpg"; | |||||
} | |||||
} | |||||
} |
@@ -36,6 +36,8 @@ namespace Learun.Application.WebApi.Modules | |||||
Get["/weixinconfig"] = GetWeixinConfig; | Get["/weixinconfig"] = GetWeixinConfig; | ||||
Post["/getweixinaccess_token"] = GetWeixinAccess_token; | Post["/getweixinaccess_token"] = GetWeixinAccess_token; | ||||
Post["/login"] = Login; | Post["/login"] = Login; | ||||
//新生首次登陆 | |||||
Post["/loginbyidcard"] = LoginByIdCard; | |||||
Get["/getweixinwebaccess_token"] = GetWeixinWebaccess_token; | Get["/getweixinwebaccess_token"] = GetWeixinWebaccess_token; | ||||
//获取ACIp | //获取ACIp | ||||
Get["/GetACIp"] = GetACIp; | Get["/GetACIp"] = GetACIp; | ||||
@@ -100,6 +102,13 @@ namespace Learun.Application.WebApi.Modules | |||||
return Success(new { appid, secret }); | return Success(new { appid, secret }); | ||||
} | } | ||||
public class wxinfo | |||||
{ | |||||
public string errcode { get; set; } | |||||
public string errmsg { get; set; } | |||||
public string openid { get; set; } | |||||
} | |||||
public Response GetWeixinAccess_token(dynamic _) | public Response GetWeixinAccess_token(dynamic _) | ||||
{ | { | ||||
var entity = weChatConfigIbll.GetEnableEntity(); | var entity = weChatConfigIbll.GetEnableEntity(); | ||||
@@ -110,7 +119,7 @@ namespace Learun.Application.WebApi.Modules | |||||
var responsejson = HttpGet("https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appid + "&secret=" + secret + "&code=" + code + "&grant_type=authorization_code"); | var responsejson = HttpGet("https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appid + "&secret=" + secret + "&code=" + code + "&grant_type=authorization_code"); | ||||
if (!string.IsNullOrEmpty(responsejson)) | if (!string.IsNullOrEmpty(responsejson)) | ||||
{ | { | ||||
var weixintokenobj = JsonConvert.DeserializeObject<dynamic>(responsejson); | |||||
var weixintokenobj = JsonConvert.DeserializeObject<wxinfo>(responsejson); | |||||
if (string.IsNullOrEmpty(weixintokenobj.errcode)) | if (string.IsNullOrEmpty(weixintokenobj.errcode)) | ||||
{ | { | ||||
string openid = weixintokenobj.openid; | string openid = weixintokenobj.openid; | ||||
@@ -241,6 +250,77 @@ namespace Learun.Application.WebApi.Modules | |||||
#endregion | #endregion | ||||
} | } | ||||
private Response LoginByIdCard(dynamic _) | |||||
{ | |||||
LoginModel loginModel = this.GetReqData<LoginModel>(); | |||||
#region 内部账户验证 | |||||
UserEntity userEntity = userIbll.CheckLoginByIdCard(loginModel.username, loginModel.password); | |||||
#region 写入日志 | |||||
LogEntity logEntity = new LogEntity(); | |||||
logEntity.F_CategoryId = 1; | |||||
logEntity.F_OperateTypeId = ((int)OperationType.Login).ToString(); | |||||
logEntity.F_OperateType = EnumAttribute.GetDescription(OperationType.Login); | |||||
logEntity.F_OperateAccount = loginModel.username + "(" + userEntity.F_RealName + ")"; | |||||
logEntity.F_OperateUserId = !string.IsNullOrEmpty(userEntity.F_UserId) ? userEntity.F_UserId : loginModel.username; | |||||
logEntity.F_Module = Config.GetValue("SoftName"); | |||||
logEntity.F_Description = "移动端"; | |||||
#endregion | |||||
if (!userEntity.LoginOk)//登录失败 | |||||
{ | |||||
//写入日志 | |||||
logEntity.F_ExecuteResult = 0; | |||||
logEntity.F_ExecuteResultJson = "登录失败:" + userEntity.LoginMsg; | |||||
logEntity.WriteLog(); | |||||
return Fail(userEntity.LoginMsg); | |||||
} | |||||
else | |||||
{ | |||||
ReqParameter req = this.Bind<ReqParameter>(); | |||||
string token = OperatorHelper.Instance.AddLoginUser(userEntity.F_Account, "Learun_ADMS_6.1_App", req.loginMark, false);//写入缓存信息 | |||||
//写入日志 | |||||
logEntity.F_ExecuteResult = 1; | |||||
logEntity.F_ExecuteResultJson = "登录成功"; | |||||
logEntity.WriteLog(); | |||||
OperatorResult res = OperatorHelper.Instance.IsOnLine(token, req.loginMark); | |||||
res.userInfo.password = null; | |||||
res.userInfo.secretkey = null; | |||||
var studententity = stuInfoBasicIBLL.GetStuInfoBasicEntityByStuNo(userEntity.F_Account); | |||||
if (studententity != null) | |||||
{ | |||||
res.userInfo.grade = studententity.Grade; | |||||
var majorinfo = majorIbll.GetCdMajorEntityByMajorNo(studententity.MajorNo); | |||||
if (majorinfo != null) | |||||
{ | |||||
res.userInfo.majorno = majorinfo.ID ?? ""; | |||||
} | |||||
} | |||||
//是否强密码验证 | |||||
bool pwd = false; | |||||
if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["verifypwd"]) && ConfigurationManager.AppSettings["verifypwd"] == "true" && loginModel.up == false) | |||||
{ | |||||
pwd = true; | |||||
} | |||||
else | |||||
{ | |||||
//保存用户设备号 | |||||
userIbll.UpdateWeixinOpenId(userEntity.F_UserId, loginModel.openid); | |||||
} | |||||
var jsonData = new | |||||
{ | |||||
baseinfo = res.userInfo, | |||||
post = postIBLL.GetListByPostIds(res.userInfo.postIds), | |||||
role = roleIBLL.GetListByRoleIds(res.userInfo.roleIds), | |||||
pwd = pwd | |||||
}; | |||||
return Success(jsonData); | |||||
} | |||||
#endregion | |||||
} | |||||
public Response GetWeixinWebaccess_token(dynamic _) | public Response GetWeixinWebaccess_token(dynamic _) | ||||
{ | { | ||||
var entity = weChatConfigIbll.GetEnableEntity(); | var entity = weChatConfigIbll.GetEnableEntity(); | ||||
@@ -66,6 +66,7 @@ | |||||
<add key="userKey" value="14B417B0-463D-4F2B-8075-0A20EEDB773A" /> | <add key="userKey" value="14B417B0-463D-4F2B-8075-0A20EEDB773A" /> | ||||
<!-- ==================注意附件上传地址 修改到主网站部署目录下的Resource要不然飞星会报错================== --> | <!-- ==================注意附件上传地址 修改到主网站部署目录下的Resource要不然飞星会报错================== --> | ||||
<add key="AnnexesFile" value="D:\leiprojects\西昌单校区\Learun.Application.Web\Resource" /> | <add key="AnnexesFile" value="D:\leiprojects\西昌单校区\Learun.Application.Web\Resource" /> | ||||
<add key="QRCodeFile" value="D:\leiprojects\西昌单校区\Learun.Application.Web\Content" /> | |||||
<add key="ReportFile" value="~/Reports" /> | <add key="ReportFile" value="~/Reports" /> | ||||
<!-- ================== 工作流服务地址 ================== --> | <!-- ================== 工作流服务地址 ================== --> | ||||
<add key="workflowapi" value="http://localhost:8013" /> | <add key="workflowapi" value="http://localhost:8013" /> | ||||
@@ -30,6 +30,7 @@ | |||||
<package id="Oracle.ManagedDataAccess" version="12.1.24160719" targetFramework="net45" /> | <package id="Oracle.ManagedDataAccess" version="12.1.24160719" targetFramework="net45" /> | ||||
<package id="Oracle.ManagedDataAccess.EntityFramework" version="12.1.2400" targetFramework="net45" /> | <package id="Oracle.ManagedDataAccess.EntityFramework" version="12.1.2400" targetFramework="net45" /> | ||||
<package id="System.ValueTuple" version="4.5.0" targetFramework="net45" requireReinstallation="true" /> | <package id="System.ValueTuple" version="4.5.0" targetFramework="net45" requireReinstallation="true" /> | ||||
<package id="ThoughtWorks.QRCode" version="1.1.0" targetFramework="net461" /> | |||||
<package id="Unity" version="4.0.1" targetFramework="net45" /> | <package id="Unity" version="4.0.1" targetFramework="net45" /> | ||||
<package id="WebGrease" version="1.5.2" targetFramework="net45" /> | <package id="WebGrease" version="1.5.2" targetFramework="net45" /> | ||||
</packages> | </packages> |
@@ -551,7 +551,91 @@ namespace Learun.Application.Form | |||||
} | } | ||||
} | } | ||||
} | } | ||||
public Dictionary<string, string> GetFolderKey(string schemeInfoId, string processIdName, string keyValue) | |||||
{ | |||||
Dictionary<string, DataTable> res = new Dictionary<string, DataTable>(); | |||||
try | |||||
{ | |||||
FormSchemeInfoEntity formSchemeInfoEntity = GetSchemeInfoEntity(schemeInfoId); | |||||
FormSchemeEntity formSchemeEntity = GetSchemeEntity(formSchemeInfoEntity.F_SchemeId); | |||||
FormSchemeModel formSchemeModel = formSchemeEntity.F_Scheme.ToObject<FormSchemeModel>(); | |||||
// 确定主从表之间的关系 | |||||
List<TreeModelEx<FormTableModel>> TableTree = new List<TreeModelEx<FormTableModel>>();// 从表 | |||||
foreach (var table in formSchemeModel.dbTable) | |||||
{ | |||||
TreeModelEx<FormTableModel> treeone = new TreeModelEx<FormTableModel>(); | |||||
treeone.data = table; | |||||
treeone.id = table.name; | |||||
treeone.parentId = table.relationName; | |||||
if (string.IsNullOrEmpty(table.relationName)) | |||||
{ | |||||
treeone.parentId = "0"; | |||||
} | |||||
TableTree.Add(treeone); | |||||
} | |||||
TableTree = TableTree.ToTree(); | |||||
// 确定表与组件之间的关系 | |||||
Dictionary<string, List<FormCompontModel>> tableComponts = new Dictionary<string, List<FormCompontModel>>(); | |||||
foreach (var tab in formSchemeModel.data) | |||||
{ | |||||
foreach (var compont in tab.componts) | |||||
{ | |||||
if (!string.IsNullOrEmpty(compont.table)) | |||||
{ | |||||
if (!tableComponts.ContainsKey(compont.table)) | |||||
{ | |||||
tableComponts[compont.table] = new List<FormCompontModel>(); | |||||
} | |||||
if (compont.type == "upload") | |||||
{ | |||||
tableComponts[compont.table].Add(compont); | |||||
} | |||||
if (compont.type == "guid") | |||||
{ | |||||
tableComponts[compont.table].Add(compont); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
GetInstanceTableData(TableTree, tableComponts, formSchemeModel.dbId, keyValue, processIdName, null, res); | |||||
Dictionary < string,string> uploadfieldkeyvalue=new Dictionary<string, string>(); | |||||
foreach (var itemCompont in tableComponts) | |||||
{ | |||||
foreach (FormCompontModel formitem in itemCompont.Value) | |||||
{ | |||||
if (formitem.type=="upload") | |||||
{ | |||||
foreach (var resitem in res) | |||||
{ | |||||
if (resitem.Value.Rows.Count>0) | |||||
{ | |||||
if (resitem.Value.Rows[0][formitem.field] != null) | |||||
uploadfieldkeyvalue.Add(formitem.id, resitem.Value.Rows[0][formitem.field].ToString()); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
return uploadfieldkeyvalue; | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
if (ex is ExceptionEx) | |||||
{ | |||||
throw; | |||||
} | |||||
else | |||||
{ | |||||
throw ExceptionEx.ThrowBusinessException(ex); | |||||
} | |||||
} | |||||
} | |||||
/// <summary> | /// <summary> | ||||
/// 保存自定义表单数据 | /// 保存自定义表单数据 | ||||
/// </summary> | /// </summary> | ||||
@@ -137,5 +137,7 @@ namespace Learun.Application.Form | |||||
/// <param name="keyValue">数据主键值</param> | /// <param name="keyValue">数据主键值</param> | ||||
void DeleteInstanceForm(string schemeInfoId, string keyValue); | void DeleteInstanceForm(string schemeInfoId, string keyValue); | ||||
#endregion | #endregion | ||||
Dictionary<string, string> GetFolderKey(string itemSchemeInfoId, string itemProcessIdName, string itemKeyValue); | |||||
} | } | ||||
} | } |
@@ -62,7 +62,7 @@ namespace Learun.Application.TwoDevelopment.EducationalAdministration | |||||
[NotMapped] public string StuCode { get; set; } | [NotMapped] public string StuCode { get; set; } | ||||
[NotMapped] public string StuName { get; set; } | [NotMapped] public string StuName { get; set; } | ||||
[NotMapped] public string GenderNo { get; set; } | |||||
[NotMapped] public bool? GenderNo { get; set; } | |||||
[NotMapped] public string IdentityCardNo { get; set; } | [NotMapped] public string IdentityCardNo { get; set; } | ||||
[NotMapped] public string DeptNo { get; set; } | [NotMapped] public string DeptNo { get; set; } | ||||
[NotMapped] public string MajorNo { get; set; } | [NotMapped] public string MajorNo { get; set; } | ||||
@@ -10,6 +10,10 @@ | |||||
{ | { | ||||
"launchtype" : "remote" | "launchtype" : "remote" | ||||
}, | }, | ||||
"mp-weixin" : | |||||
{ | |||||
"launchtype" : "remote" | |||||
}, | |||||
"type" : "uniCloud" | "type" : "uniCloud" | ||||
} | } | ||||
] | ] | ||||
@@ -10,7 +10,7 @@ | |||||
// H5 刷新时获取当前页面路径 | // H5 刷新时获取当前页面路径 | ||||
const pagePath = "/" + param.path; | const pagePath = "/" + param.path; | ||||
// 如果 H5 刷新后访问的不是首页/登录页/注册页,直接跳转回首页 | // 如果 H5 刷新后访问的不是首页/登录页/注册页,直接跳转回首页 | ||||
if (!["/pages/login", "/pages/home", "/pages/signup"].includes(pagePath)) { | |||||
if (!["/pages/login", "/pages/weixinLogin","/pages/home", "/pages/signup","/pages/my/newpassword"].includes(pagePath)) { | |||||
this.$nextTick(() => { | this.$nextTick(() => { | ||||
this.TAB_TO("/pages/home"); | this.TAB_TO("/pages/home"); | ||||
return; | return; | ||||
@@ -24,274 +24,310 @@ import moment from 'moment' | |||||
*/ | */ | ||||
export default { | export default { | ||||
methods: { | |||||
/** | |||||
* 获取一个 scheme 表单项的源数据 (加载表单时使用) | |||||
* 参数: 单个 schemeItem | |||||
* | |||||
* radio、select、checkbox、layer 这四种表单项,需要加载额外的选单数据 | |||||
* 选单数据有两种获取方式: | |||||
* 1、来自数据字典: | |||||
* 数据字典在 this.GET_GLOBAL('dataDictionary') | |||||
* 表单使用的字段在 schemeItem.itemCode | |||||
* 选单数据中的 text 字段作为显示, value 字段作为值 | |||||
* | |||||
* 2、来自数据源: | |||||
* 将 schemeItem.dataSourceId 按符号「,」逗号分割为数组,分割为: [code, displayField, valueField] | |||||
* 数据源需要请求 API 来获取,请求需要带上数据源的编号 code | |||||
* displayField、valueField 分别为展示字段和值绑定字段 | |||||
* | |||||
* 选单数据有两种格式: | |||||
* 1、对于 radio、select、checkbox 来说: | |||||
* 只需要一个数组,数组形如: [{ text: '选项文字', value: '选项值' }, ...] | |||||
* 将获取的数据绑定到组件的 range 属性上即可 | |||||
* 全局数据中默认是对象形式,使用 Object.values() 转化即可 | |||||
* | |||||
* 2、对于 layer 来说: | |||||
* 返回一个对象,形如 { source, layerData, selfField } | |||||
* source: 为弹层中列出的数据,是一个数组 | |||||
* layerData: 需要在弹层窗口中展示的字段及标题文字,形如: [{ name:'要展示的字段名', label:'标题文字' }] | |||||
* selfField: 该表单值绑定哪个字段,默认为绑定到自身的字段 | |||||
*/ | |||||
async getSourceData(schemeItem) { | |||||
if (['radio', 'select', 'checkbox'].includes(schemeItem.type)) { | |||||
// radio select checkbox 三种情况 | |||||
if (!schemeItem.dataSource || Number(schemeItem.dataSource) === 0) { | |||||
// dataSource 为 0,使用 clientData | |||||
return Object | |||||
.values(this.GET_GLOBAL('dataDictionary')[schemeItem.itemCode]) | |||||
.map(t => ({ value: t.value, text: t.text })) | |||||
} else { | |||||
// dataSource 不为 0,使用数据源,需要请求接口,并且提取出显示字段和实际字段 | |||||
const [code, displayField = schemeItem.showField, valueField = schemeItem.saveField] = schemeItem.dataSourceId | |||||
.split(',') | |||||
const sourceData = await this.FETCH_DATASOURCE(code) | |||||
if (!sourceData) { return [] } | |||||
return sourceData.data.map(t => ({ text: t[displayField], value: t[valueField] })) | |||||
} | |||||
} else if (['layer'].includes(schemeItem.type)) { | |||||
// layer 需要更多属性 | |||||
if (!schemeItem.dataSource || Number(schemeItem.dataSource) === 0) { | |||||
// dataSource 为 0,使用 clientData | |||||
// clientData 对象转数组后,隐含 key:item.text 和 value:item.value 的关系 | |||||
const [keyItem, valueItem] = schemeItem.layerData | |||||
const source = Object | |||||
.values(this.GET_GLOBAL('dataDictionary')[schemeItem.itemCode]) | |||||
.map(t => ({ value: t.value, text: t.text })) | |||||
return { | |||||
source, | |||||
layerData: [ | |||||
{ name: 'text', label: keyItem.label || '', value: keyItem.value || '' }, | |||||
{ name: 'value', label: valueItem.label || '', value: valueItem.value || '' } | |||||
] | |||||
} | |||||
} else { | |||||
// dataSource 不为 0,使用数据源,需要请求接口,并且提取出显示字段和实际字段 | |||||
const [code] = schemeItem.dataSourceId.split(',') | |||||
const sourceData = await this.FETCH_DATASOURCE(code) | |||||
if (!sourceData) { return [] } | |||||
const source = sourceData.data | |||||
return { source, layerData: schemeItem.layerData.filter(t => (!t.hide) && (t.value || t.label)) } | |||||
} | |||||
} | |||||
return [] | |||||
}, | |||||
/** | |||||
* 获取一个 scheme 表单项的默认值 (用户新建表单时使用,或是编辑草稿) | |||||
* 参数: 单个 schemeItem , { processId } | |||||
* | |||||
* 每种类别的表单项分别获取的默认值: | |||||
* | |||||
* currentInfo: 根据类别取当前用户/部门/公司/时间日期 | |||||
* datetime: 根据 dfValue 字段表示昨天/今天/明天,格式化为字符串 | |||||
* radio、select: 有 dfValue 则使用,否则取第一条 | |||||
* checkbox: 有 dfValue 则使用,否则为空数组 | |||||
* encode: 根据 rulecode 请求表单编码 | |||||
* upload: 空数组 | |||||
* guid: 赋值第二个参数中的 processId,但是如果在子表格中,赋空字符串 | |||||
* girdtable: 递归所有表格项 scheme 依次为它们生成默认值 | |||||
* datetimerange: 字符串 0 | |||||
*/ | |||||
async getDefaultData(item, prop) { | |||||
const { processId } = prop | |||||
switch (item.type) { | |||||
case 'currentInfo': | |||||
switch (item.dataType) { | |||||
case 'user': | |||||
return this.GET_GLOBAL('loginUser').userId | |||||
case 'department': | |||||
return this.GET_GLOBAL('loginUser').departmentId | |||||
case 'company': | |||||
return this.GET_GLOBAL('loginUser').companyId | |||||
case 'time': | |||||
return moment().format('YYYY-MM-DD HH:mm:ss') | |||||
default: | |||||
return '' | |||||
} | |||||
case 'datetime': | |||||
const datetimeFormat = item.table ? | |||||
(Number(item.dateformat) === 0 ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss') : | |||||
(item.datetime === 'datetime' ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD') | |||||
const today = moment() | |||||
const dfDatetime = [ | |||||
today.subtract(1, 'day'), | |||||
today, | |||||
today.add(1, 'day') | |||||
][Number(item.dfvalue)] || today | |||||
return dfDatetime.format(datetimeFormat) || '' | |||||
case 'radio': | |||||
case 'select': | |||||
const radioItem = item.__sourceData__.find(t => t.value === item.dfvalue) || item.__sourceData__[0] | |||||
return item.type === 'radio' ? radioItem.value : '' | |||||
case 'checkbox': | |||||
if (!item.dfvalue) { | |||||
return [] | |||||
} | |||||
return item.dfvalue.split(',').filter(t => item.__sourceData__.find(s => s.value === t)) | |||||
case 'encode': | |||||
const result = await this.FETCH_ENCODE(item.rulecode) | |||||
return result | |||||
case 'upload': | |||||
return [] | |||||
case 'guid': | |||||
return item.table ? processId : '' | |||||
case 'girdtable': | |||||
const tableItemObj = {} | |||||
for (const fieldItem of item.fieldsData) { | |||||
tableItemObj[fieldItem.field] = await this.getDefaultData(fieldItem, prop) | |||||
} | |||||
return this.COPY(tableItemObj) | |||||
case 'datetimerange': | |||||
return '0' | |||||
default: | |||||
return item.dfvalue || '' | |||||
} | |||||
}, | |||||
/** | |||||
* 将单条 formData 值转化为 formValue 值 (拉取表单数据时使用) | |||||
* 参数: 单个 schemeItem , 数据值 | |||||
* | |||||
* 具体执行逻辑: | |||||
* radio、select: 剔除无效值 | |||||
* checkbox: 分割成数组并剔除无效值 | |||||
* upload: 分割成数组,拉取其中所有文件的信息 | |||||
* datetime: 按照时间日期格式进行格式化字符串 | |||||
* 其他类型: 保留原值 | |||||
*/ | |||||
async convertToFormValue(item, val) { | |||||
switch (item.type) { | |||||
case 'upload': | |||||
if (!val) { return [] } | |||||
const uidList = val.split(',') | |||||
const fileList = [] | |||||
for (const uid of uidList || []) { | |||||
const fileInfo = await this.FETCH_FILEINFO(uid) | |||||
if (!fileInfo) { continue } | |||||
const fileType = fileInfo.F_FileType | |||||
const fileSize = fileInfo.F_FileSize | |||||
const path = this.API + '/learun/adms/annexes/wxdown?' + this.URL_QUERY(uid, true) | |||||
fileList.push({ path, type: fileType, uid, size: fileSize }) | |||||
} | |||||
return fileList | |||||
case 'select': | |||||
case 'radio': | |||||
if (!val || !item.__sourceData__.map(t => t.value).includes(val)) { | |||||
return '' | |||||
} | |||||
return val | |||||
case 'checkbox': | |||||
const validValue = item.__sourceData__.map(t => t.value) | |||||
const checkboxVal = val.split(',') || [] | |||||
return checkboxVal.filter(t => validValue.includes(t)) | |||||
case 'datetime': | |||||
if (!val) { | |||||
return '' | |||||
} | |||||
return moment(val).format( | |||||
Number(item.dateformat) === 0 || item.datetime === 'date' ? | |||||
'YYYY-MM-DD' : | |||||
'YYYY-MM-DD HH:mm:ss' | |||||
) | |||||
default: | |||||
return val || '' | |||||
} | |||||
}, | |||||
/** | |||||
* 将一个 formValue 值转化为 post 提交值(提交表单数据时使用) | |||||
* 参数: 单个 schemeItem , 表单项值 , 所有 formValue , scheme | |||||
* | |||||
* 具体执行逻辑: | |||||
* checkbox: 将数组使用符号「,」逗号拼接成字符串 | |||||
* datetimerange: 获取开始日期、结束日期,计算差值天数并保留整数 | |||||
* datetime: 格式化为完整时间日期字符串 | |||||
* upload: 依次上传文件,将返回的文件 ID 使用符号「,」逗号拼接成字符串 | |||||
* 其他类型: 保留原值 | |||||
*/ | |||||
async convertToPostData(item, val, formValue, scheme) { | |||||
switch (item.type) { | |||||
case 'checkbox': | |||||
return val ? val.join(',') : '' | |||||
case 'datetimerange': | |||||
const startTime = get(formValue, scheme.find(t => t.id === item.startTime).__valuePath__, null) | |||||
const endTime = get(formValue, scheme.find(t => t.id === item.endTime).__valuePath__, null) | |||||
if (!startTime || !endTime || moment(endTime).isBefore(startTime)) { | |||||
return '' | |||||
} else { | |||||
return moment.duration(moment(endTime).diff(moment(startTime))).asDays().toFixed(0) | |||||
} | |||||
case 'datetime': | |||||
return val ? moment(val).format('YYYY-MM-DD HH:mm:ss') : '' | |||||
case 'upload': | |||||
const uploadUid = [] | |||||
// { path, uid } | |||||
for (const item of val) { | |||||
if (item.uid) { | |||||
uploadUid.push(item.uid) | |||||
continue | |||||
} | |||||
const fileId = await this.HTTP_UPLOAD(item.path||item) | |||||
if (fileId) { | |||||
uploadUid.push(fileId) | |||||
} | |||||
} | |||||
return uploadUid.join(',') | |||||
default: | |||||
return val || '' | |||||
} | |||||
} | |||||
} | |||||
methods: { | |||||
/** | |||||
* 获取一个 scheme 表单项的源数据 (加载表单时使用) | |||||
* 参数: 单个 schemeItem | |||||
* | |||||
* radio、select、checkbox、layer 这四种表单项,需要加载额外的选单数据 | |||||
* 选单数据有两种获取方式: | |||||
* 1、来自数据字典: | |||||
* 数据字典在 this.GET_GLOBAL('dataDictionary') | |||||
* 表单使用的字段在 schemeItem.itemCode | |||||
* 选单数据中的 text 字段作为显示, value 字段作为值 | |||||
* | |||||
* 2、来自数据源: | |||||
* 将 schemeItem.dataSourceId 按符号「,」逗号分割为数组,分割为: [code, displayField, valueField] | |||||
* 数据源需要请求 API 来获取,请求需要带上数据源的编号 code | |||||
* displayField、valueField 分别为展示字段和值绑定字段 | |||||
* | |||||
* 选单数据有两种格式: | |||||
* 1、对于 radio、select、checkbox 来说: | |||||
* 只需要一个数组,数组形如: [{ text: '选项文字', value: '选项值' }, ...] | |||||
* 将获取的数据绑定到组件的 range 属性上即可 | |||||
* 全局数据中默认是对象形式,使用 Object.values() 转化即可 | |||||
* | |||||
* 2、对于 layer 来说: | |||||
* 返回一个对象,形如 { source, layerData, selfField } | |||||
* source: 为弹层中列出的数据,是一个数组 | |||||
* layerData: 需要在弹层窗口中展示的字段及标题文字,形如: [{ name:'要展示的字段名', label:'标题文字' }] | |||||
* selfField: 该表单值绑定哪个字段,默认为绑定到自身的字段 | |||||
*/ | |||||
async getSourceData(schemeItem) { | |||||
if (['radio', 'select', 'checkbox'].includes(schemeItem.type)) { | |||||
// radio select checkbox 三种情况 | |||||
if (!schemeItem.dataSource || Number(schemeItem.dataSource) === 0) { | |||||
// dataSource 为 0,使用 clientData | |||||
return Object | |||||
.values(this.GET_GLOBAL('dataDictionary')[schemeItem.itemCode]) | |||||
.map(t => ({ | |||||
value: t.value, | |||||
text: t.text | |||||
})) | |||||
} else { | |||||
// dataSource 不为 0,使用数据源,需要请求接口,并且提取出显示字段和实际字段 | |||||
const [code, displayField = schemeItem.showField, valueField = schemeItem.saveField] = | |||||
schemeItem.dataSourceId | |||||
.split(',') | |||||
const sourceData = await this.FETCH_DATASOURCE(code) | |||||
if (!sourceData) { | |||||
return [] | |||||
} | |||||
return sourceData.data.map(t => ({ | |||||
text: t[displayField], | |||||
value: t[valueField] | |||||
})) | |||||
} | |||||
} else if (['layer'].includes(schemeItem.type)) { | |||||
// layer 需要更多属性 | |||||
if (!schemeItem.dataSource || Number(schemeItem.dataSource) === 0) { | |||||
// dataSource 为 0,使用 clientData | |||||
// clientData 对象转数组后,隐含 key:item.text 和 value:item.value 的关系 | |||||
const [keyItem, valueItem] = schemeItem.layerData | |||||
const source = Object | |||||
.values(this.GET_GLOBAL('dataDictionary')[schemeItem.itemCode]) | |||||
.map(t => ({ | |||||
value: t.value, | |||||
text: t.text | |||||
})) | |||||
return { | |||||
source, | |||||
layerData: [{ | |||||
name: 'text', | |||||
label: keyItem.label || '', | |||||
value: keyItem.value || '' | |||||
}, | |||||
{ | |||||
name: 'value', | |||||
label: valueItem.label || '', | |||||
value: valueItem.value || '' | |||||
} | |||||
] | |||||
} | |||||
} else { | |||||
// dataSource 不为 0,使用数据源,需要请求接口,并且提取出显示字段和实际字段 | |||||
const [code] = schemeItem.dataSourceId.split(',') | |||||
const sourceData = await this.FETCH_DATASOURCE(code) | |||||
if (!sourceData) { | |||||
return [] | |||||
} | |||||
const source = sourceData.data | |||||
return { | |||||
source, | |||||
layerData: schemeItem.layerData.filter(t => (!t.hide) && (t.value || t.label)) | |||||
} | |||||
} | |||||
} | |||||
return [] | |||||
}, | |||||
/** | |||||
* 获取一个 scheme 表单项的默认值 (用户新建表单时使用,或是编辑草稿) | |||||
* 参数: 单个 schemeItem , { processId } | |||||
* | |||||
* 每种类别的表单项分别获取的默认值: | |||||
* | |||||
* currentInfo: 根据类别取当前用户/部门/公司/时间日期 | |||||
* datetime: 根据 dfValue 字段表示昨天/今天/明天,格式化为字符串 | |||||
* radio、select: 有 dfValue 则使用,否则取第一条 | |||||
* checkbox: 有 dfValue 则使用,否则为空数组 | |||||
* encode: 根据 rulecode 请求表单编码 | |||||
* upload: 空数组 | |||||
* guid: 赋值第二个参数中的 processId,但是如果在子表格中,赋空字符串 | |||||
* girdtable: 递归所有表格项 scheme 依次为它们生成默认值 | |||||
* datetimerange: 字符串 0 | |||||
*/ | |||||
async getDefaultData(item, prop) { | |||||
const { | |||||
processId | |||||
} = prop | |||||
switch (item.type) { | |||||
case 'currentInfo': | |||||
switch (item.dataType) { | |||||
case 'user': | |||||
return this.GET_GLOBAL('loginUser').userId | |||||
case 'department': | |||||
return this.GET_GLOBAL('loginUser').departmentId | |||||
case 'company': | |||||
return this.GET_GLOBAL('loginUser').companyId | |||||
case 'time': | |||||
return moment().format('YYYY-MM-DD HH:mm:ss') | |||||
default: | |||||
return '' | |||||
} | |||||
case 'datetime': | |||||
const datetimeFormat = item.table ? | |||||
(Number(item.dateformat) === 0 ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss') : | |||||
(item.datetime === 'datetime' ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD') | |||||
const today = moment() | |||||
const dfDatetime = [ | |||||
today.subtract(1, 'day'), | |||||
today, | |||||
today.add(1, 'day') | |||||
][Number(item.dfvalue)] || today | |||||
return dfDatetime.format(datetimeFormat) || '' | |||||
case 'radio': | |||||
case 'select': | |||||
const radioItem = item.__sourceData__.find(t => t.value === item.dfvalue) || item | |||||
.__sourceData__[0] | |||||
return item.type === 'radio' ? radioItem.value : '' | |||||
case 'checkbox': | |||||
if (!item.dfvalue) { | |||||
return [] | |||||
} | |||||
return item.dfvalue.split(',').filter(t => item.__sourceData__.find(s => s.value === t)) | |||||
case 'encode': | |||||
const result = await this.FETCH_ENCODE(item.rulecode) | |||||
return result | |||||
case 'upload': | |||||
return [] | |||||
case 'guid': | |||||
return item.table ? processId : '' | |||||
case 'girdtable': | |||||
const tableItemObj = {} | |||||
for (const fieldItem of item.fieldsData) { | |||||
tableItemObj[fieldItem.field] = await this.getDefaultData(fieldItem, prop) | |||||
} | |||||
return this.COPY(tableItemObj) | |||||
case 'datetimerange': | |||||
return '0' | |||||
default: | |||||
return item.dfvalue || '' | |||||
} | |||||
}, | |||||
/** | |||||
* 将单条 formData 值转化为 formValue 值 (拉取表单数据时使用) | |||||
* 参数: 单个 schemeItem , 数据值 | |||||
* | |||||
* 具体执行逻辑: | |||||
* radio、select: 剔除无效值 | |||||
* checkbox: 分割成数组并剔除无效值 | |||||
* upload: 分割成数组,拉取其中所有文件的信息 | |||||
* datetime: 按照时间日期格式进行格式化字符串 | |||||
* 其他类型: 保留原值 | |||||
*/ | |||||
async convertToFormValue(item, val) { | |||||
switch (item.type) { | |||||
case 'upload': | |||||
if (!val) { | |||||
return [] | |||||
} | |||||
const uidList = val; | |||||
const fileList = [] | |||||
const wxlist = await this.FETCH_FILEList(uidList); | |||||
for (const wxfile of wxlist) { | |||||
const fileInfo = await this.FETCH_FILEINFO(wxfile.F_Id) | |||||
if (!fileInfo) { | |||||
continue | |||||
} | |||||
const fileType = fileInfo.F_FileType | |||||
const fileSize = fileInfo.F_FileSize | |||||
const path = this.API + '/learun/adms/annexes/wxdown?' + this.URL_QUERY(wxfile.F_Id, true) | |||||
fileList.push({ | |||||
path, | |||||
type: fileType, | |||||
uid:wxfile.F_Id, | |||||
folderId:wxfile.F_FolderId, | |||||
size: fileSize | |||||
}) | |||||
} | |||||
return fileList | |||||
case 'select': | |||||
case 'radio': | |||||
if (!val || !item.__sourceData__.map(t => t.value).includes(val)) { | |||||
return '' | |||||
} | |||||
return val | |||||
case 'checkbox': | |||||
const validValue = item.__sourceData__.map(t => t.value) | |||||
const checkboxVal = val.split(',') || [] | |||||
return checkboxVal.filter(t => validValue.includes(t)) | |||||
case 'datetime': | |||||
if (!val) { | |||||
return '' | |||||
} | |||||
return moment(val).format( | |||||
Number(item.dateformat) === 0 || item.datetime === 'date' ? | |||||
'YYYY-MM-DD' : | |||||
'YYYY-MM-DD HH:mm:ss' | |||||
) | |||||
default: | |||||
return val || '' | |||||
} | |||||
}, | |||||
/** | |||||
* 将一个 formValue 值转化为 post 提交值(提交表单数据时使用) | |||||
* 参数: 单个 schemeItem , 表单项值 , 所有 formValue , scheme | |||||
* | |||||
* 具体执行逻辑: | |||||
* checkbox: 将数组使用符号「,」逗号拼接成字符串 | |||||
* datetimerange: 获取开始日期、结束日期,计算差值天数并保留整数 | |||||
* datetime: 格式化为完整时间日期字符串 | |||||
* upload: 依次上传文件,将返回的文件 ID 使用符号「,」逗号拼接成字符串 | |||||
* 其他类型: 保留原值 | |||||
*/ | |||||
async convertToPostData(item, val, formValue, scheme, guid) { | |||||
switch (item.type) { | |||||
case 'checkbox': | |||||
return val ? val.join(',') : '' | |||||
case 'datetimerange': | |||||
const startTime = get(formValue, scheme.find(t => t.id === item.startTime).__valuePath__, null) | |||||
const endTime = get(formValue, scheme.find(t => t.id === item.endTime).__valuePath__, null) | |||||
if (!startTime || !endTime || moment(endTime).isBefore(startTime)) { | |||||
return '' | |||||
} else { | |||||
return moment.duration(moment(endTime).diff(moment(startTime))).asDays().toFixed(0) | |||||
} | |||||
case 'datetime': | |||||
return val ? moment(val).format('YYYY-MM-DD HH:mm:ss') : '' | |||||
case 'upload': | |||||
var uploadUid = ''; | |||||
for (const item of val) { | |||||
if (item.uid) { | |||||
uploadUid = item.uid | |||||
continue | |||||
} | |||||
const fileId = await this.HTTP_UPLOAD(item.path || item, undefined, guid || '') | |||||
if (fileId) { | |||||
uploadUid = fileId; | |||||
} | |||||
} | |||||
return uploadUid; | |||||
default: | |||||
return val || '' | |||||
} | |||||
} | |||||
} | |||||
} | } |
@@ -1,3 +1,4 @@ | |||||
import { conforms } from 'lodash' | |||||
import get from 'lodash/get' | import get from 'lodash/get' | ||||
import omit from 'lodash/omit' | import omit from 'lodash/omit' | ||||
import moment from 'moment' | import moment from 'moment' | ||||
@@ -233,7 +234,11 @@ export default { | |||||
} else { | } else { | ||||
for (const [fieldName, scheme] of Object.entries(schemeItem)) { | for (const [fieldName, scheme] of Object.entries(schemeItem)) { | ||||
const dataSource = get(this.dataSource, `${tableName}.${fieldName}`) | const dataSource = get(this.dataSource, `${tableName}.${fieldName}`) | ||||
data[tableName][fieldName] = await this.convertToFormValue(scheme, data[tableName][fieldName], dataSource) | |||||
if(data[tableName]){ | |||||
data[tableName][fieldName] = await this.convertToFormValue(scheme, data[tableName][fieldName], dataSource) | |||||
}else{ | |||||
this.scheme[tableName][fieldName] = await this.convertToFormValue(scheme, this.scheme[tableName][fieldName], dataSource) | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -257,7 +262,6 @@ export default { | |||||
const fileSize = fileInfo.F_FileSize | const fileSize = fileInfo.F_FileSize | ||||
const path = this.API + '/learun/adms/annexes/wxdown?' + this.URL_QUERY(uid, true) | const path = this.API + '/learun/adms/annexes/wxdown?' + this.URL_QUERY(uid, true) | ||||
fileList.push({ path, type: fileType, uid, size: fileSize }) | fileList.push({ path, type: fileType, uid, size: fileSize }) | ||||
} | } | ||||
return fileList | return fileList | ||||
@@ -229,6 +229,14 @@ export default { | |||||
return await this.HTTP_GET('learun/adms/annexes/wxfileinfo', fileId) | return await this.HTTP_GET('learun/adms/annexes/wxfileinfo', fileId) | ||||
}, | }, | ||||
//获取文件夹下文件列表 | |||||
async FETCH_FILEList(folderId) { | |||||
if (!folderId) { | |||||
return null | |||||
} | |||||
return await this.HTTP_GET('learun/adms/annexes/wxlist', folderId) | |||||
}, | |||||
// 封装的 GET 请求,集成了验证信息 | // 封装的 GET 请求,集成了验证信息 | ||||
// 返回请求结果或 null | // 返回请求结果或 null | ||||
@@ -258,8 +266,8 @@ export default { | |||||
// url 为请求地址 | // url 为请求地址 | ||||
// filePath 为临时文件的路径 | // filePath 为临时文件的路径 | ||||
// formData 为请求附带的提交数据 | // formData 为请求附带的提交数据 | ||||
async HTTP_UPLOAD(filePath, formData) { | |||||
const [err, res] = await this.UPLOAD('/learun/adms/annexes/wxupload', filePath, formData) | |||||
async HTTP_UPLOAD(filePath, formData,guid) { | |||||
const [err, res] = await this.UPLOAD('/learun/adms/annexes/wxupload', filePath, formData,guid) | |||||
return this.handleResult(err, res) | return this.handleResult(err, res) | ||||
}, | }, | ||||
@@ -308,11 +316,12 @@ export default { | |||||
// 返回结果是一个数组: [error, result] | // 返回结果是一个数组: [error, result] | ||||
// error 表示错误,一般是网络错误,请求很可能根本没有发出 | // error 表示错误,一般是网络错误,请求很可能根本没有发出 | ||||
// result 包含 { statusCode, data } 分别表示状态码、接口返回的数据 | // result 包含 { statusCode, data } 分别表示状态码、接口返回的数据 | ||||
async UPLOAD(url, filePath, formData) { | |||||
async UPLOAD(url, filePath, formData,guid) { | |||||
const uploadUrl = this.handleUrl(url) | const uploadUrl = this.handleUrl(url) | ||||
const query = { | const query = { | ||||
loginMark: this.getLoginMark(), | loginMark: this.getLoginMark(), | ||||
token: this.GET_GLOBAL('token') | |||||
token: this.GET_GLOBAL('token'), | |||||
folderId:guid | |||||
} | } | ||||
if (formData && typeof formData === 'object') { | if (formData && typeof formData === 'object') { | ||||
@@ -683,13 +692,13 @@ export default { | |||||
if(result.data.code != 200){ | if(result.data.code != 200){ | ||||
uni.hideLoading() | uni.hideLoading() | ||||
uni.showToast({ | uni.showToast({ | ||||
title: tips||result.data.info||"未知错误", | |||||
title: result.data.info, | |||||
icon: 'none' | icon: 'none' | ||||
}) | }) | ||||
return null | return null | ||||
} | } | ||||
return result.data.data||true | |||||
return result.data.data | |||||
}, | }, | ||||
// 【即将废弃】请使用 this.CONFIG() 来替代 | // 【即将废弃】请使用 this.CONFIG() 来替代 | ||||
@@ -194,12 +194,14 @@ export default { | |||||
// 依次验证表单项,返回一个所有错误提示的数组,如果为空数组则表示无错误 | // 依次验证表单项,返回一个所有错误提示的数组,如果为空数组则表示无错误 | ||||
verifyValue() { | verifyValue() { | ||||
const errorList = [] | const errorList = [] | ||||
console.log(this.scheme) | |||||
this.scheme | this.scheme | ||||
.filter(t => t.verify) | .filter(t => t.verify) | ||||
.forEach(schemeItem => { | .forEach(schemeItem => { | ||||
if (schemeItem.table && schemeItem.field) { | if (schemeItem.table && schemeItem.field) { | ||||
console.log(schemeItem.verify,'hemeItem.verify') | |||||
const verifyFunc = this.verify[schemeItem.verify] | const verifyFunc = this.verify[schemeItem.verify] | ||||
console.log(schemeItem.verify) | |||||
const verifyResult = verifyFunc(this.getValue(schemeItem.__valuePath__)) | const verifyResult = verifyFunc(this.getValue(schemeItem.__valuePath__)) | ||||
if (verifyResult !== true) { | if (verifyResult !== true) { | ||||
errorList.push(`[${schemeItem.title}]: ${verifyResult}`) | errorList.push(`[${schemeItem.title}]: ${verifyResult}`) | ||||
@@ -304,7 +306,8 @@ export default { | |||||
MobileOrPhoneOrNull: t => | MobileOrPhoneOrNull: t => | ||||
t.length <= 0 || /^1[0-9]{10}$/.test(t) || /^[+0-9- ]*$/.test(t) || '须留空或符合手机/电话号码格式', | t.length <= 0 || /^1[0-9]{10}$/.test(t) || /^[+0-9- ]*$/.test(t) || '须留空或符合手机/电话号码格式', | ||||
Uri: t => /^[a-zA-z]+:\/\/[^\s]*$/.test(t) || '须符合网址Url格式', | Uri: t => /^[a-zA-z]+:\/\/[^\s]*$/.test(t) || '须符合网址Url格式', | ||||
UriOrNull: t => t.length <= 0 || /^[a-zA-z]+:\/\/[^\s]*$/.test(t) || '须留空或符合网址Url格式' | |||||
UriOrNull: t => t.length <= 0 || /^[a-zA-z]+:\/\/[^\s]*$/.test(t) || '须留空或符合网址Url格式', | |||||
PositiveFloatint:t=> /^([1-9]\d*|(0|[1-9]\d*)\.\d*[1-9])$/.test(t) || '请输入正确的整数或小数(不能为零和负数)' | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -89,7 +89,7 @@ export default { | |||||
// #endif | // #endif | ||||
// #ifndef MP-DINGTALK | // #ifndef MP-DINGTALK | ||||
uni.chooseImage({ | |||||
uni.chooseFile({ | |||||
count: Number(this.number), | count: Number(this.number), | ||||
sizeType: ['original', 'compressed'], | sizeType: ['original', 'compressed'], | ||||
sourceType: ['album', 'camera'], | sourceType: ['album', 'camera'], | ||||
@@ -1,296 +1,293 @@ | |||||
<template> | <template> | ||||
<view class="cu-form-group"> | |||||
<view class="grid col-4 grid-square flex-sub"> | |||||
<view | |||||
v-for="(item, index) in imgList" | |||||
@tap="viewImg(item)" | |||||
:key="index" | |||||
class="bg-img" | |||||
> | |||||
<!-- {{API + '/user/img?data=' + (path.path ? path.path : path)}} --> | |||||
<image | |||||
v-if="showfile()&&isImage(item.type)" | |||||
:src="CONFIG('webHost') + item.url" | |||||
mode="aspectFill" | |||||
></image> | |||||
<l-icon v-if="showfile()&&!isImage(item.type)" type="text" /> | |||||
<text class="file-name">{{item.name}}</text> | |||||
<view v-if="!readonly" @tap.stop="delImg(index)" class="cu-tag bg-red" style="width: 18px; height: 18px; font-size: 24px"> | |||||
<l-icon | |||||
type="close" | |||||
style="width: 18px; height: 18px; font-size: 12px" | |||||
/> | |||||
</view> | |||||
</view> | |||||
<view class="cu-form-group"> | |||||
<view class="grid col-4 grid-square flex-sub"> | |||||
<view v-for="(item, index) in imgList" @tap="viewImg(item)" :key="index" class="bg-img"> | |||||
<image v-if="showfile()&&isImage(item.type)" :src="CONFIG('webHost') + item.url" mode="aspectFill"> | |||||
</image> | |||||
<l-icon v-if="showfile()&&!isImage(item.type)" type="text" /> | |||||
<text class="file-name">{{item.name}}</text> | |||||
<view v-if="!readonly" @tap.stop="delImg(index)" class="cu-tag bg-red" | |||||
style="width: 18px; height: 18px; font-size: 24px"> | |||||
<l-icon type="close" style="width: 18px; height: 18px; font-size: 12px" /> | |||||
</view> | |||||
</view> | |||||
<view v-show="!readonly && imgList.length < Number(number)&&isShow" class="solids"> | |||||
<!-- @tap="chooseImg" --> | |||||
<l-icon type="file" /> | |||||
<lsj-upload ref="lsjUpload" height="80px" width="100%" :size="20" :option="{}" :count="1" | |||||
@change="chooseChange" style="opacity: 0;"></lsj-upload> | |||||
</view> | |||||
</view> | |||||
</view> | |||||
<view | |||||
v-show="!readonly && imgList.length < Number(number)&&isShow" | |||||
class="solids" | |||||
> | |||||
<!-- @tap="chooseImg" --> | |||||
<l-icon type="file" /> | |||||
<lsj-upload | |||||
ref="lsjUpload" | |||||
height="80px" | |||||
width="100%" | |||||
:size="20" | |||||
:option="{}" | |||||
:count="1" | |||||
@change="chooseChange" | |||||
style="opacity: 0;" | |||||
></lsj-upload> | |||||
</view> | |||||
</view> | |||||
</view> | |||||
</template> | </template> | ||||
<script> | <script> | ||||
export default { | |||||
export default { | |||||
props: { | |||||
number: { default: 1 }, | |||||
readonly: {}, | |||||
value: { default: () => [] }, | |||||
folderId:{}, | |||||
}, | |||||
data(){ | |||||
return{ | |||||
isShow:false, | |||||
imgList:[], | |||||
} | |||||
}, | |||||
props: { | |||||
number: { | |||||
default: 1 | |||||
}, | |||||
readonly: {}, | |||||
value: { | |||||
default: () => [] | |||||
}, | |||||
folderId: {}, | |||||
}, | |||||
methods: { | |||||
chooseChange(files){ | |||||
let array = Array.from(files); | |||||
if(array.length){ | |||||
this.$refs.lsjUpload.clear() | |||||
} | |||||
let tempFilePaths = [],tempFiles=[]; | |||||
array.forEach(item=>{ | |||||
tempFilePaths.push(item[1].path) | |||||
tempFiles.push(item[1].file) | |||||
}) | |||||
this.chooseChangeback(tempFilePaths,tempFiles) | |||||
}, | |||||
delImg(index) { | |||||
this.LOADING('正在删除…'); | |||||
const newList = JSON.parse(JSON.stringify(this.imgList)); | |||||
this.HTTP_POST('StuInfoFresh/deleteFiles', {id:this.imgList[index].id},"文件删除失败").then((data) => { | |||||
this.HIDE_LOADING(); | |||||
if (data) { | |||||
newList.splice(index, 1); | |||||
this.imgList = newList | |||||
this.$emit("update:value", newList); | |||||
this.$emit("input", newList); | |||||
this.$emit("change"); | |||||
this.$emit("del"); | |||||
data() { | |||||
return { | |||||
isShow: false, | |||||
imgList: [], | |||||
} | } | ||||
}) | |||||
}, | |||||
showfile() { | |||||
return true; | |||||
}, | |||||
async chooseChangeback(tempFilePaths,tempFiles) { | |||||
// let {tempFilePaths,tempFiles} = res | |||||
// if(!this.validate(tempFiles))return | |||||
let uploadImageRes = await this.uploadImage(tempFilePaths[0],tempFiles[0]?tempFiles[0].name:"") | |||||
let newList = this.imgList || [] | |||||
if(uploadImageRes){ | |||||
newList = JSON.parse(JSON.stringify(newList)).concat(uploadImageRes); | |||||
} | |||||
this.imgList = newList | |||||
this.$emit("update:value", newList); | |||||
this.$emit("input", newList); | |||||
this.$emit("change",newList); | |||||
this.$emit("add"); | |||||
}, | |||||
uploadImage(url,name){ | |||||
if(!url)return | |||||
// 文件上传 | |||||
return new Promise(async (reslove,reject)=>{ | |||||
this.LOADING('正在上传…'); | |||||
let params = name?{folderId:this.folderId,name}:{folderId:this.folderId} | |||||
this.HTTP_UPLOAD2('StuInfoFresh/upload', url,params).then((data) => { | |||||
this.HIDE_LOADING(); | |||||
this.$refs.lsjUpload.show() | |||||
if (data) { | |||||
// this.HTTP_GET('StuInfoFresh/upload', {fileId:data}) | |||||
reslove([{ | |||||
id:data.F_Id, | |||||
name:data.F_FileName, | |||||
url:data.F_FilePath, | |||||
type:data.F_FileType, | |||||
}]) | |||||
}else{ | |||||
reject('上传失败!') | |||||
}, | |||||
methods: { | |||||
chooseChange(files) { | |||||
let array = Array.from(files); | |||||
if (array.length) { | |||||
this.$refs.lsjUpload.clear() | |||||
} | } | ||||
}) | |||||
}) | |||||
}, | |||||
ceshi(){ | |||||
function apiFn(params){ | |||||
return new Promise((resolve,reject)=>{ | |||||
this.LOADING('正在上传…'); | |||||
this.HTTP_UPLOAD2('StuInfoFresh/upload', params.url,{folderId:this.folderId}).then((data) => { | |||||
this.HIDE_LOADING(); | |||||
if (data) { | |||||
// this.HTTP_GET('StuInfoFresh/upload', {fileId:data}) | |||||
this.imgList[params.index] = [{ | |||||
id:data.F_Id, | |||||
name:data.F_FileName, | |||||
url:data.F_FilePath, | |||||
type:data.F_FileType | |||||
}] | |||||
reslove(this.imgList[params.index]) | |||||
}else{ | |||||
reject('上传失败!') | |||||
let tempFilePaths = [], | |||||
tempFiles = []; | |||||
array.forEach(item => { | |||||
tempFilePaths.push(item[1].path) | |||||
tempFiles.push(item[1].file) | |||||
}) | |||||
this.chooseChangeback(tempFilePaths, tempFiles) | |||||
}, | |||||
delImg(index) { | |||||
this.CONFIRM("", "是否确认删除?", true).then(res => { | |||||
if(!res)return | |||||
this.LOADING('正在删除…'); | |||||
const newList = JSON.parse(JSON.stringify(this.imgList)); | |||||
this.HTTP_POST('StuInfoFresh/deleteFiles', { | |||||
id: this.imgList[index].id | |||||
}, "文件删除失败").then((data) => { | |||||
this.HIDE_LOADING(); | |||||
if (data) { | |||||
newList.splice(index, 1); | |||||
this.imgList = newList | |||||
this.$emit("update:value", newList); | |||||
this.$emit("input", newList); | |||||
this.$emit("change"); | |||||
this.$emit("del"); | |||||
} | |||||
}) | |||||
}) | |||||
}, | |||||
showfile() { | |||||
return true; | |||||
}, | |||||
async chooseChangeback(tempFilePaths, tempFiles) { | |||||
// let {tempFilePaths,tempFiles} = res | |||||
// if(!this.validate(tempFiles))return | |||||
let uploadImageRes = await this.uploadImage(tempFilePaths[0], tempFiles[0] ? tempFiles[0].name : "") | |||||
let newList = this.imgList || [] | |||||
if (uploadImageRes) { | |||||
newList = JSON.parse(JSON.stringify(newList)).concat(uploadImageRes); | |||||
} | |||||
this.imgList = newList | |||||
this.$emit("update:value", newList); | |||||
this.$emit("input", newList); | |||||
this.$emit("change", newList); | |||||
// this.$emit("add"); | |||||
}, | |||||
uploadImage(url, name) { | |||||
if (!url) return | |||||
// 文件上传 | |||||
return new Promise(async (reslove, reject) => { | |||||
this.LOADING('正在上传…'); | |||||
let params = name ? { | |||||
folderId: this.folderId, | |||||
name | |||||
} : { | |||||
folderId: this.folderId | |||||
} | } | ||||
this.HTTP_UPLOAD2('StuInfoFresh/upload', url, params).then((data) => { | |||||
this.HIDE_LOADING(); | |||||
this.$refs.lsjUpload.show() | |||||
if (data) { | |||||
// this.HTTP_GET('StuInfoFresh/upload', {fileId:data}) | |||||
reslove([{ | |||||
id: data.F_Id, | |||||
name: data.F_FileName, | |||||
url: data.F_FilePath, | |||||
type: data.F_FileType, | |||||
}]) | |||||
} else { | |||||
reject('上传失败!') | |||||
} | |||||
}) | |||||
}) | }) | ||||
}) | |||||
} | |||||
let array = this.imgList.map(item=>{ | |||||
if(item.id){ | |||||
return "" | |||||
}else{ | |||||
return { | |||||
url:"learun/adms/annexes/upload" | |||||
}, | |||||
ceshi() { | |||||
function apiFn(params) { | |||||
return new Promise((resolve, reject) => { | |||||
this.LOADING('正在上传…'); | |||||
this.HTTP_UPLOAD2('StuInfoFresh/upload', params.url, { | |||||
folderId: this.folderId | |||||
}).then((data) => { | |||||
this.HIDE_LOADING(); | |||||
if (data) { | |||||
// this.HTTP_GET('StuInfoFresh/upload', {fileId:data}) | |||||
this.imgList[params.index] = [{ | |||||
id: data.F_Id, | |||||
name: data.F_FileName, | |||||
url: data.F_FilePath, | |||||
type: data.F_FileType | |||||
}] | |||||
reslove(this.imgList[params.index]) | |||||
} else { | |||||
reject('上传失败!') | |||||
} | |||||
}) | |||||
}) | |||||
} | } | ||||
} | |||||
}) | |||||
this.promiseAllLimit(2,[1,2,3,4,5,6,7,8,9],a).then(res=>{ | |||||
console.log(res) | |||||
}) | |||||
}, | |||||
/** | |||||
* @description 控制promise.all并发数量 | |||||
* @param limit 并发数 | |||||
* @param array 参数列表 | |||||
* @param apiFn 执行函数 | |||||
* @returns {Promise<Awaited<unknown>[]>} | |||||
*/ | |||||
async promiseAllLimit(limit, array, apiFn) { | |||||
const ret = [] // 用于存放所有的promise实例 | |||||
const executing = [] // 用于存放目前正在执行的promise | |||||
for (const item of array) { | |||||
const p = apiFn(item) | |||||
ret.push(p) | |||||
if (limit <= array.length) { | |||||
// then回调中,当这个promise状态变为fulfilled后,将其从正在执行的promise列表executing中删除 | |||||
const e = p.then(() => executing.splice(executing.indexOf(e), 1)) | |||||
executing.push(e) | |||||
if (executing.length >= limit) { | |||||
// 一旦正在执行的promise列表数量等于限制数,就使用Promise.race等待某一个promise状态发生变更, | |||||
// 状态变更后,就会执行上面then的回调,将该promise从executing中删除, | |||||
// 然后再进入到下一次for循环,生成新的promise进行补充 | |||||
await Promise.race(executing) | |||||
let array = this.imgList.map(item => { | |||||
if (item.id) { | |||||
return "" | |||||
} else { | |||||
return { | |||||
url: "learun/adms/annexes/upload" | |||||
} | |||||
} | |||||
}) | |||||
this.promiseAllLimit(2, [1, 2, 3, 4, 5, 6, 7, 8, 9], a).then(res => { | |||||
console.log(res) | |||||
}) | |||||
}, | |||||
/** | |||||
* @description 控制promise.all并发数量 | |||||
* @param limit 并发数 | |||||
* @param array 参数列表 | |||||
* @param apiFn 执行函数 | |||||
* @returns {Promise<Awaited<unknown>[]>} | |||||
*/ | |||||
async promiseAllLimit(limit, array, apiFn) { | |||||
const ret = [] // 用于存放所有的promise实例 | |||||
const executing = [] // 用于存放目前正在执行的promise | |||||
for (const item of array) { | |||||
const p = apiFn(item) | |||||
ret.push(p) | |||||
if (limit <= array.length) { | |||||
// then回调中,当这个promise状态变为fulfilled后,将其从正在执行的promise列表executing中删除 | |||||
const e = p.then(() => executing.splice(executing.indexOf(e), 1)) | |||||
executing.push(e) | |||||
if (executing.length >= limit) { | |||||
// 一旦正在执行的promise列表数量等于限制数,就使用Promise.race等待某一个promise状态发生变更, | |||||
// 状态变更后,就会执行上面then的回调,将该promise从executing中删除, | |||||
// 然后再进入到下一次for循环,生成新的promise进行补充 | |||||
await Promise.race(executing) | |||||
} | |||||
} | |||||
} | } | ||||
} | |||||
} | |||||
return Promise.all(ret) | |||||
}, | |||||
validate(array){ | |||||
// let type = array.every(item=>{ | |||||
// return item.type && item.type.substring(0,6) == "image/" | |||||
// }) | |||||
// if(!type){ | |||||
// this.TOAST('文件类型错误'); | |||||
// return false | |||||
// } | |||||
let size = array.every(item=>{ | |||||
return item.size && item.size <= 200 * 1024 * 1024 | |||||
}) | |||||
if(!size){ | |||||
this.TOAST('文件大小不得超过200M'); | |||||
return false | |||||
} | |||||
return true | |||||
}, | |||||
isImage(type){ | |||||
if(type&&type.length){ | |||||
return ["png","jpg"].includes(type.substring(type.length-3,type.length)) | |||||
}else{ | |||||
return false | |||||
} | |||||
}, | |||||
return Promise.all(ret) | |||||
}, | |||||
viewImg(item) { | |||||
if(!this.isImage(item.type)){ | |||||
window.location.href = this.CONFIG("webHost")+item.url | |||||
}else{ | |||||
uni.previewImage({ | |||||
urls: [this.CONFIG('webHost')+item.url], | |||||
current: this.CONFIG('webHost')+item.url | |||||
}); | |||||
} | |||||
}, | |||||
// previewFile() { | |||||
// var file = document.querySelector('input[type=file]').files[0]; | |||||
// var reader = new FileReader(); | |||||
// // fileReader.readAsDataURL(blob); | |||||
// // fileReader.onerror = () => { | |||||
// // reject(new Error('blobToBase64 error')); | |||||
// // }; | |||||
// // var encodedData = window.btoa("Hello, world"); | |||||
// reader.onloadend = function () { | |||||
// //$('#PhotoImg').attr('src', reader.result); | |||||
// var postData = { | |||||
// Base64Url: reader.result | |||||
// } | |||||
// this.HTTP_POST(config.webapi + "StuInfoFresh/savePhoto", postData, (data) => { | |||||
// if (data) { | |||||
// $('#Photo').val(data.AnnexesFileId); | |||||
// $('#PhotoImg').attr('src', config.web + data.Url); | |||||
// } else { | |||||
// learun.layer.toast('采集照片信息失败!'); | |||||
// } | |||||
// }); | |||||
// } | |||||
// if (file) { | |||||
// reader.readAsDataURL(file); | |||||
// } | |||||
// }, | |||||
}, | |||||
created() { | |||||
this.imgList = JSON.parse(JSON.stringify(this.value.map(item=>{ | |||||
return { | |||||
id:item.F_Id, | |||||
name:item.F_FileName, | |||||
url:item.F_FilePath, | |||||
type:item.F_FileType | |||||
validate(array) { | |||||
// let type = array.every(item=>{ | |||||
// return item.type && item.type.substring(0,6) == "image/" | |||||
// }) | |||||
// if(!type){ | |||||
// this.TOAST('文件类型错误'); | |||||
// return false | |||||
// } | |||||
let size = array.every(item => { | |||||
return item.size && item.size <= 200 * 1024 * 1024 | |||||
}) | |||||
if (!size) { | |||||
this.TOAST('文件大小不得超过200M'); | |||||
return false | |||||
} | |||||
return true | |||||
}, | |||||
isImage(type) { | |||||
if (type && type.length) { | |||||
return ["png", "jpg"].includes(type.substring(type.length - 3, type.length)) | |||||
} else { | |||||
return false | |||||
} | |||||
}, | |||||
viewImg(item) { | |||||
if (!this.isImage(item.type)) { | |||||
window.location.href = this.CONFIG("webHost") + item.url | |||||
} else { | |||||
uni.previewImage({ | |||||
urls: [this.CONFIG('webHost') + item.url], | |||||
current: this.CONFIG('webHost') + item.url | |||||
}); | |||||
} | |||||
}, | |||||
// previewFile() { | |||||
// var file = document.querySelector('input[type=file]').files[0]; | |||||
// var reader = new FileReader(); | |||||
// // fileReader.readAsDataURL(blob); | |||||
// // fileReader.onerror = () => { | |||||
// // reject(new Error('blobToBase64 error')); | |||||
// // }; | |||||
// // var encodedData = window.btoa("Hello, world"); | |||||
// reader.onloadend = function () { | |||||
// //$('#PhotoImg').attr('src', reader.result); | |||||
// var postData = { | |||||
// Base64Url: reader.result | |||||
// } | |||||
// this.HTTP_POST(config.webapi + "StuInfoFresh/savePhoto", postData, (data) => { | |||||
// if (data) { | |||||
// $('#Photo').val(data.AnnexesFileId); | |||||
// $('#PhotoImg').attr('src', config.web + data.Url); | |||||
// } else { | |||||
// learun.layer.toast('采集照片信息失败!'); | |||||
// } | |||||
// }); | |||||
// } | |||||
// if (file) { | |||||
// reader.readAsDataURL(file); | |||||
// } | |||||
// }, | |||||
}, | |||||
created() { | |||||
console.log(this.value) | |||||
this.imgList = JSON.parse(JSON.stringify(this.value.map(item => { | |||||
return { | |||||
id: item.F_Id, | |||||
name: item.F_FileName, | |||||
url: item.F_FilePath, | |||||
type: item.F_FileType | |||||
} | |||||
}))) | |||||
this.$nextTick(() => { | |||||
this.isShow = true | |||||
}) | |||||
} | } | ||||
}))) | |||||
this.$nextTick(()=>{ | |||||
this.isShow = true | |||||
}) | |||||
} | |||||
}; | |||||
}; | |||||
</script> | </script> | ||||
<style scoped> | <style scoped> | ||||
.file-name{ | |||||
.file-name { | |||||
position: absolute; | position: absolute; | ||||
bottom: 0; | bottom: 0; | ||||
width: 100%; | width: 100%; | ||||
color: #606266; | color: #606266; | ||||
font-size: 13px; | font-size: 13px; | ||||
text-align: center; | text-align: center; | ||||
background-color: rgba(255,255,255,0.6); | |||||
background-color: rgba(255, 255, 255, 0.6); | |||||
text-overflow: ellipsis; | text-overflow: ellipsis; | ||||
overflow: hidden; | overflow: hidden; | ||||
white-space: nowrap; | white-space: nowrap; | ||||
@@ -21,10 +21,10 @@ export default { | |||||
// "http://192.168.2.98:8088/" | // "http://192.168.2.98:8088/" | ||||
// ], | // ], | ||||
"apiHost": [ | "apiHost": [ | ||||
"http://192.168.10.68:8002/" | |||||
// "http://192.168.10.85:8088/" | |||||
"http://192.168.10.58:8012/" | |||||
// "http://123.57.209.16:31173/" | |||||
], | ], | ||||
"webHost":"http://localhost:20472/", | |||||
"webHost":"http://demo.bjquanjiang.com:8081/", | |||||
// 开发环境下自动填充登录账号密码,与接口地址一一对应,只在开发环境下显示 | // 开发环境下自动填充登录账号密码,与接口地址一一对应,只在开发环境下显示 | ||||
"devAccount": [ | "devAccount": [ | ||||
// 20201130230 21364200000400266 老师 420528196310072253 学生 420528200606205026 420528200507261428 | // 20201130230 21364200000400266 老师 420528196310072253 学生 420528200606205026 420528200507261428 | ||||
@@ -119,7 +119,7 @@ | |||||
"quickapp" : {}, | "quickapp" : {}, | ||||
/* 小程序特有相关 */ | /* 小程序特有相关 */ | ||||
"mp-weixin" : { | "mp-weixin" : { | ||||
"appid" : "wxbc18c9bf92c86d28", | |||||
"appid" : "wx36f8c96ee26af75b", | |||||
"setting" : { | "setting" : { | ||||
"urlCheck" : false, | "urlCheck" : false, | ||||
"es6" : true, | "es6" : true, | ||||
@@ -1028,6 +1028,15 @@ | |||||
} | } | ||||
} | } | ||||
,{ | |||||
"path" : "pages/onlienpay/payInvioce", | |||||
"style" : | |||||
{ | |||||
"navigationBarTitleText": "", | |||||
"enablePullDownRefresh": false | |||||
} | |||||
} | |||||
], | ], | ||||
// 全局样式 | // 全局样式 | ||||
@@ -3,7 +3,8 @@ | |||||
<!-- 主列表页 --> | <!-- 主列表页 --> | ||||
<view :class="sideOpen ? 'show' : ''" class="mainpage" style="padding-top: 80rpx;"> | <view :class="sideOpen ? 'show' : ''" class="mainpage" style="padding-top: 80rpx;"> | ||||
<!-- 顶部条目/分页信息栏 --> | <!-- 顶部条目/分页信息栏 --> | ||||
<l-customlist-banner @buttonClick="sideOpen = true">{{ tips }}</l-customlist-banner> | |||||
<!-- @buttonClick="sideOpen = true" --> | |||||
<l-customlist-banner @buttonClick="">{{ tips }}</l-customlist-banner> | |||||
<!-- 滚动列表,跨端支持上拉/下拉 --> | <!-- 滚动列表,跨端支持上拉/下拉 --> | ||||
<l-scroll-list v-if="ready" @pullDown="pullDown" @toBottom="fetchList()" ref="list"> | <l-scroll-list v-if="ready" @pullDown="pullDown" @toBottom="fetchList()" ref="list"> | ||||
@@ -26,14 +27,14 @@ | |||||
{{ displayListItem(item, 'EmpName') }} | {{ displayListItem(item, 'EmpName') }} | ||||
</view> | </view> | ||||
<view class="customlist-item-field"> | |||||
<view class="customlist-item-field"> | |||||
<text class="customlist-item-field-title">课程名称:</text> | <text class="customlist-item-field-title">课程名称:</text> | ||||
{{ displayListItem(item, 'LessonName') }} | |||||
{{ displayListItem(item, 'LessonName') }} | |||||
</view> | </view> | ||||
<view class="customlist-item-field"> | <view class="customlist-item-field"> | ||||
<text class="customlist-item-field-title">评教状态:</text> | <text class="customlist-item-field-title">评教状态:</text> | ||||
{{ displayListItem(item, 'UID') }} | {{ displayListItem(item, 'UID') }} | ||||
</view> | |||||
</view> | |||||
<l-customlist-action @view="action('view', item)" /> | <l-customlist-action @view="action('view', item)" /> | ||||
@@ -1,69 +1,63 @@ | |||||
<template> | <template> | ||||
<view class="page"> | <view class="page"> | ||||
<view v-if="ready"> | |||||
<l-input | |||||
@input="setValue('JournalSend.JTitle', $event)" | |||||
:value="getValue('JournalSend.JTitle')" | |||||
:disabled="!edit" | |||||
title="上课是否迟到" | |||||
/> | |||||
<l-select | |||||
@input="setValue('JournalSend.JTypeId', $event)" | |||||
:value="getValue('JournalSend.JTypeId')" | |||||
:disabled="!edit" | |||||
:range="dataSource.JournalSend.JTypeId" | |||||
title="是否拖堂" | |||||
/> | |||||
<l-organize-picker | |||||
@input="setValue('JournalSend.JReceiveId', $event)" | |||||
:value="getValue('JournalSend.JReceiveId')" | |||||
:readonly="!edit" | |||||
type="user" | |||||
title="作业量是否合理" | |||||
/> | |||||
<l-textarea | |||||
@input="setValue('JournalSend.JContent', $event)" | |||||
:value="getValue('JournalSend.JContent')" | |||||
:readonly="!edit" | |||||
title="对老师还有什么建议" | |||||
/> | |||||
</view> | |||||
<view v-if="ready"> | |||||
<!-- <l-input v-model="text" disabled title="你说呢你说呢?"></l-input> | |||||
<radio-group> | |||||
<l-radio v-model="radioValue" title="单选框1" radioValue="1" /> | |||||
<l-radio v-model="radioValue" title="单选框2" radioValue="2" /> | |||||
</radio-group> --> | |||||
<view v-for="(item,index) in formData.Eval_Questions" :key="item.QID"> | |||||
<view class="questionTitle"> | |||||
<text style="color: red;">{{item.QMust?"* ":""}}</text> | |||||
{{item.QTitle}} | |||||
</view> | |||||
<!-- 单选 --> | |||||
<l-select | |||||
v-if="item.QType == 1" | |||||
v-model="aa" | |||||
:range="item.Eval_QuestionItems" | |||||
title="" | |||||
placeholder="请选择" | |||||
:disabled="false" | |||||
textField="ITitle" | |||||
valueField="IID" | |||||
/> | |||||
<!-- 多选 --> | |||||
<!-- <l-checkbox | |||||
v-if="item.QTypeString == 1" | |||||
v-model="aa" | |||||
@change="searchChange" | |||||
:range="item.Eval_QuestionItems" | |||||
title="" | |||||
placeholder="请选择" | |||||
:disabled="false" | |||||
textField="ITitle" | |||||
valueField="IID" | |||||
/> --> | |||||
<checkbox-group v-if="item.QType == 1"> | |||||
<l-checkbox v-for="item1 in item.Eval_QuestionItems" :key="item1.IID" v-model="bbb" :title="item1.ITitle" :checkboxValue="item1.IID.toString()" /> | |||||
</checkbox-group> | |||||
<!-- 填空 --> | |||||
<l-textarea v-if="item.QType == 1" v-model="aa" placeholder="请输入" /> | |||||
</view> | |||||
<!-- <l-input v-model="text" disabled title="你说呢你说呢?"></l-input> | |||||
<radio-group> | |||||
<l-radio v-model="radioValue" title="单选框1" radioValue="1" /> | |||||
<l-radio v-model="radioValue" title="单选框2" radioValue="2" /> | |||||
</radio-group> --> | |||||
</view> | |||||
<view v-if="ready" class="bg-white margin-tb padding" style="padding-top: 0; overflow: hidden;"> | <view v-if="ready" class="bg-white margin-tb padding" style="padding-top: 0; overflow: hidden;"> | ||||
<l-button v-if="edit" @click="action('save')" size="lg" color="green" class="block margin-top" block> | |||||
<l-button v-if="edit" @click="action('save')" size="lg" style="background-color: #0C86D8;color: #fff;" class="block margin-top" block> | |||||
提交保存 | 提交保存 | ||||
</l-button> | </l-button> | ||||
<l-button v-if="!edit && mode !== 'create'" @click="action('edit')" size="lg" line="orange" class="block margin-top" block> | |||||
编辑本页 | |||||
</l-button> | |||||
<l-button v-if="edit && mode !== 'create'" @click="action('reset')" size="lg" line="red" class="block margin-top" block> | |||||
取消编辑 | |||||
</l-button> | |||||
<l-button v-if="!edit && mode !== 'create'" @click="action('delete')" size="lg" line="red" class="block margin-top" block> | |||||
删除 | |||||
</l-button> | |||||
</view> | </view> | ||||
</view> | </view> | ||||
</template> | </template> | ||||
<script> | <script> | ||||
/* | |||||
* 版 本 Learun-ADMS V7.0.3 力软敏捷开发框架(http://www.learun.cn) | |||||
* Copyright (c) 2013-2020 上海力软信息技术有限公司 | |||||
* 创建人:超级管理员 | |||||
* 日 期:2020-10-16 15:39 | |||||
* 描 述:工作日志 | |||||
*/ | |||||
/** | |||||
* 本段代码由移动端代码生成器输出,移动端须 2.2.0 版本及以上可以使用 | |||||
* 请在移动端 /pages.json 中的 pages 字段中添加一条记录: | |||||
* { "path": "pages/EducationalAdministration/JournalSend/single", "style": { "navigationBarTitleText": "表单详情页" } } | |||||
* | |||||
* (navigationBarTitleText 字段为本页面的标题文本,可以修改) | |||||
* (必须自行操作该步骤,力软代码生成器不会自动帮您修改 /pages.json 文件) | |||||
*/ | |||||
import get from 'lodash/get' | import get from 'lodash/get' | ||||
import set from 'lodash/set' | import set from 'lodash/set' | ||||
@@ -74,73 +68,50 @@ export default { | |||||
mixins: [customPageMixins], | mixins: [customPageMixins], | ||||
data() { | data() { | ||||
return { | |||||
return { | |||||
aa:"", | |||||
bbb:[], | |||||
// 页面相关参数 | // 页面相关参数 | ||||
id: null, | id: null, | ||||
mode: null, | |||||
edit: null, | edit: null, | ||||
ready: false, | |||||
// 表单数据 | |||||
current: {}, | |||||
origin: {}, | |||||
// 表单项数据结构 | |||||
scheme: { | |||||
JournalSend: { | |||||
JTitle: { type: 'text', title: '日志主题' }, | |||||
JTypeId: { type: 'select', title: '日志类型', dataSource: '0' }, | |||||
JReceiveId: { type: 'organize', title: '接收人', dataType: 'user' }, | |||||
JContent: { type: 'textarea', title: '日志内容' }, | |||||
}, | |||||
}, | |||||
// 数据源 | |||||
dataSource: { | |||||
JournalSend: { | |||||
JTypeId: [], | |||||
}, | |||||
} | |||||
} | |||||
}, | |||||
async onLoad({ type, id }) { | |||||
await this.init(type, id) | |||||
ready: false, | |||||
formData:{}, | |||||
submitParams:null | |||||
} | |||||
}, | |||||
async onLoad({ id,EmpNo,LessonNo }) { | |||||
this.submitParams = {EmpNo,LessonNo} | |||||
await this.init(id) | |||||
}, | }, | ||||
methods: { | methods: { | ||||
aaa(){ | |||||
console.log(this.bbb,this) | |||||
}, | |||||
// 页面初始化 | // 页面初始化 | ||||
async init(type, id) { | |||||
this.LOADING('加载数据中...') | |||||
this.id = id | |||||
this.mode = type | |||||
this.edit = ['create', 'edit'].includes(this.mode) | |||||
// 拉取表单数据,同时拉取所有来自数据源的选单数据 | |||||
await Promise.all([ | |||||
() => {} | |||||
]) | |||||
async init( id ) { | |||||
this.LOADING('加载数据中...') | |||||
this.id = id | |||||
await this.fetchForm() | await this.fetchForm() | ||||
this.ready = true | this.ready = true | ||||
this.HIDE_LOADING() | this.HIDE_LOADING() | ||||
}, | }, | ||||
// 加载表单数据 | // 加载表单数据 | ||||
async fetchForm() { | |||||
if (this.mode === 'create') { | |||||
this.origin = await this.getDefaultForm() | |||||
} else { | |||||
const result = await this.HTTP_GET('learun/adms/eval/paper', {VID:this.id}) | |||||
console.log(result); | |||||
this.origin = await this.formatFormData(result) | |||||
} | |||||
this.current = this.COPY(this.origin) | |||||
async fetchForm() { | |||||
return this.HTTP_GET('learun/adms/eval/paper', {VID:this.id}, '加载数据时出错').then(success => { | |||||
this.HIDE_LOADING() | |||||
if (!success) { | |||||
return | |||||
} | |||||
if(success){ | |||||
this.edit = true | |||||
} | |||||
console.log(success) | |||||
this.formData = success | |||||
}) | |||||
}, | }, | ||||
// 点击 「编辑」、「重置」、「保存」、「删除」 按钮 | // 点击 「编辑」、「重置」、「保存」、「删除」 按钮 | ||||
@@ -156,29 +127,37 @@ console.log(result); | |||||
break | break | ||||
case 'save': | case 'save': | ||||
const verifyResult = this.verifyForm() | |||||
if (verifyResult.length > 0) { | |||||
this.CONFIRM('表单验证失败', verifyResult.join('\n')) | |||||
return | |||||
} | |||||
// const verifyResult = this.verifyForm() | |||||
// if (verifyResult.length > 0) { | |||||
// this.CONFIRM('表单验证失败', verifyResult.join('\n')) | |||||
// return | |||||
// } | |||||
if (!(await this.CONFIRM('提交确认', '确定要提交本页表单内容吗?', true))) { | if (!(await this.CONFIRM('提交确认', '确定要提交本页表单内容吗?', true))) { | ||||
return | return | ||||
} | } | ||||
this.LOADING('正在提交...') | |||||
const postData = await this.getPostData(this.id) | |||||
this.LOADING('正在提交...') | |||||
let postarray = this.formData.Eval_Questions.map(item=>{ | |||||
return { | |||||
QID:item.QID, | |||||
IID:item.IID.toString(), | |||||
UText:item.UText, | |||||
} | |||||
}) | |||||
const postData = { | |||||
VID:this.formData.VID, | |||||
...this.submitParams, | |||||
postarray | |||||
} | |||||
this.HTTP_POST('learun/adms/EducationalAdministration/Journal/save', postData, '表单提交保存失败').then(success => { | this.HTTP_POST('learun/adms/EducationalAdministration/Journal/save', postData, '表单提交保存失败').then(success => { | ||||
this.HIDE_LOADING() | this.HIDE_LOADING() | ||||
if (!success) { | if (!success) { | ||||
return | return | ||||
} | } | ||||
this.EMIT('EducationalAdministrationJournalSend-list-change') | |||||
this.NAV_BACK() | |||||
this.TOAST('提交保存成功') | |||||
}) | |||||
this.NAV_BACK() | |||||
this.TOAST('提交保存成功') | |||||
}) | |||||
break | break | ||||
case 'delete': | case 'delete': | ||||
@@ -214,4 +193,17 @@ console.log(result); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
</script> | |||||
</script> | |||||
<style scoped lang="scss"> | |||||
.questionTitle{ | |||||
line-height: 18px; | |||||
background-color: #fff; | |||||
color: #000; | |||||
margin-top: 8px; | |||||
margin-bottom: 1px; | |||||
padding: 16px 12px; | |||||
} | |||||
:deep(.cu-form-group){ | |||||
display: none; | |||||
} | |||||
</style> |
@@ -508,6 +508,7 @@ export default{ | |||||
text-align: center; | text-align: center; | ||||
font-size: 14px; | font-size: 14px; | ||||
color: #1a1a1a; | color: #1a1a1a; | ||||
background-color: #ffffff; | |||||
} | } | ||||
.timeTableAlertLi.active { | .timeTableAlertLi.active { | ||||
@@ -518,10 +519,6 @@ export default{ | |||||
background-color: #fbfdff; | background-color: #fbfdff; | ||||
} | } | ||||
.timeTableAlertLi:nth-child(2n - 1) { | |||||
background-color: #ffffff; | |||||
} | |||||
#MeasureTime { | #MeasureTime { | ||||
text-align: center; | text-align: center; | ||||
} | } | ||||
@@ -273,7 +273,7 @@ page { | |||||
.otherLogin{ | .otherLogin{ | ||||
display: flex; | display: flex; | ||||
justify-content: right; | |||||
justify-content: flex-end; | |||||
.textBtn{ | .textBtn{ | ||||
width: 100px; | width: 100px; | ||||
color: #606266; | color: #606266; | ||||
@@ -132,7 +132,7 @@ export default { | |||||
return null | return null | ||||
} | } | ||||
return this.API + `/user/img?data=${item.F_OtherUserId}` | |||||
return this.API + `/learun/adms/user/img?data=${item.F_OtherUserId}` | |||||
} | } | ||||
}, | }, | ||||
@@ -186,7 +186,7 @@ export default { | |||||
// 获取用户头像图片 url | // 获取用户头像图片 url | ||||
avatar(id) { | avatar(id) { | ||||
return id === this.chatUserId && this.isSystem ? null : this.API + `/user/img?data=${id}` | |||||
return id === this.chatUserId && this.isSystem ? null : this.API + `/learun/adms/user/img?data=${id}` | |||||
} | } | ||||
}, | }, | ||||
@@ -156,7 +156,7 @@ export default { | |||||
return '' | return '' | ||||
} | } | ||||
return this.API + `/user/img?data=${this.currentUser.userId}` | |||||
return this.API + `/learun/adms/user/img?data=${this.currentUser.userId}` | |||||
} | } | ||||
}, | }, | ||||
@@ -34,7 +34,7 @@ export default { | |||||
// 头像图片 url | // 头像图片 url | ||||
avatarSrc() { | avatarSrc() { | ||||
return this.API + `/user/img?data=${this.currentUser.userId}` | |||||
return this.API + `/learun/adms/user/img?data=${this.currentUser.userId}` | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -30,7 +30,7 @@ export default { | |||||
// 头像图片 url | // 头像图片 url | ||||
avatar() { | avatar() { | ||||
return this.API + `/user/img?data=${this.currentUser.userId}` | |||||
return this.API + `/learun/adms/user/img?data=${this.currentUser.userId}` | |||||
}, | }, | ||||
// 用户公司部门 tag | // 用户公司部门 tag | ||||
@@ -38,7 +38,7 @@ | |||||
<view class="tSec2Con2"> | <view class="tSec2Con2"> | ||||
<view class="studCheckList"> | <view class="studCheckList"> | ||||
<view class="studCheckLi" v-for="(k, i) in data.result" :key="k.StuName"> | <view class="studCheckLi" v-for="(k, i) in data.result" :key="k.StuName"> | ||||
<view style="float:right; margin-top: 7px;" class="studCheckStatue" :class="type(k.Sort)"> | |||||
<view style="float:right; margin-top: 7px;" class="studCheckStatue" :class="[type(k.Sort)]"> | |||||
<text></text> | <text></text> | ||||
{{ k.Sort }} | {{ k.Sort }} | ||||
</view> | </view> | ||||
@@ -95,14 +95,15 @@ export default { | |||||
// t.formId 使用表单,根据这个 formId 来获取 scheme 等信息 | // t.formId 使用表单,根据这个 formId 来获取 scheme 等信息 | ||||
// t.appurl 使用移动页面,直接跳转到本地的页面;表单结构等均写死在页面里 | // t.appurl 使用移动页面,直接跳转到本地的页面;表单结构等均写死在页面里 | ||||
const { wfForms } = this.currentNode | const { wfForms } = this.currentNode | ||||
console.log(wfForms); | |||||
// 处理没有有效表单的情况,停止加载 | // 处理没有有效表单的情况,停止加载 | ||||
if (!wfForms || wfForms.every(t => !t.formId && !t.appurl)) { | if (!wfForms || wfForms.every(t => !t.formId && !t.appurl)) { | ||||
this.HIDE_LOADING() | this.HIDE_LOADING() | ||||
this.TOAST('移动表单数据(wfForms)中无有效表单') | this.TOAST('移动表单数据(wfForms)中无有效表单') | ||||
return | return | ||||
} | } | ||||
const fetchFolderkeyData=await this.fetchFolderkeyData(this.currentNode , this.processId); | |||||
uni.setStorageSync('guids',JSON.stringify(fetchFolderkeyData)); | |||||
// 处理移动端本地表单(也就是系统表单)的情况,直接跳转过去 | // 处理移动端本地表单(也就是系统表单)的情况,直接跳转过去 | ||||
const appSysPage = wfForms.find(t => t.appurl) | const appSysPage = wfForms.find(t => t.appurl) | ||||
@@ -151,8 +152,6 @@ export default { | |||||
// 不是子流程,可以直接渲染 | // 不是子流程,可以直接渲染 | ||||
const schemeData = await this.fetchSchemeData(this.currentNode) | const schemeData = await this.fetchSchemeData(this.currentNode) | ||||
const formData = await this.fetchFormData(this.currentNode, this.processId) | const formData = await this.fetchFormData(this.currentNode, this.processId) | ||||
console.log(schemeData) | |||||
console.log(formData) | |||||
const { formValue, scheme, rel } = await this.getCustomForm({ | const { formValue, scheme, rel } = await this.getCustomForm({ | ||||
formData, | formData, | ||||
schemeData, | schemeData, | ||||
@@ -161,7 +160,6 @@ export default { | |||||
code: null | code: null | ||||
}) | }) | ||||
this.scheme = scheme | this.scheme = scheme | ||||
console.log(scheme) | |||||
this.formValue = formValue | this.formValue = formValue | ||||
this.rel = rel | this.rel = rel | ||||
} | } | ||||
@@ -201,7 +199,7 @@ export default { | |||||
return | return | ||||
} | } | ||||
this.LOADING(`提交${actionText}中…`) | this.LOADING(`提交${actionText}中…`) | ||||
this.HTTP_POST(`/newwf${actionUrl}`, actionData, `提交${actionText}失败`).then(success => { | |||||
this.HTTP_POST(`/learun/adms/newwf${actionUrl}`, actionData, `提交${actionText}失败`).then(success => { | |||||
this.HIDE_LOADING() | this.HIDE_LOADING() | ||||
if (success) { | if (success) { | ||||
this.EMIT('task-list-change') | this.EMIT('task-list-change') | ||||
@@ -220,7 +218,7 @@ export default { | |||||
this.LOADING('正在提交…') | this.LOADING('正在提交…') | ||||
const draftFormValue = this.$refs.form.getFormValue() | const draftFormValue = this.$refs.form.getFormValue() | ||||
const draftPostData = await this.getPostData(draftFormValue, this.scheme) | const draftPostData = await this.getPostData(draftFormValue, this.scheme) | ||||
this.HTTP_POST('/newwf/draft', draftPostData, '提交草稿失败').then(success => { | |||||
this.HTTP_POST('/learun/adms/newwf/draft', draftPostData, '提交草稿失败').then(success => { | |||||
this.HIDE_LOADING() | this.HIDE_LOADING() | ||||
if (success) { | if (success) { | ||||
this.EMIT('task-list-change') | this.EMIT('task-list-change') | ||||
@@ -249,7 +247,7 @@ export default { | |||||
postData.parentTaskId = this.taskId | postData.parentTaskId = this.taskId | ||||
} | } | ||||
const errorTips = '流程发起失败' | const errorTips = '流程发起失败' | ||||
this.HTTP_POST('/newwf/createchildflow', postData, errorTips).then(success => { | |||||
this.HTTP_POST('/learun/adms/newwf/createchildflow', postData, errorTips).then(success => { | |||||
this.HIDE_LOADING() | this.HIDE_LOADING() | ||||
if (success) { | if (success) { | ||||
this.EMIT('task-list-change') | this.EMIT('task-list-change') | ||||
@@ -110,7 +110,10 @@ export default { | |||||
this.needTitle = this.type !== 'again' && Number(currentNode.isTitle) === 1 | this.needTitle = this.type !== 'again' && Number(currentNode.isTitle) === 1 | ||||
const formData = await this.fetchFormData(currentNode, processId) | const formData = await this.fetchFormData(currentNode, processId) | ||||
const schemeData = await this.fetchSchemeData(currentNode) | |||||
const schemeData = await this.fetchSchemeData(currentNode); | |||||
const fetchFolderkeyData=await this.fetchFolderkeyData(currentNode, processId); | |||||
uni.setStorageSync('guids',JSON.stringify(fetchFolderkeyData)); | |||||
const { formValue, scheme, rel } = await this.getCustomForm({ | const { formValue, scheme, rel } = await this.getCustomForm({ | ||||
schemeData, | schemeData, | ||||
processId, | processId, | ||||
@@ -119,14 +122,15 @@ export default { | |||||
code: this.type === 'again' ? null : code, | code: this.type === 'again' ? null : code, | ||||
useDefault: true | useDefault: true | ||||
}) | }) | ||||
this.rel = rel | this.rel = rel | ||||
this.scheme = scheme | this.scheme = scheme | ||||
this.formValue = formValue | this.formValue = formValue | ||||
this.code = code | this.code = code | ||||
this.processId = processId | this.processId = processId | ||||
this.ready = true | this.ready = true | ||||
this.HIDE_LOADING() | this.HIDE_LOADING() | ||||
}, | }, | ||||
// 提交草稿按钮 | // 提交草稿按钮 | ||||
@@ -153,9 +157,10 @@ export default { | |||||
// 发起流程按钮 | // 发起流程按钮 | ||||
async submit() { | async submit() { | ||||
const isAgain = this.type === 'again' | const isAgain = this.type === 'again' | ||||
// 先验证表单,验证不通过则提示 | // 先验证表单,验证不通过则提示 | ||||
const verifyResult = this.verifyValue() | const verifyResult = this.verifyValue() | ||||
if (verifyResult.length > 0) { | if (verifyResult.length > 0) { | ||||
this.CONFIRM('表单验证失败', verifyResult.join('\n')) | this.CONFIRM('表单验证失败', verifyResult.join('\n')) | ||||
return | return | ||||
@@ -191,6 +196,7 @@ export default { | |||||
// 获取表单验证结果,是一个包含错误信息的数组,长度为 0 则没有错误 | // 获取表单验证结果,是一个包含错误信息的数组,长度为 0 则没有错误 | ||||
verifyValue() { | verifyValue() { | ||||
const errList = this.$refs.form.verifyValue() | const errList = this.$refs.form.verifyValue() | ||||
if (this.needTitle && !this.title) { | if (this.needTitle && !this.title) { | ||||
errList.push(`流程的标题不能为空`) | errList.push(`流程的标题不能为空`) | ||||
@@ -32,298 +32,383 @@ import customForm from '@/common/customform.js' | |||||
* (以上只是简单介绍;实际使用中,如果打开子流程,需要拉取父/子两个流程信息) | * (以上只是简单介绍;实际使用中,如果打开子流程,需要拉取父/子两个流程信息) | ||||
*/ | */ | ||||
export default { | export default { | ||||
mixins: [customForm], | |||||
methods: { | |||||
/** | |||||
* 从流程信息中生成 scheme、formValue | |||||
* 参数: { schemeData (必填), processId, currentNode, formData (新建时为 null), code, useDefault } | |||||
* 返回: { scheme, formValue, rel } | |||||
* | |||||
* 参数: | |||||
* schemeData: 使用 fetchSchemeData 方法拉取到的原始 scheme 数据,未经过格式化处理 | |||||
* processId: 表单 GUID;如果是新建表单,可以用 this.GUID('-') 生成一个 | |||||
* currentNode: 使用 getCurrentNode 方法拉取到的当前节点信息,用于权限控制 | |||||
* formData: 填入表单的表单值,新建表单时此项为 null 即可 | |||||
* code: 表单编号 code,会被赋值到返回的 formValue.code;重新发起流程的场合赋 null | |||||
* useDefault: 如果 formData 中某一项为空,是否对这一项填入默认值;通常在编辑草稿时启用 | |||||
* | |||||
* 该方法返回的 scheme 项可能带有以下属性: | |||||
* __valuePath__: 表单值在 formValue 中的路径,使用 lodash 的 get、set 方法即可读写 | |||||
* __sourceData__: 表单值的选单数据 | |||||
* __defaultItem__: 类型为 girdtable 的表单项带有此属性,表示添加一行表格时候表格项的默认值 | |||||
* __schemeIndex__: (暂时用不到)表单项位于 schemeData 根级内的第几个子项中 | |||||
* __dataIndex__: (暂时用不到)表单项位于 F_Scheme.data 中的第几个子项中 | |||||
*/ | |||||
async getCustomForm(prop) { | |||||
const { schemeData, formData, currentNode, code, processId, useDefault } = prop | |||||
// 处理字段之间的级联、绑定关系 | |||||
// 需要绑定 change 事件的: | |||||
// datetime: 修改后重新计算 datetimerange | |||||
// organize: 修改后重设级联到该组件的其他组件的值,user 一级无需处理 | |||||
// 需要绑定某值的: | |||||
// organize: 级联到某个组件,company 一级无需处理 | |||||
const schemeRef = {} | |||||
const refList = [] | |||||
// 最终返回值:scheme、rel、formValue | |||||
const scheme = [] | |||||
const rel = {} | |||||
const formValue = { processId, formreq: [] } | |||||
if (code) { | |||||
formValue.code = code | |||||
} | |||||
// 遍历 schemeData 中所有的 scheme | |||||
const schemeList = Array.isArray(schemeData) ? schemeData : Object.values(schemeData) | |||||
for (let schemeIndex = 0; schemeIndex < schemeList.length; ++schemeIndex) { | |||||
const schemeItem = schemeList[schemeIndex] | |||||
schemeItem.F_Scheme = JSON.parse(schemeItem.F_Scheme) | |||||
// 已有表单值的时候,舍弃掉不存在表单值中的 scheme | |||||
if (formData && !formData[schemeItem.F_SchemeInfoId]) { | |||||
continue | |||||
} | |||||
// 设置 formreq 的内容,非新建模式下需要设置 keyValue | |||||
const { formId, field } = get(currentNode, `wfForms.${schemeIndex}`, {}) | |||||
const formreqObj = { schemeInfoId: formId, processIdName: field, formData: {} } | |||||
if (formData) { | |||||
if (Object.values(get(formData, `${schemeItem.F_SchemeInfoId}`, {})).some(t => t && t.length > 0)) { | |||||
formreqObj.keyValue = processId | |||||
} | |||||
} | |||||
formValue.formreq[schemeIndex] = formreqObj | |||||
for (let dataIndex = 0; dataIndex < schemeItem.F_Scheme.data.length; ++dataIndex) { | |||||
const { componts } = schemeItem.F_Scheme.data[dataIndex] | |||||
for (const t of componts) { | |||||
// 之后的 t 即表示每个 scheme 项 | |||||
t.__valuePath__ = `formreq.${schemeIndex}.formData.${t.id}` | |||||
// 以下两个属性暂时用不到 | |||||
t.__schemeIndex__ = schemeIndex | |||||
t.__dataIndex__ = dataIndex | |||||
if (t.type === 'girdtable' && t.table) { | |||||
// 数据项是表格的情况 | |||||
// 先设置源数据,不然无法获取默认值 | |||||
for (const fieldItem of t.fieldsData) { | |||||
fieldItem.__sourceData__ = await this.getSourceData(fieldItem) | |||||
} | |||||
t.__defaultItem__ = await this.getDefaultData(t, prop) | |||||
if (formData) { | |||||
// 有表单值的情况,从表单值中获取数据 | |||||
const val = [] | |||||
for (const valueItem of get(formData, `${schemeItem.F_SchemeInfoId}.${t.table}`, [])) { | |||||
const tableItemValue = {} | |||||
for (const fieldItem of t.fieldsData.filter(t => t.field)) { | |||||
const formDataValue = get(valueItem, fieldItem.field.toLowerCase()) | |||||
tableItemValue[fieldItem.field] = await this.convertToFormValue(fieldItem, formDataValue) | |||||
} | |||||
val.push(tableItemValue) | |||||
} | |||||
// useDefault 表示在从 formData 取不到值的时候使用默认值 | |||||
if ((!val || val.length <= 0) && useDefault) { | |||||
set(formValue, t.__valuePath__, [this.COPY(t.__defaultItem__)]) | |||||
} else { | |||||
set(formValue, t.__valuePath__, val) | |||||
} | |||||
} else { | |||||
// 无表单值的情况,默认值 | |||||
set(formValue, t.__valuePath__, [this.COPY(t.__defaultItem__)]) | |||||
} | |||||
} else if (t.field) { | |||||
// 数据项不是表格的情况 | |||||
// 先设置源数据,不然无法获取默认值 | |||||
t.__sourceData__ = await this.getSourceData(t) | |||||
if (formData) { | |||||
// 有表单值的情况,从表单值中获取数据 | |||||
const path = `${schemeItem.F_SchemeInfoId}.${t.table}.${dataIndex}.${t.field.toLowerCase()}` | |||||
const formDataValue = get(formData, path) | |||||
// useDefault 表示在从 formData 取不到值的时候使用默认值 | |||||
if (!formDataValue && useDefault) { | |||||
set(formValue, t.__valuePath__, await this.getDefaultData(t, prop)) | |||||
} else { | |||||
set(formValue, t.__valuePath__, await this.convertToFormValue(t, formDataValue)) | |||||
} | |||||
} else { | |||||
// 无表单值的情况,默认值 | |||||
set(formValue, t.__valuePath__, await this.getDefaultData(t, prop)) | |||||
} | |||||
} | |||||
// 权限控制 | |||||
const authObj = get(currentNode, `wfForms.${schemeIndex}.authorize.${t.id}`, {}) | |||||
t.edit = authObj.isEdit | |||||
if (Number(t.isHide) !== 1 && authObj.isLook !== 0) { | |||||
// 加入 scheme | |||||
scheme.push(t) | |||||
// organize、datetime 可能作为其他 organize 或 datetimerange 的依赖项,引用它们 | |||||
if (['organize', 'datetime'].includes(t.type)) { | |||||
schemeRef[t.id] = t | |||||
} | |||||
// datetimerange、带有 relation 级联字段的 organize,依赖其他项 | |||||
if ((t.type === 'datetimerange' && t.startTime && t.endTime) || (t.type === 'organize' && t.relation)) { | |||||
refList.push(t) | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
// 依次处理表单关联 | |||||
refList.forEach(t => { | |||||
if (t.type === 'organize') { | |||||
// 处理组件结构级联 | |||||
// 给当前组件赋上级级联的值路径 __relationPath__ | |||||
const parent = schemeRef[t.relation] | |||||
t.__relationPath__ = parent.__valuePath__ | |||||
// 给上级级联的组件注册自动重置当前组件的 change 事件 | |||||
const relItem = { type: 'organize', id: t.id, path: t.__valuePath__ } | |||||
rel[parent.id] = rel[parent.id] ? rel[parent.id].concat(relItem) : [relItem] | |||||
} else if (t.type === 'datetimerange') { | |||||
// 处理日期区间 | |||||
const start = schemeRef[t.startTime] | |||||
const end = schemeRef[t.endTime] | |||||
const relItem = { | |||||
type: 'datetimerange', | |||||
path: t.__valuePath__, | |||||
id: t.id, | |||||
startPath: start.__valuePath__, | |||||
endPath: end.__valuePath__, | |||||
} | |||||
rel[start.id] = rel[start.id] ? rel[start.id].concat(relItem) : [relItem] | |||||
rel[end.id] = rel[end.id] ? rel[end.id].concat(relItem) : [relItem] | |||||
} | |||||
}) | |||||
return { scheme, formValue, rel } | |||||
}, | |||||
/** | |||||
* 获取最终需要 POST 的数据 | |||||
* 参数:formValue, scheme | |||||
* 返回:用于提交的数据 | |||||
* | |||||
* 遍历 formValue,将其中的表单值依次使用 convertToPostData 这个方法转化为提交值 | |||||
*/ | |||||
async getPostData(originFormValue, scheme) { | |||||
const formValue = this.COPY(originFormValue) | |||||
// 依次按照 scheme 项目遍历 | |||||
for (const item of scheme) { | |||||
if (item.field) { | |||||
// 不是表格的情况 | |||||
const path = item.__valuePath__ | |||||
const val = get(formValue, path) | |||||
const result = await this.convertToPostData(item, val, originFormValue, scheme) | |||||
set(formValue, path, result) | |||||
} else if (item.table && item.fieldsData) { | |||||
// 是表格的情况 | |||||
const tableValue = get(formValue, item.__valuePath__, []) | |||||
for (let valueIndex = 0; valueIndex < tableValue.length; ++valueIndex) { | |||||
for (const schemeItem of item.fieldsData) { | |||||
const path = `${item.__valuePath__}.${valueIndex}.${schemeItem.field}` | |||||
const val = get(formValue, path) | |||||
const result = await this.convertToPostData(schemeItem, val, originFormValue, scheme) | |||||
set(formValue, path, result) | |||||
} | |||||
} | |||||
} | |||||
} | |||||
formValue.formreq.forEach(t => { t.formData = JSON.stringify(t.formData) }) | |||||
formValue.formreq = JSON.stringify(formValue.formreq) | |||||
return formValue | |||||
}, | |||||
/** | |||||
* 获取流程信息 | |||||
* 参数: { code, processId, taskId } | |||||
* | |||||
*/ | |||||
async fetchProcessInfo({ code, processId, taskId }) { | |||||
const url = processId ? 'learun/adms/newwf/processinfo' : 'learun/adms/newwf/scheme' | |||||
const reqObj = { processId } | |||||
if (taskId) { | |||||
reqObj.taskId = taskId | |||||
} | |||||
const data = processId ? reqObj : code | |||||
const result = await this.HTTP_GET(url, data) | |||||
if (!result) { return {} } | |||||
if (result.info) { | |||||
result.info.Scheme = JSON.parse(result.info.Scheme) | |||||
} else if (result.F_Content) { | |||||
result.F_Content = JSON.parse(result.F_Content) | |||||
} | |||||
return result | |||||
}, | |||||
/** | |||||
* 从 processInfo 流程信息中,提取出 currentNode | |||||
* 参数: processInfo | |||||
* | |||||
*/ | |||||
getCurrentNode(processInfo) { | |||||
if (processInfo.info) { | |||||
return processInfo.info.Scheme.nodes.find(t => t.id === processInfo.info.CurrentNodeId) | |||||
} else if (processInfo.F_Content) { | |||||
return processInfo.F_Content.nodes.find(t => t.type === 'startround') | |||||
} | |||||
return {} | |||||
}, | |||||
/** | |||||
* 拉取表单的 schemeData | |||||
* 参数: currentNode | |||||
* | |||||
* 从当前节点 currentNode 中提取出表单 id,然后自 API 地址 /form/scheme 中拉取表单数据并返回 | |||||
*/ | |||||
async fetchSchemeData(currentNode, currentTask, type) { | |||||
const { wfForms } = currentNode | |||||
const data = wfForms.filter(t => t.formId).map(t => ({ id: t.formId, ver: '' })) | |||||
const schemeData = await this.HTTP_GET('learun/adms/form/scheme', data) | |||||
return schemeData || {} | |||||
}, | |||||
/** | |||||
* 拉取表单的 formData | |||||
* 参数: currentNode, keyValue | |||||
* | |||||
* 提取当前节点信息、表单主键信息,从 API 地址 /form/data 中拉取表单数据 | |||||
*/ | |||||
async fetchFormData({ wfForms }, keyValue) { | |||||
const reqData = wfForms | |||||
.filter(t => t.formId) | |||||
.map(t => ({ | |||||
schemeInfoId: t.formId, | |||||
processIdName: t.field, | |||||
keyValue | |||||
})) | |||||
const formData = await this.HTTP_GET('learun/adms/form/data', reqData) | |||||
return formData || {} | |||||
} | |||||
} | |||||
mixins: [customForm], | |||||
methods: { | |||||
/** | |||||
* 从流程信息中生成 scheme、formValue | |||||
* 参数: { schemeData (必填), processId, currentNode, formData (新建时为 null), code, useDefault } | |||||
* 返回: { scheme, formValue, rel } | |||||
* | |||||
* 参数: | |||||
* schemeData: 使用 fetchSchemeData 方法拉取到的原始 scheme 数据,未经过格式化处理 | |||||
* processId: 表单 GUID;如果是新建表单,可以用 this.GUID('-') 生成一个 | |||||
* currentNode: 使用 getCurrentNode 方法拉取到的当前节点信息,用于权限控制 | |||||
* formData: 填入表单的表单值,新建表单时此项为 null 即可 | |||||
* code: 表单编号 code,会被赋值到返回的 formValue.code;重新发起流程的场合赋 null | |||||
* useDefault: 如果 formData 中某一项为空,是否对这一项填入默认值;通常在编辑草稿时启用 | |||||
* | |||||
* 该方法返回的 scheme 项可能带有以下属性: | |||||
* __valuePath__: 表单值在 formValue 中的路径,使用 lodash 的 get、set 方法即可读写 | |||||
* __sourceData__: 表单值的选单数据 | |||||
* __defaultItem__: 类型为 girdtable 的表单项带有此属性,表示添加一行表格时候表格项的默认值 | |||||
* __schemeIndex__: (暂时用不到)表单项位于 schemeData 根级内的第几个子项中 | |||||
* __dataIndex__: (暂时用不到)表单项位于 F_Scheme.data 中的第几个子项中 | |||||
*/ | |||||
async getCustomForm(prop) { | |||||
const { | |||||
schemeData, | |||||
formData, | |||||
currentNode, | |||||
code, | |||||
processId, | |||||
useDefault | |||||
} = prop | |||||
// 处理字段之间的级联、绑定关系 | |||||
// 需要绑定 change 事件的: | |||||
// datetime: 修改后重新计算 datetimerange | |||||
// organize: 修改后重设级联到该组件的其他组件的值,user 一级无需处理 | |||||
// 需要绑定某值的: | |||||
// organize: 级联到某个组件,company 一级无需处理 | |||||
const schemeRef = {} | |||||
const refList = [] | |||||
// 最终返回值:scheme、rel、formValue | |||||
const scheme = [] | |||||
const rel = {} | |||||
const formValue = { | |||||
processId, | |||||
formreq: [] | |||||
} | |||||
if (code) { | |||||
formValue.code = code | |||||
} | |||||
// 遍历 schemeData 中所有的 scheme | |||||
const schemeList = Array.isArray(schemeData) ? schemeData : Object.values(schemeData) | |||||
for (let schemeIndex = 0; schemeIndex < schemeList.length; ++schemeIndex) { | |||||
const schemeItem = schemeList[schemeIndex] | |||||
schemeItem.F_Scheme = JSON.parse(schemeItem.F_Scheme) | |||||
// 已有表单值的时候,舍弃掉不存在表单值中的 scheme | |||||
if (formData && !formData[schemeItem.F_SchemeInfoId]) { | |||||
continue | |||||
} | |||||
// 设置 formreq 的内容,非新建模式下需要设置 keyValue | |||||
const { | |||||
formId, | |||||
field | |||||
} = get(currentNode, `wfForms.${schemeIndex}`, {}) | |||||
const formreqObj = { | |||||
schemeInfoId: formId, | |||||
processIdName: field, | |||||
formData: {} | |||||
} | |||||
if (formData) { | |||||
if (Object.values(get(formData, `${schemeItem.F_SchemeInfoId}`, {})).some(t => t && t.length > | |||||
0)) { | |||||
formreqObj.keyValue = processId | |||||
} | |||||
} | |||||
formValue.formreq[schemeIndex] = formreqObj | |||||
for (let dataIndex = 0; dataIndex < schemeItem.F_Scheme.data.length; ++dataIndex) { | |||||
const { | |||||
componts | |||||
} = schemeItem.F_Scheme.data[dataIndex] | |||||
for (const t of componts) { | |||||
// 之后的 t 即表示每个 scheme 项 | |||||
t.__valuePath__ = `formreq.${schemeIndex}.formData.${t.id}` | |||||
// 以下两个属性暂时用不到 | |||||
t.__schemeIndex__ = schemeIndex | |||||
t.__dataIndex__ = dataIndex | |||||
if (t.type === 'girdtable' && t.table) { | |||||
// 数据项是表格的情况 | |||||
// 先设置源数据,不然无法获取默认值 | |||||
for (const fieldItem of t.fieldsData) { | |||||
fieldItem.__sourceData__ = await this.getSourceData(fieldItem) | |||||
} | |||||
t.__defaultItem__ = await this.getDefaultData(t, prop) | |||||
if (formData) { | |||||
// 有表单值的情况,从表单值中获取数据 | |||||
const val = [] | |||||
for (const valueItem of get(formData, `${schemeItem.F_SchemeInfoId}.${t.table}`, | |||||
[])) { | |||||
const tableItemValue = {} | |||||
for (const fieldItem of t.fieldsData.filter(t => t.field)) { | |||||
const formDataValue = get(valueItem, fieldItem.field.toLowerCase()) | |||||
tableItemValue[fieldItem.field] = await this.convertToFormValue(fieldItem, | |||||
formDataValue) | |||||
} | |||||
val.push(tableItemValue) | |||||
} | |||||
// useDefault 表示在从 formData 取不到值的时候使用默认值 | |||||
if ((!val || val.length <= 0) && useDefault) { | |||||
set(formValue, t.__valuePath__, [this.COPY(t.__defaultItem__)]) | |||||
} else { | |||||
set(formValue, t.__valuePath__, val) | |||||
} | |||||
} else { | |||||
// 无表单值的情况,默认值 | |||||
set(formValue, t.__valuePath__, [this.COPY(t.__defaultItem__)]) | |||||
} | |||||
} else if (t.field) { | |||||
// 数据项不是表格的情况 | |||||
// 先设置源数据,不然无法获取默认值 | |||||
t.__sourceData__ = await this.getSourceData(t) | |||||
if (formData) { | |||||
// 有表单值的情况,从表单值中获取数据 | |||||
const path = | |||||
`${schemeItem.F_SchemeInfoId}.${t.table}.${dataIndex}.${t.field.toLowerCase()}` | |||||
const formDataValue = get(formData, path) | |||||
// useDefault 表示在从 formData 取不到值的时候使用默认值 | |||||
if (!formDataValue && useDefault) { | |||||
set(formValue, t.__valuePath__, await this.getDefaultData(t, prop)) | |||||
} else { | |||||
set(formValue, t.__valuePath__, await this.convertToFormValue(t, formDataValue)) | |||||
} | |||||
} else { | |||||
// 无表单值的情况,默认值 | |||||
set(formValue, t.__valuePath__, await this.getDefaultData(t, prop)) | |||||
} | |||||
} | |||||
// 权限控制 | |||||
const authObj = get(currentNode, `wfForms.${schemeIndex}.authorize.${t.id}`, {}) | |||||
t.edit = authObj.isEdit | |||||
if (Number(t.isHide) !== 1 && authObj.isLook !== 0) { | |||||
// 加入 scheme | |||||
scheme.push(t) | |||||
// organize、datetime 可能作为其他 organize 或 datetimerange 的依赖项,引用它们 | |||||
if (['organize', 'datetime'].includes(t.type)) { | |||||
schemeRef[t.id] = t | |||||
} | |||||
// datetimerange、带有 relation 级联字段的 organize,依赖其他项 | |||||
if ((t.type === 'datetimerange' && t.startTime && t.endTime) || (t.type === | |||||
'organize' && t.relation)) { | |||||
refList.push(t) | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
// 依次处理表单关联 | |||||
refList.forEach(t => { | |||||
if (t.type === 'organize') { | |||||
// 处理组件结构级联 | |||||
// 给当前组件赋上级级联的值路径 __relationPath__ | |||||
const parent = schemeRef[t.relation] | |||||
t.__relationPath__ = parent.__valuePath__ | |||||
// 给上级级联的组件注册自动重置当前组件的 change 事件 | |||||
const relItem = { | |||||
type: 'organize', | |||||
id: t.id, | |||||
path: t.__valuePath__ | |||||
} | |||||
rel[parent.id] = rel[parent.id] ? rel[parent.id].concat(relItem) : [relItem] | |||||
} else if (t.type === 'datetimerange') { | |||||
// 处理日期区间 | |||||
const start = schemeRef[t.startTime] | |||||
const end = schemeRef[t.endTime] | |||||
const relItem = { | |||||
type: 'datetimerange', | |||||
path: t.__valuePath__, | |||||
id: t.id, | |||||
startPath: start.__valuePath__, | |||||
endPath: end.__valuePath__, | |||||
} | |||||
rel[start.id] = rel[start.id] ? rel[start.id].concat(relItem) : [relItem] | |||||
rel[end.id] = rel[end.id] ? rel[end.id].concat(relItem) : [relItem] | |||||
} | |||||
}) | |||||
return { | |||||
scheme, | |||||
formValue, | |||||
rel | |||||
} | |||||
}, | |||||
newguid() { | |||||
return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) { | |||||
var r = Math.random() * 16 | 0, | |||||
v = c == 'x' ? r : (r & 0x3 | 0x8); | |||||
return v.toString(16); | |||||
}); | |||||
}, | |||||
/** | |||||
* 获取最终需要 POST 的数据 | |||||
* 参数:formValue, scheme | |||||
* 返回:用于提交的数据 | |||||
* | |||||
* 遍历 formValue,将其中的表单值依次使用 convertToPostData 这个方法转化为提交值 | |||||
*/ | |||||
async getPostData(originFormValue, scheme) { | |||||
const formValue = this.COPY(originFormValue) | |||||
// 依次按照 scheme 项目遍历 | |||||
for (const item of scheme) { | |||||
if (item.field) { | |||||
// 不是表格的情况 | |||||
const path = item.__valuePath__ | |||||
const val = get(formValue, path) | |||||
if (item.type == 'upload') { | |||||
// 先生成一个guid | |||||
var guid = this.newguid(); | |||||
// 取出当前列对应的labelId | |||||
var labeId = item.id | |||||
// 从缓存取出当前审批流程所有的guid | |||||
var guids = JSON.parse(uni.getStorageSync('guids')) | |||||
if (guids&&JSON.stringify(guids)!=='{}') { | |||||
guid = guids[labeId] | |||||
} | |||||
} | |||||
const result = await this.convertToPostData(item, val, originFormValue, scheme, guid) | |||||
set(formValue, path, result) | |||||
} else if (item.table && item.fieldsData) { | |||||
// 是表格的情况 | |||||
const tableValue = get(formValue, item.__valuePath__, []) | |||||
for (let valueIndex = 0; valueIndex < tableValue.length; ++valueIndex) { | |||||
for (const schemeItem of item.fieldsData) { | |||||
const path = `${item.__valuePath__}.${valueIndex}.${schemeItem.field}` | |||||
const val = get(formValue, path) | |||||
const result = await this.convertToPostData(schemeItem, val, originFormValue, scheme, | |||||
guid) | |||||
set(formValue, path, result) | |||||
} | |||||
} | |||||
} | |||||
} | |||||
formValue.formreq.forEach(t => { | |||||
t.formData = JSON.stringify(t.formData) | |||||
}) | |||||
formValue.formreq = JSON.stringify(formValue.formreq) | |||||
return formValue | |||||
}, | |||||
/** | |||||
* 获取流程信息 | |||||
* 参数: { code, processId, taskId } | |||||
* | |||||
*/ | |||||
async fetchProcessInfo({ | |||||
code, | |||||
processId, | |||||
taskId | |||||
}) { | |||||
const url = processId ? 'learun/adms/newwf/processinfo' : 'learun/adms/newwf/scheme' | |||||
const reqObj = { | |||||
processId | |||||
} | |||||
if (taskId) { | |||||
reqObj.taskId = taskId | |||||
} | |||||
const data = processId ? reqObj : code | |||||
const result = await this.HTTP_GET(url, data) | |||||
if (!result) { | |||||
return {} | |||||
} | |||||
if (result.info) { | |||||
result.info.Scheme = JSON.parse(result.info.Scheme) | |||||
} else if (result.F_Content) { | |||||
result.F_Content = JSON.parse(result.F_Content) | |||||
} | |||||
return result | |||||
}, | |||||
/** | |||||
* 从 processInfo 流程信息中,提取出 currentNode | |||||
* 参数: processInfo | |||||
* | |||||
*/ | |||||
getCurrentNode(processInfo) { | |||||
if (processInfo.info) { | |||||
return processInfo.info.Scheme.nodes.find(t => t.id === processInfo.info.CurrentNodeId) | |||||
} else if (processInfo.F_Content) { | |||||
return processInfo.F_Content.nodes.find(t => t.type === 'startround') | |||||
} | |||||
return {} | |||||
}, | |||||
/** | |||||
* 拉取表单的 schemeData | |||||
* 参数: currentNode | |||||
* | |||||
* 从当前节点 currentNode 中提取出表单 id,然后自 API 地址 /form/scheme 中拉取表单数据并返回 | |||||
*/ | |||||
async fetchSchemeData(currentNode, currentTask, type) { | |||||
const { | |||||
wfForms | |||||
} = currentNode | |||||
const data = wfForms.filter(t => t.formId).map(t => ({ | |||||
id: t.formId, | |||||
ver: '' | |||||
})) | |||||
const schemeData = await this.HTTP_GET('learun/adms/form/scheme', data) | |||||
return schemeData || {} | |||||
}, | |||||
/** | |||||
* 拉取表单的 formData | |||||
* 参数: currentNode, keyValue | |||||
* | |||||
* 提取当前节点信息、表单主键信息,从 API 地址 /form/data 中拉取表单数据 | |||||
*/ | |||||
async fetchFormData({ | |||||
wfForms | |||||
}, keyValue) { | |||||
const reqData = wfForms | |||||
.filter(t => t.formId) | |||||
.map(t => ({ | |||||
schemeInfoId: t.formId, | |||||
processIdName: t.field, | |||||
keyValue | |||||
})) | |||||
const formData = await this.HTTP_GET('learun/adms/form/data', reqData) | |||||
return formData || {} | |||||
}, | |||||
async fetchFolderkeyData(currentNode, keyValue) { | |||||
const { | |||||
wfForms | |||||
} = currentNode | |||||
const reqData = wfForms | |||||
.filter(t => t.formId) | |||||
.map(t => ({ | |||||
id: t.formId, | |||||
ver: '', | |||||
schemeInfoId: t.formId, | |||||
processIdName: t.field, | |||||
keyValue | |||||
})) | |||||
const folderkeyData = await this.HTTP_GET('learun/adms/form/folderkey', reqData) | |||||
return folderkeyData || {} | |||||
}, | |||||
} | |||||
} | } |
@@ -14,6 +14,7 @@ | |||||
<l-input title="住宿费" :value="formData.StuNo" placeholder="请填写" right /> | <l-input title="住宿费" :value="formData.StuNo" placeholder="请填写" right /> | ||||
<l-input title="应缴合计" :value="formData.StuNo" placeholder="请填写" right /> | <l-input title="应缴合计" :value="formData.StuNo" placeholder="请填写" right /> | ||||
<view class="btn" @click="submit">支 付</view> | <view class="btn" @click="submit">支 付</view> | ||||
<view class="btn" @click="lookInvoice">查看发票</view> | |||||
</view> | </view> | ||||
</template> | </template> | ||||
@@ -44,6 +45,9 @@ export default { | |||||
this.TOAST('缴费成功'); | this.TOAST('缴费成功'); | ||||
} | } | ||||
}); | }); | ||||
}, | |||||
lookInvoice(){ | |||||
this.NAV_TO("./payInvioce") | |||||
} | } | ||||
}, | }, | ||||
created() { | created() { | ||||
@@ -0,0 +1,63 @@ | |||||
<template> | |||||
<view> | |||||
<view class="menu"> | |||||
<view v-for="item in menuOptions" :key="item.active" :class="{menu_item:true,active:activeIndex==item.active}" @click="()=>{activeIndex = item.active;activeIndexChange(item)}"> | |||||
{{item.label}} | |||||
</view> | |||||
</view> | |||||
<iframe v-show="activeIndex == 1" src="https://www.baidu.com"></iframe> | |||||
<iframe v-show="activeIndex == 2" src="https://www.baidu.com"></iframe> | |||||
</view> | |||||
</template> | |||||
<script> | |||||
export default { | |||||
data() { | |||||
return { | |||||
menuOptions:[ | |||||
{active:1,label:"123"}, | |||||
{active:2,label:"456"} | |||||
], | |||||
activeIndex:1, | |||||
} | |||||
}, | |||||
methods: { | |||||
// 选项卡改变 | |||||
activeIndexChange(item){ | |||||
// | |||||
} | |||||
}, | |||||
} | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.menu{ | |||||
display: flex; | |||||
justify-content: space-between; | |||||
background-color: #fff; | |||||
border: 1px solid #E4E7ED; | |||||
.menu_item{ | |||||
flex: 1; | |||||
text-align: center; | |||||
box-sizing: border-box; | |||||
line-height: 36px; | |||||
border: 1px solid #E4E7ED; | |||||
position: relative; | |||||
} | |||||
.menu_item.active::after{ | |||||
content: ""; | |||||
display: block; | |||||
background-color: #409EFF; | |||||
position: absolute; | |||||
width: 50%; | |||||
height: 2px; | |||||
left: 0;right: 0; | |||||
margin: auto; | |||||
bottom: 0; | |||||
} | |||||
} | |||||
iframe{ | |||||
width: 100%; | |||||
height: calc(100vh - 40px); | |||||
} | |||||
</style> |
@@ -0,0 +1,47 @@ | |||||
<template> | |||||
<view> | |||||
<tki-qrcode | |||||
style="display: flex;justify-content: center;margin-top: 18px;" | |||||
ref="qrcode" | |||||
val="http://localhost:8080/#/pages/onlienpay/payqrcode?id=15641654" | |||||
:size="300" | |||||
:onval="true" | |||||
:loadMake="true" | |||||
/> | |||||
<view class="btn" @click="submit">查询结果</view> | |||||
<view class="btn bg-white" @click="cancel">取消</view> | |||||
</view> | |||||
</template> | |||||
<script> | |||||
export default { | |||||
data() { | |||||
return { | |||||
payData:"", | |||||
} | |||||
}, | |||||
methods: { | |||||
getPayData(id){ | |||||
this.LOADING(); | |||||
this.HTTP_GET('StuInfoFresh/saveStuInfoFresh', {id},).then(res => { | |||||
this.HIDE_LOADING(); | |||||
if (res) { | |||||
this.payData = res | |||||
} | |||||
}); | |||||
}, | |||||
cancel(){ | |||||
this.NAV_BACK() | |||||
} | |||||
}, | |||||
onLoad({id}) { | |||||
this.getPayData(id) | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang="scss"> | |||||
.bg-white{ | |||||
background-color: gray; | |||||
} | |||||
</style> |
@@ -36,7 +36,7 @@ | |||||
<view v-if="weekData.rows.length == 0">暂时没有信息</view> | <view v-if="weekData.rows.length == 0">暂时没有信息</view> | ||||
<view v-if="weekData.rows.length != 0"> | <view v-if="weekData.rows.length != 0"> | ||||
<view | <view | ||||
:class="timeTableClass(k.Sort)" | |||||
:class="[timeTableClass(k.Sort)]" | |||||
class="timeTableLi" v-for="(k, i) in weekData.rows" | class="timeTableLi" v-for="(k, i) in weekData.rows" | ||||
:key="k.StuNo" | :key="k.StuNo" | ||||
@click="tapTimeTable(i, timeTableClass(k.Sort))" | @click="tapTimeTable(i, timeTableClass(k.Sort))" | ||||
@@ -46,7 +46,7 @@ | |||||
</view> | </view> | ||||
</view> | </view> | ||||
</view> | </view> | ||||
<view class="timeTableAlert" :class="flag? 'active' : ''"> | |||||
<view class="timeTableAlert" :class="[flag? 'active' : '']"> | |||||
<view class="timeTableAlertTop"> | <view class="timeTableAlertTop"> | ||||
<view class="timeTableAlertT">{{ weekData.rows[ind].StuName }}</view> | <view class="timeTableAlertT">{{ weekData.rows[ind].StuName }}</view> | ||||
<view class="timeTableAlertTxt">学号: {{ weekData.rows[ind].StuNo }} </view> | <view class="timeTableAlertTxt">学号: {{ weekData.rows[ind].StuNo }} </view> | ||||
@@ -55,7 +55,7 @@ | |||||
<view | <view | ||||
v-for="(n, i) in Statue" | v-for="(n, i) in Statue" | ||||
:key="i" | :key="i" | ||||
:class="n.className == className? 'active ' + n.className : n.className" | |||||
:class="[n.className == className? 'active ' + n.className : n.className]" | |||||
class="timeTableAlertLi" | class="timeTableAlertLi" | ||||
@click="tapStatus(i)" | @click="tapStatus(i)" | ||||
><text></text>{{ n.txt }}</view> | ><text></text>{{ n.txt }}</view> | ||||
@@ -491,6 +491,7 @@ export default{ | |||||
text-align: center; | text-align: center; | ||||
font-size: 14px; | font-size: 14px; | ||||
color: #1a1a1a; | color: #1a1a1a; | ||||
background-color: #ffffff; | |||||
} | } | ||||
.timeTableAlertLi.active { | .timeTableAlertLi.active { | ||||
@@ -500,8 +501,4 @@ export default{ | |||||
.timeTableAlertLi:nth-child(2n) { | .timeTableAlertLi:nth-child(2n) { | ||||
background-color: #fbfdff; | background-color: #fbfdff; | ||||
} | } | ||||
.timeTableAlertLi:nth-child(2n - 1) { | |||||
background-color: #ffffff; | |||||
} | |||||
</style> | </style> |
@@ -72,7 +72,6 @@ export default { | |||||
'加载数据时出错' | '加载数据时出错' | ||||
).then( res => { | ).then( res => { | ||||
this.HIDE_LOADING() | this.HIDE_LOADING() | ||||
// console.log(res) | |||||
if (res == null || JSON.stringify(res) == '{}') { | if (res == null || JSON.stringify(res) == '{}') { | ||||
_this.flag = false; | _this.flag = false; | ||||
return; | return; | ||||
@@ -28,10 +28,10 @@ | |||||
<view class="tSec2Box"> | <view class="tSec2Box"> | ||||
<view class="tSec2Con" v-for="(items, i) in weekArr" :key="items.num" v-show="i == num"> | <view class="tSec2Con" v-for="(items, i) in weekArr" :key="items.num" v-show="i == num"> | ||||
<view class="tSec2List"> | <view class="tSec2List"> | ||||
<view v-if="dataArr[i+1].length <= 0" class="tSec2ListLi"> | |||||
<view v-if="dataArr[i+1]&&dataArr[i+1].length <= 0" class="tSec2ListLi"> | |||||
<view class="noHtml">该时间段没有课表</view> | <view class="noHtml">该时间段没有课表</view> | ||||
</view> | </view> | ||||
<view v-if="dataArr[i+1].length > 0"> | |||||
<view v-if="dataArr[i+1]&&dataArr[i+1].length > 0"> | |||||
<view class="tSec2ListLi" v-for="(k, j) in dataArr[i+1]" :key="j" @click="classTap(k)"> | <view class="tSec2ListLi" v-for="(k, j) in dataArr[i+1]" :key="j" @click="classTap(k)"> | ||||
<view class="tSec2ListL">第 {{ k.jc }} 节</view> | <view class="tSec2ListL">第 {{ k.jc }} 节</view> | ||||
<view class="tSec2ListR"> | <view class="tSec2ListR"> | ||||
@@ -25,13 +25,13 @@ | |||||
</view> | </view> | ||||
<!-- 账户密码表单 --> | <!-- 账户密码表单 --> | ||||
<l-input v-if="ready" v-model="username" placeholder="手机号 / 账号" left> | |||||
<l-input v-if="ready" v-model="username" placeholder="身份证号" left> | |||||
<l-icon slot="title" type="people" /> | <l-icon slot="title" type="people" /> | ||||
</l-input> | </l-input> | ||||
<l-input v-if="ready" v-model="password" placeholder="请输入身份证后八位" password left> | <l-input v-if="ready" v-model="password" placeholder="请输入身份证后八位" password left> | ||||
<l-icon slot="title" type="lock" /> | <l-icon slot="title" type="lock" /> | ||||
</l-input> | </l-input> | ||||
<l-button @click="login(null)" size="lg" color="blue" class="margin-top-sm block" block>确 认</l-button> | |||||
<l-button v-if="ready" @click="loginClick(null)" size="lg" color="blue" class="margin-top-sm block" block>确 认</l-button> | |||||
<view class="otherLogin"> | <view class="otherLogin"> | ||||
<navigator url="/pages/login" class="textBtn">常规登陆</text></navigator> | <navigator url="/pages/login" class="textBtn">常规登陆</text></navigator> | ||||
</view> | </view> | ||||
@@ -68,11 +68,14 @@ | |||||
</template> | </template> | ||||
<script> | <script> | ||||
import moment from 'moment'; | |||||
export default { | export default { | ||||
data() { | data() { | ||||
return { | return { | ||||
username: '', | username: '', | ||||
password: '', | password: '', | ||||
code:'', | |||||
ready: false, | ready: false, | ||||
showApiRootSelector: false, | showApiRootSelector: false, | ||||
@@ -84,6 +87,9 @@ export default { | |||||
}, | }, | ||||
async onLoad() { | async onLoad() { | ||||
if(this.getHashSearchParam("code")){ | |||||
this.code = this.getHashSearchParam("code") | |||||
} | |||||
await this.init() | await this.init() | ||||
}, | }, | ||||
@@ -101,15 +107,103 @@ export default { | |||||
this.username = account.username | this.username = account.username | ||||
this.password = account.password | this.password = account.password | ||||
} | } | ||||
this.ready = true | |||||
// this.ready = true | |||||
this.loginInit() | |||||
}, | }, | ||||
getHashSearchParam(key) { | |||||
let search = location.search | |||||
let array = [] | |||||
if(search){ | |||||
search = search.substring(1) | |||||
array = search.split("&") | |||||
let res = array.find((item)=>item.split("=")[0] == key) | |||||
return res.split("=")[1] | |||||
} | |||||
return '' | |||||
}, | |||||
// 点击新用户注册 | // 点击新用户注册 | ||||
signUp() { | signUp() { | ||||
this.NAV_TO('/pages/signup') | this.NAV_TO('/pages/signup') | ||||
}, | }, | ||||
// 切换后台地址 | |||||
loginInit(){ | |||||
if (this.code) { | |||||
this.LOADING("加载中...") | |||||
this.HTTP_POST("weixinapi/getweixinaccess_token?code="+this.code,null).then(success=>{ | |||||
this.HIDE_LOADING() | |||||
if(!success){ | |||||
location.href = "http://" + window.location.host; | |||||
return | |||||
} | |||||
if(success.logined){ | |||||
// var logininfo = { | |||||
// account: account, | |||||
// token: success.baseinfo.token, | |||||
// date: moment().format('yyyy-MM-dd hh:mm:ss') | |||||
// }; | |||||
this.SET_STORAGE("token",success.baseinfo.token) | |||||
// this.SET_STORAGE("logininfo",logininfo) | |||||
// this.SET_STORAGE("userinfo",success) | |||||
location.href = "http://" + window.location.host + "/#/pages/my/newpassword"; | |||||
// location.href = "http://" + window.location.host; | |||||
}else{ | |||||
this.ready = true | |||||
this.openid = success.openid | |||||
} | |||||
}) | |||||
} else { | |||||
this.HIDE_LOADING(); | |||||
this.HTTP_GET("weixinapi/weixinconfig").then(success=>{ | |||||
if(!success){ | |||||
return | |||||
} | |||||
window.location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + success.appid + "&redirect_uri=" + encodeURIComponent('http://' + window.location.host + '/#/pages/weixinLogin') + "&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect"; | |||||
}) | |||||
} | |||||
}, | |||||
loginClick(){ | |||||
// 点击登录 | |||||
// 账号密码登录时,验证输入,输入有误则返回 | |||||
if (!this.check()) { | |||||
return | |||||
} | |||||
let up = true | |||||
var postData = { | |||||
username: this.username, | |||||
password: this.password, | |||||
openid: this.openid, | |||||
up: up | |||||
}; | |||||
this.LOADING("正在登录,请稍后") | |||||
this.HTTP_POST("weixinapi/loginbyidcard", postData).then(success=>{ | |||||
this.HIDE_LOADING() | |||||
if(!success){ | |||||
return | |||||
} | |||||
var logininfo = { | |||||
account: this.username, | |||||
token: success.baseinfo.token, | |||||
date: moment().format('yyyy-MM-dd hh:mm:ss') | |||||
}; | |||||
this.SET_STORAGE("token",success.baseinfo.token) | |||||
// this.SET_STORAGE('logininfo', logininfo); | |||||
// this.SET_STORAGE('userinfo', success); | |||||
this.username = "" | |||||
this.password = "" | |||||
if (success.pwd === true) { | |||||
this.SET_STORAGE('pwd', true); | |||||
this.TOAST("绑定失败!您的密码不满足强度要求,请您先修改密码后再执行系统其他操作"); | |||||
} else { | |||||
this.SET_STORAGE('pwd', false); | |||||
} | |||||
location.href = "http://" + window.location.host + "/#/pages/my/newpassword"; | |||||
}) | |||||
}, | |||||
// 切换后台地址 | |||||
changeApiRoot(newIndex) { | changeApiRoot(newIndex) { | ||||
const newApiRoot = this.apiRootList[newIndex] | const newApiRoot = this.apiRootList[newIndex] | ||||
this.currentApiRoot = newApiRoot | this.currentApiRoot = newApiRoot | ||||
@@ -272,7 +366,7 @@ page { | |||||
.otherLogin{ | .otherLogin{ | ||||
display: flex; | display: flex; | ||||
justify-content: right; | |||||
justify-content: flex-end; | |||||
.textBtn{ | .textBtn{ | ||||
width: 100px; | width: 100px; | ||||
color: #606266; | color: #606266; | ||||
@@ -170,6 +170,7 @@ export default { | |||||
this.HTTP_GET('StuInfoFresh/saveStuInfoFresh', this.queryData).then(res => { | this.HTTP_GET('StuInfoFresh/saveStuInfoFresh', this.queryData).then(res => { | ||||
this.HIDE_LOADING(); | this.HIDE_LOADING(); | ||||
if (res) { | if (res) { | ||||
this.NAV_TO("/pages/my/newpassword") | |||||
this.TOAST('保存成功'); | this.TOAST('保存成功'); | ||||
} | } | ||||
}); | }); | ||||
@@ -20,6 +20,21 @@ | |||||
<SccProvider> | <SccProvider> | ||||
</SccProvider> | </SccProvider> | ||||
<TargetFrameworkProfile /> | <TargetFrameworkProfile /> | ||||
<PublishUrl>publish\</PublishUrl> | |||||
<Install>true</Install> | |||||
<InstallFrom>Disk</InstallFrom> | |||||
<UpdateEnabled>false</UpdateEnabled> | |||||
<UpdateMode>Foreground</UpdateMode> | |||||
<UpdateInterval>7</UpdateInterval> | |||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits> | |||||
<UpdatePeriodically>false</UpdatePeriodically> | |||||
<UpdateRequired>false</UpdateRequired> | |||||
<MapFileExtensions>true</MapFileExtensions> | |||||
<ApplicationRevision>0</ApplicationRevision> | |||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion> | |||||
<IsWebBootstrapper>false</IsWebBootstrapper> | |||||
<UseApplicationTrust>false</UseApplicationTrust> | |||||
<BootstrapperEnabled>true</BootstrapperEnabled> | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | ||||
<PlatformTarget>x64</PlatformTarget> | <PlatformTarget>x64</PlatformTarget> | ||||
@@ -138,5 +153,17 @@ | |||||
<Name>Learun.DataBase</Name> | <Name>Learun.DataBase</Name> | ||||
</ProjectReference> | </ProjectReference> | ||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | |||||
<BootstrapperPackage Include=".NETFramework,Version=v4.6.1"> | |||||
<Visible>False</Visible> | |||||
<ProductName>Microsoft .NET Framework 4.6.1 %28x86 和 x64%29</ProductName> | |||||
<Install>true</Install> | |||||
</BootstrapperPackage> | |||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1"> | |||||
<Visible>False</Visible> | |||||
<ProductName>.NET Framework 3.5 SP1</ProductName> | |||||
<Install>false</Install> | |||||
</BootstrapperPackage> | |||||
</ItemGroup> | |||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | ||||
</Project> | </Project> |