Преглед изворни кода

Merge branch '西昌分支' of http://123.57.209.16:3000/bjquanjiang/DigitalScholl into 西昌分支

西昌缴费二期
zhangli пре 2 година
родитељ
комит
23dc5c4991
52 измењених фајлова са 2193 додато и 1165 уклоњено
  1. +1
    -1
      Learun.Framework.Ultimate V7/Learun.Application.Mobile/www/scripts/weixinlogin.js
  2. +1
    -4
      Learun.Framework.Ultimate V7/Learun.Application.Web/Areas/EducationalAdministration/Controllers/StuInfoFreshController.cs
  3. +1
    -2
      Learun.Framework.Ultimate V7/Learun.Application.Web/Areas/EducationalAdministration/Views/StuInfoBasic_PayFee/PayFeeForm.js
  4. +2
    -2
      Learun.Framework.Ultimate V7/Learun.Application.Web/Areas/EducationalAdministration/Views/StuInfoBasic_PayFee/PayFeeIndex.js
  5. +2
    -1
      Learun.Framework.Ultimate V7/Learun.Application.Web/Areas/EducationalAdministration/Views/StuInfoFresh/PayFeeForm.js
  6. +9
    -3
      Learun.Framework.Ultimate V7/Learun.Application.Web/Areas/EducationalAdministration/Views/StuInfoFresh/PayFeeIndex.js
  7. +7
    -6
      Learun.Framework.Ultimate V7/Learun.Application.Web/Views/UserCenter/Index.cshtml
  8. +1
    -1
      Learun.Framework.Ultimate V7/Learun.Application.Web/XmlConfig/system.config
  9. +5
    -0
      Learun.Framework.Ultimate V7/Learun.Application.WebApi/Learun.Application.WebApi.csproj
  10. +129
    -130
      Learun.Framework.Ultimate V7/Learun.Application.WebApi/Modules/AnnexesApiWx.cs
  11. +45
    -0
      Learun.Framework.Ultimate V7/Learun.Application.WebApi/Modules/FormApi.cs
  12. +219
    -0
      Learun.Framework.Ultimate V7/Learun.Application.WebApi/Modules/StuFreshPayFeeApi.cs
  13. +215
    -0
      Learun.Framework.Ultimate V7/Learun.Application.WebApi/Modules/StuPayFeeApi.cs
  14. +81
    -1
      Learun.Framework.Ultimate V7/Learun.Application.WebApi/Modules/WeixinApi.cs
  15. +1
    -0
      Learun.Framework.Ultimate V7/Learun.Application.WebApi/XmlConfig/system.config
  16. +1
    -0
      Learun.Framework.Ultimate V7/Learun.Application.WebApi/packages.config
  17. +85
    -1
      Learun.Framework.Ultimate V7/Learun.Framework.Module/Learun.Application.Module/Learun.Application.Form/Scheme/FormSchemeBLL.cs
  18. +2
    -0
      Learun.Framework.Ultimate V7/Learun.Framework.Module/Learun.Application.Module/Learun.Application.Form/Scheme/FormSchemeIBLL.cs
  19. +1
    -1
      Learun.Framework.Ultimate V7/Learun.Framework.Module/Learun.Application.Module/Learun.Application.TwoDevelopment/EducationalAdministration/StuInfoBasic_PayFee/StuInfoBasic_PayFeeEntity.cs
  20. +4
    -0
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/.hbuilderx/launch.json
  21. +1
    -1
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/App.vue
  22. +306
    -270
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/common/customform.js
  23. +6
    -2
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/common/custompage.js
  24. +15
    -6
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/common/mixins.js
  25. +5
    -2
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/components/learun-app/customform.vue
  26. +1
    -1
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/components/learun-app/upload-file.vue
  27. +266
    -269
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/components/upload-file.vue
  28. +3
    -3
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/config.js
  29. +1
    -1
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/manifest.json
  30. +9
    -0
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages.json
  31. +5
    -4
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/EvaluationTeach/list.vue
  32. +114
    -122
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/EvaluationTeach/single.vue
  33. +1
    -4
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/Thermography/measure/list.vue
  34. +1
    -1
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/login.vue
  35. +1
    -1
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/msg.vue
  36. +1
    -1
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/msg/chat.vue
  37. +1
    -1
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/my.vue
  38. +1
    -1
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/my/info.vue
  39. +1
    -1
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/my/qrcode.vue
  40. +1
    -1
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/myAttendance/single.vue
  41. +6
    -8
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/nworkflow/myflow/single.vue
  42. +9
    -3
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/nworkflow/releasetask/single.vue
  43. +379
    -294
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/nworkflow/workflow.js
  44. +4
    -0
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/onlienpay/list.vue
  45. +63
    -0
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/onlienpay/payInvioce.vue
  46. +47
    -0
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/onlienpay/payqrcode.vue
  47. +4
    -7
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/studentAttendance/single.vue
  48. +0
    -1
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/studentSee/list.vue
  49. +2
    -2
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/timeTable/list.vue
  50. +99
    -5
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/weixinLogin.vue
  51. +1
    -0
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/welcome/list.vue
  52. +27
    -0
      Learun.Framework.Ultimate V7/Quanjiang.DigitalScholl.JobService/Quanjiang.DigitalScholl.JobService.csproj

+ 1
- 1
Learun.Framework.Ultimate V7/Learun.Application.Mobile/www/scripts/weixinlogin.js Прегледај датотеку

@@ -1,4 +1,4 @@
function GetQueryString(name) {
function GetQueryString(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);//search,查询?后面的参数,并匹配正则
if (r != null) return unescape(r[2]); return null;


+ 1
- 4
Learun.Framework.Ultimate V7/Learun.Application.Web/Areas/EducationalAdministration/Controllers/StuInfoFreshController.cs Прегледај датотеку

@@ -665,7 +665,7 @@ namespace Learun.Application.Web.Areas.EducationalAdministration.Controllers
FinaChargesStandardList = FinaChargesStandardList,
StuInfoFreshFamilyList = stuInfoFreshFamily,
PayFeeTotal = PayFeeTotal,
YJAmount = FeeOrderList.Sum(x => x.SJAmount)
YJAmount = FinaChargesStandardList.Sum(x => x.PayedMoney)
};
return Success(jsonData);
}
@@ -1321,9 +1321,6 @@ namespace Learun.Application.Web.Areas.EducationalAdministration.Controllers

if (!string.IsNullOrEmpty(imgUrl))
{
// model.PayFeeDetail = entity.PayFeeDetail;
// model.PayMoney = entity.PayMoney;
model.LoanMoney = entity.LoanMoney;
model.orderid = orderid;
stuInfoFreshIBLL.SaveFeeData(keyValue, model, list);
}


+ 1
- 2
Learun.Framework.Ultimate V7/Learun.Application.Web/Areas/EducationalAdministration/Views/StuInfoBasic_PayFee/PayFeeForm.js Прегледај датотеку

@@ -115,6 +115,7 @@ var bootstrap = function ($, learun) {
var detail = "";
var ifisnull = false;
$('.paydetail').each(function (i, item) {
$(this).attr('disabled', 'disabled');
var value = 0;
if (!!$(this).val()) {
value = parseFloat($(this).val());
@@ -142,8 +143,6 @@ var bootstrap = function ($, learun) {
param.PayMoney = $('#PayMoney').html();
learun.loading(true, '正在生成付款信息请稍等...');
$("#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.loading(false);
$('#qrcodeImg').attr('src', res.info);


+ 2
- 2
Learun.Framework.Ultimate V7/Learun.Application.Web/Areas/EducationalAdministration/Views/StuInfoBasic_PayFee/PayFeeIndex.js Прегледај датотеку

@@ -52,7 +52,7 @@ var bootstrap = function ($, learun) {
title: '二维码缴费',
url: top.$.rootUrl + '/EducationalAdministration/StuInfoBasic_PayFee/PayFeeForm?keyValue=' + keyValue,
width: 800,
height: 650,
height: 690,
btn: null
});
}
@@ -108,7 +108,7 @@ var bootstrap = function ($, learun) {
{
label: "性别", name: "GenderNo", width: 80, align: "left",
formatter: function (cellvalue) {
return cellvalue == true ? "男" : "女";
return cellvalue === true ? "男" : "女";
}
},
{ label: "身份证号", name: "IdentityCardNo", width: 150, align: "left" },


+ 2
- 1
Learun.Framework.Ultimate V7/Learun.Application.Web/Areas/EducationalAdministration/Views/StuInfoFresh/PayFeeForm.js Прегледај датотеку

@@ -102,7 +102,7 @@ var bootstrap = function ($, learun) {
$.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\">应缴合计</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\">&nbsp;</td><td colspan="2">&nbsp;</td></tr>';
html += '<tr><td class=\"tableLeft\">已缴金额</td><td colspan="2">' + YJAmount + '</td></tr>';
$('#PayFeeDetail').html(html);
@@ -114,6 +114,7 @@ var bootstrap = function ($, learun) {
var detail = "";
var ifisnull = false;
$('.paydetail').each(function (i, item) {
$(this).attr('disabled', 'disabled');
var value = 0;
if (!!$(this).val()) {
value = parseFloat($(this).val());


+ 9
- 3
Learun.Framework.Ultimate V7/Learun.Application.Web/Areas/EducationalAdministration/Views/StuInfoFresh/PayFeeIndex.js Прегледај датотеку

@@ -53,7 +53,7 @@ var bootstrap = function ($, learun) {
title: '二维码缴费',
url: top.$.rootUrl + '/EducationalAdministration/StuInfoFresh/PayFeeForm?keyValue=' + keyValue,
width: 800,
height: 650,
height: 690,
btn: null
});
}
@@ -302,8 +302,14 @@ var bootstrap = function ($, learun) {
{ label: '学号', name: 'StuNo', 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" },


+ 7
- 6
Learun.Framework.Ultimate V7/Learun.Application.Web/Views/UserCenter/Index.cshtml Прегледај датотеку

@@ -15,14 +15,14 @@
<div class="lr-layout-wrap lr-layout-wrap-notitle" style="padding-top:10px;">
<div class="lr-layout-body">
<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="3">我的头像</li>
<li data-value="4">修改密码</li>
<li data-value="5">我的日志</li>
@if (ViewBag.UserType == "学生")
{
<li data-value="6">选修流程</li>
@*<li data-value="6">选修流程</li>*@
}
<li data-value="7">语言设置</li>
</ul>
@@ -190,6 +190,7 @@
},
filters: {
sex: function (value) {
console.log(value);
return value ? "男生" : "女生";

},
@@ -686,7 +687,7 @@
</div>
@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>
@@ -710,7 +711,7 @@
3、选择课只开放三天,三天后自动关闭选课功能,每门选修课记2个选修学分,如果修不够选修学分将会无法毕业。<br />
</p>
</div>
</div>
</div>*@
}

@if (ViewBag.UserType == "学生" || ViewBag.UserType == "教师")
@@ -742,8 +743,8 @@
$("#headUrl").attr("src", "/LR_OrganizationModule/User/GetImg?userId=" + loginInfo.userId);

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 {
$("#lr_left_list").children('li').eq(0).addClass("active");


+ 1
- 1
Learun.Framework.Ultimate V7/Learun.Application.Web/XmlConfig/system.config Прегледај датотеку

@@ -154,7 +154,7 @@
<add key="ACIp" value="192.168.90.2"/>
<add key="ACIp2" value="192.168.200.252"/>
<!-- 是否强制验证强密码 -->
<add key="verifypwd" value="true"/>
<add key="verifypwd" value="false"/>
<!--疫情防控组角色Id-->
<add key="EpidemicControlTeamRoleId" value="87f38e4e-b0a6-472c-b01a-2620b8f1ec46" />
<!--注册教师生成编号 金隅:jy;西昌:xc;大厂:dc-->


+ 5
- 0
Learun.Framework.Ultimate V7/Learun.Application.WebApi/Learun.Application.WebApi.csproj Прегледај датотеку

@@ -156,6 +156,9 @@
<Reference Include="System.Web.Services" />
<Reference Include="System.EnterpriseServices" />
<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">
<HintPath>..\packages\WebGrease.1.5.2\lib\WebGrease.dll</HintPath>
</Reference>
@@ -192,6 +195,8 @@
<ItemGroup>
<Compile Include="Bootstraper.cs" />
<Compile Include="Modules\AnnexesApiWx.cs" />
<Compile Include="Modules\StuFreshPayFeeApi.cs" />
<Compile Include="Modules\StuPayFeeApi.cs" />
<Compile Include="Modules\BaseNoLoginApi.cs" />
<Compile Include="Modules\ArrangeLessonTermAttemperApi.cs" />
<Compile Include="Modules\DataSourceNoLoginApi.cs" />


+ 129
- 130
Learun.Framework.Ultimate V7/Learun.Application.WebApi/Modules/AnnexesApiWx.cs Прегледај датотеку

@@ -7,136 +7,135 @@ using System.IO;

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("");
}
}
}

+ 45
- 0
Learun.Framework.Ultimate V7/Learun.Application.WebApi/Modules/FormApi.cs Прегледај датотеку

@@ -21,12 +21,28 @@ namespace Learun.Application.WebApi.Modules
{
Get["/scheme"] = GetScheme;
Get["/data"] = GetData;
Get["/folderkey"] = GetFolderkey;

Post["/save"] = Save;
Post["/delete"] = DeleteForm;
}
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>
@@ -104,6 +120,35 @@ namespace Learun.Application.WebApi.Modules
}

#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 {
/// <summary>
/// 表单请求Id


+ 219
- 0
Learun.Framework.Ultimate V7/Learun.Application.WebApi/Modules/StuFreshPayFeeApi.cs Прегледај датотеку

@@ -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";
}
}
}

+ 215
- 0
Learun.Framework.Ultimate V7/Learun.Application.WebApi/Modules/StuPayFeeApi.cs Прегледај датотеку

@@ -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";
}
}
}

+ 81
- 1
Learun.Framework.Ultimate V7/Learun.Application.WebApi/Modules/WeixinApi.cs Прегледај датотеку

@@ -36,6 +36,8 @@ namespace Learun.Application.WebApi.Modules
Get["/weixinconfig"] = GetWeixinConfig;
Post["/getweixinaccess_token"] = GetWeixinAccess_token;
Post["/login"] = Login;
//新生首次登陆
Post["/loginbyidcard"] = LoginByIdCard;
Get["/getweixinwebaccess_token"] = GetWeixinWebaccess_token;
//获取ACIp
Get["/GetACIp"] = GetACIp;
@@ -100,6 +102,13 @@ namespace Learun.Application.WebApi.Modules
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 _)
{
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");
if (!string.IsNullOrEmpty(responsejson))
{
var weixintokenobj = JsonConvert.DeserializeObject<dynamic>(responsejson);
var weixintokenobj = JsonConvert.DeserializeObject<wxinfo>(responsejson);
if (string.IsNullOrEmpty(weixintokenobj.errcode))
{
string openid = weixintokenobj.openid;
@@ -241,6 +250,77 @@ namespace Learun.Application.WebApi.Modules
#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 _)
{
var entity = weChatConfigIbll.GetEnableEntity();


+ 1
- 0
Learun.Framework.Ultimate V7/Learun.Application.WebApi/XmlConfig/system.config Прегледај датотеку

@@ -66,6 +66,7 @@
<add key="userKey" value="14B417B0-463D-4F2B-8075-0A20EEDB773A" />
<!-- ==================注意附件上传地址 修改到主网站部署目录下的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="workflowapi" value="http://localhost:8013" />


+ 1
- 0
Learun.Framework.Ultimate V7/Learun.Application.WebApi/packages.config Прегледај датотеку

@@ -30,6 +30,7 @@
<package id="Oracle.ManagedDataAccess" version="12.1.24160719" 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="ThoughtWorks.QRCode" version="1.1.0" targetFramework="net461" />
<package id="Unity" version="4.0.1" targetFramework="net45" />
<package id="WebGrease" version="1.5.2" targetFramework="net45" />
</packages>

+ 85
- 1
Learun.Framework.Ultimate V7/Learun.Framework.Module/Learun.Application.Module/Learun.Application.Form/Scheme/FormSchemeBLL.cs Прегледај датотеку

@@ -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>


+ 2
- 0
Learun.Framework.Ultimate V7/Learun.Framework.Module/Learun.Application.Module/Learun.Application.Form/Scheme/FormSchemeIBLL.cs Прегледај датотеку

@@ -137,5 +137,7 @@ namespace Learun.Application.Form
/// <param name="keyValue">数据主键值</param>
void DeleteInstanceForm(string schemeInfoId, string keyValue);
#endregion

Dictionary<string, string> GetFolderKey(string itemSchemeInfoId, string itemProcessIdName, string itemKeyValue);
}
}

+ 1
- 1
Learun.Framework.Ultimate V7/Learun.Framework.Module/Learun.Application.Module/Learun.Application.TwoDevelopment/EducationalAdministration/StuInfoBasic_PayFee/StuInfoBasic_PayFeeEntity.cs Прегледај датотеку

@@ -62,7 +62,7 @@ namespace Learun.Application.TwoDevelopment.EducationalAdministration

[NotMapped] public string StuCode { 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 DeptNo { get; set; }
[NotMapped] public string MajorNo { get; set; }


+ 4
- 0
Learun.Framework.Ultimate V7/LearunApp-2.2.0/.hbuilderx/launch.json Прегледај датотеку

@@ -10,6 +10,10 @@
{
"launchtype" : "remote"
},
"mp-weixin" :
{
"launchtype" : "remote"
},
"type" : "uniCloud"
}
]


+ 1
- 1
Learun.Framework.Ultimate V7/LearunApp-2.2.0/App.vue Прегледај датотеку

@@ -10,7 +10,7 @@
// H5 刷新时获取当前页面路径
const pagePath = "/" + param.path;
// 如果 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.TAB_TO("/pages/home");
return;


+ 306
- 270
Learun.Framework.Ultimate V7/LearunApp-2.2.0/common/customform.js Прегледај датотеку

@@ -24,274 +24,310 @@ import moment from 'moment'
*/

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 || ''
}
}
}
}

+ 6
- 2
Learun.Framework.Ultimate V7/LearunApp-2.2.0/common/custompage.js Прегледај датотеку

@@ -1,3 +1,4 @@
import { conforms } from 'lodash'
import get from 'lodash/get'
import omit from 'lodash/omit'
import moment from 'moment'
@@ -233,7 +234,11 @@ export default {
} else {
for (const [fieldName, scheme] of Object.entries(schemeItem)) {
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 path = this.API + '/learun/adms/annexes/wxdown?' + this.URL_QUERY(uid, true)

fileList.push({ path, type: fileType, uid, size: fileSize })
}
return fileList


+ 15
- 6
Learun.Framework.Ultimate V7/LearunApp-2.2.0/common/mixins.js Прегледај датотеку

@@ -229,6 +229,14 @@ export default {

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 请求,集成了验证信息
// 返回请求结果或 null
@@ -258,8 +266,8 @@ export default {
// url 为请求地址
// filePath 为临时文件的路径
// 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)
},
@@ -308,11 +316,12 @@ export default {
// 返回结果是一个数组: [error, result]
// error 表示错误,一般是网络错误,请求很可能根本没有发出
// result 包含 { statusCode, data } 分别表示状态码、接口返回的数据
async UPLOAD(url, filePath, formData) {
async UPLOAD(url, filePath, formData,guid) {
const uploadUrl = this.handleUrl(url)
const query = {
loginMark: this.getLoginMark(),
token: this.GET_GLOBAL('token')
token: this.GET_GLOBAL('token'),
folderId:guid
}

if (formData && typeof formData === 'object') {
@@ -683,13 +692,13 @@ export default {
if(result.data.code != 200){
uni.hideLoading()
uni.showToast({
title: tips||result.data.info||"未知错误",
title: result.data.info,
icon: 'none'
})
return null
}

return result.data.data||true
return result.data.data
},

// 【即将废弃】请使用 this.CONFIG() 来替代


+ 5
- 2
Learun.Framework.Ultimate V7/LearunApp-2.2.0/components/learun-app/customform.vue Прегледај датотеку

@@ -194,12 +194,14 @@ export default {
// 依次验证表单项,返回一个所有错误提示的数组,如果为空数组则表示无错误
verifyValue() {
const errorList = []
console.log(this.scheme)
this.scheme
.filter(t => t.verify)
.forEach(schemeItem => {
if (schemeItem.table && schemeItem.field) {
console.log(schemeItem.verify,'hemeItem.verify')
const verifyFunc = this.verify[schemeItem.verify]
console.log(schemeItem.verify)
const verifyResult = verifyFunc(this.getValue(schemeItem.__valuePath__))
if (verifyResult !== true) {
errorList.push(`[${schemeItem.title}]: ${verifyResult}`)
@@ -304,7 +306,8 @@ export default {
MobileOrPhoneOrNull: t =>
t.length <= 0 || /^1[0-9]{10}$/.test(t) || /^[+0-9- ]*$/.test(t) || '须留空或符合手机/电话号码格式',
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) || '请输入正确的整数或小数(不能为零和负数)'
}
}
}


+ 1
- 1
Learun.Framework.Ultimate V7/LearunApp-2.2.0/components/learun-app/upload-file.vue Прегледај датотеку

@@ -89,7 +89,7 @@ export default {
// #endif

// #ifndef MP-DINGTALK
uni.chooseImage({
uni.chooseFile({
count: Number(this.number),
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],


+ 266
- 269
Learun.Framework.Ultimate V7/LearunApp-2.2.0/components/upload-file.vue Прегледај датотеку

@@ -1,296 +1,293 @@
<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>

<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>

<style scoped>
.file-name{
.file-name {
position: absolute;
bottom: 0;
width: 100%;
color: #606266;
font-size: 13px;
text-align: center;
background-color: rgba(255,255,255,0.6);
background-color: rgba(255, 255, 255, 0.6);
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;


+ 3
- 3
Learun.Framework.Ultimate V7/LearunApp-2.2.0/config.js Прегледај датотеку

@@ -21,10 +21,10 @@ export default {
// "http://192.168.2.98:8088/"
// ],
"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": [
// 20201130230 21364200000400266 老师 420528196310072253 学生 420528200606205026 420528200507261428


+ 1
- 1
Learun.Framework.Ultimate V7/LearunApp-2.2.0/manifest.json Прегледај датотеку

@@ -119,7 +119,7 @@
"quickapp" : {},
/* 小程序特有相关 */
"mp-weixin" : {
"appid" : "wxbc18c9bf92c86d28",
"appid" : "wx36f8c96ee26af75b",
"setting" : {
"urlCheck" : false,
"es6" : true,


+ 9
- 0
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages.json Прегледај датотеку

@@ -1028,6 +1028,15 @@
}
}
,{
"path" : "pages/onlienpay/payInvioce",
"style" :
{
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}
],

// 全局样式


+ 5
- 4
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/EvaluationTeach/list.vue Прегледај датотеку

@@ -3,7 +3,8 @@
<!-- 主列表页 -->
<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">
@@ -26,14 +27,14 @@
{{ displayListItem(item, 'EmpName') }}
</view>
<view class="customlist-item-field">
<view class="customlist-item-field">
<text class="customlist-item-field-title">课程名称:</text>
{{ displayListItem(item, 'LessonName') }}
{{ displayListItem(item, 'LessonName') }}
</view>
<view class="customlist-item-field">
<text class="customlist-item-field-title">评教状态:</text>
{{ displayListItem(item, 'UID') }}
</view>
</view>
<l-customlist-action @view="action('view', item)" />


+ 114
- 122
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/EvaluationTeach/single.vue Прегледај датотеку

@@ -1,69 +1,63 @@
<template>
<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;">
<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 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>
</template>
<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 set from 'lodash/set'
@@ -74,73 +68,50 @@ export default {
mixins: [customPageMixins],
data() {
return {
return {
aa:"",
bbb:[],
// 页面相关参数
id: null,
mode: 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: {
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()
this.ready = true
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
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))) {
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.HIDE_LOADING()
if (!success) {
return
}
this.EMIT('EducationalAdministrationJournalSend-list-change')
this.NAV_BACK()
this.TOAST('提交保存成功')
})
this.NAV_BACK()
this.TOAST('提交保存成功')
})
break
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>

+ 1
- 4
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/Thermography/measure/list.vue Прегледај датотеку

@@ -508,6 +508,7 @@ export default{
text-align: center;
font-size: 14px;
color: #1a1a1a;
background-color: #ffffff;
}

.timeTableAlertLi.active {
@@ -518,10 +519,6 @@ export default{
background-color: #fbfdff;
}

.timeTableAlertLi:nth-child(2n - 1) {
background-color: #ffffff;
}

#MeasureTime {
text-align: center;
}


+ 1
- 1
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/login.vue Прегледај датотеку

@@ -273,7 +273,7 @@ page {
.otherLogin{
display: flex;
justify-content: right;
justify-content: flex-end;
.textBtn{
width: 100px;
color: #606266;


+ 1
- 1
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/msg.vue Прегледај датотеку

@@ -132,7 +132,7 @@ export default {
return null
}

return this.API + `/user/img?data=${item.F_OtherUserId}`
return this.API + `/learun/adms/user/img?data=${item.F_OtherUserId}`
}
},



+ 1
- 1
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/msg/chat.vue Прегледај датотеку

@@ -186,7 +186,7 @@ export default {

// 获取用户头像图片 url
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}`
}
},



+ 1
- 1
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/my.vue Прегледај датотеку

@@ -156,7 +156,7 @@ export default {
return ''
}

return this.API + `/user/img?data=${this.currentUser.userId}`
return this.API + `/learun/adms/user/img?data=${this.currentUser.userId}`
}
},



+ 1
- 1
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/my/info.vue Прегледај датотеку

@@ -34,7 +34,7 @@ export default {
// 头像图片 url
avatarSrc() {
return this.API + `/user/img?data=${this.currentUser.userId}`
return this.API + `/learun/adms/user/img?data=${this.currentUser.userId}`
}
}
}


+ 1
- 1
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/my/qrcode.vue Прегледај датотеку

@@ -30,7 +30,7 @@ export default {

// 头像图片 url
avatar() {
return this.API + `/user/img?data=${this.currentUser.userId}`
return this.API + `/learun/adms/user/img?data=${this.currentUser.userId}`
},

// 用户公司部门 tag


+ 1
- 1
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/myAttendance/single.vue Прегледај датотеку

@@ -38,7 +38,7 @@
<view class="tSec2Con2">
<view class="studCheckList">
<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>
{{ k.Sort }}
</view>


+ 6
- 8
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/nworkflow/myflow/single.vue Прегледај датотеку

@@ -95,14 +95,15 @@ export default {
// t.formId 使用表单,根据这个 formId 来获取 scheme 等信息
// t.appurl 使用移动页面,直接跳转到本地的页面;表单结构等均写死在页面里
const { wfForms } = this.currentNode
console.log(wfForms);

// 处理没有有效表单的情况,停止加载
if (!wfForms || wfForms.every(t => !t.formId && !t.appurl)) {
this.HIDE_LOADING()
this.TOAST('移动表单数据(wfForms)中无有效表单')
return
}
const fetchFolderkeyData=await this.fetchFolderkeyData(this.currentNode , this.processId);
uni.setStorageSync('guids',JSON.stringify(fetchFolderkeyData));

// 处理移动端本地表单(也就是系统表单)的情况,直接跳转过去
const appSysPage = wfForms.find(t => t.appurl)
@@ -151,8 +152,6 @@ export default {
// 不是子流程,可以直接渲染
const schemeData = await this.fetchSchemeData(this.currentNode)
const formData = await this.fetchFormData(this.currentNode, this.processId)
console.log(schemeData)
console.log(formData)
const { formValue, scheme, rel } = await this.getCustomForm({
formData,
schemeData,
@@ -161,7 +160,6 @@ export default {
code: null
})
this.scheme = scheme
console.log(scheme)
this.formValue = formValue
this.rel = rel
}
@@ -201,7 +199,7 @@ export default {
return
}
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()
if (success) {
this.EMIT('task-list-change')
@@ -220,7 +218,7 @@ export default {
this.LOADING('正在提交…')
const draftFormValue = this.$refs.form.getFormValue()
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()
if (success) {
this.EMIT('task-list-change')
@@ -249,7 +247,7 @@ export default {
postData.parentTaskId = this.taskId
}
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()
if (success) {
this.EMIT('task-list-change')


+ 9
- 3
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/nworkflow/releasetask/single.vue Прегледај датотеку

@@ -110,7 +110,10 @@ export default {

this.needTitle = this.type !== 'again' && Number(currentNode.isTitle) === 1
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({
schemeData,
processId,
@@ -119,14 +122,15 @@ export default {
code: this.type === 'again' ? null : code,
useDefault: true
})
this.rel = rel
this.scheme = scheme
this.formValue = formValue
this.code = code
this.processId = processId

this.ready = true
this.HIDE_LOADING()
},

// 提交草稿按钮
@@ -153,9 +157,10 @@ export default {
// 发起流程按钮
async submit() {
const isAgain = this.type === 'again'
// 先验证表单,验证不通过则提示
const verifyResult = this.verifyValue()
if (verifyResult.length > 0) {
this.CONFIRM('表单验证失败', verifyResult.join('\n'))
return
@@ -191,6 +196,7 @@ export default {

// 获取表单验证结果,是一个包含错误信息的数组,长度为 0 则没有错误
verifyValue() {
const errList = this.$refs.form.verifyValue()
if (this.needTitle && !this.title) {
errList.push(`流程的标题不能为空`)


+ 379
- 294
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/nworkflow/workflow.js Прегледај датотеку

@@ -32,298 +32,383 @@ import customForm from '@/common/customform.js'
* (以上只是简单介绍;实际使用中,如果打开子流程,需要拉取父/子两个流程信息)
*/
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 || {}
},
}
}

+ 4
- 0
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/onlienpay/list.vue Прегледај датотеку

@@ -14,6 +14,7 @@
<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="lookInvoice">查看发票</view>
</view>
</template>

@@ -44,6 +45,9 @@ export default {
this.TOAST('缴费成功');
}
});
},
lookInvoice(){
this.NAV_TO("./payInvioce")
}
},
created() {


+ 63
- 0
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/onlienpay/payInvioce.vue Прегледај датотеку

@@ -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>

+ 47
- 0
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/onlienpay/payqrcode.vue Прегледај датотеку

@@ -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>

+ 4
- 7
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/studentAttendance/single.vue Прегледај датотеку

@@ -36,7 +36,7 @@
<view v-if="weekData.rows.length == 0">暂时没有信息</view>
<view v-if="weekData.rows.length != 0">
<view
:class="timeTableClass(k.Sort)"
:class="[timeTableClass(k.Sort)]"
class="timeTableLi" v-for="(k, i) in weekData.rows"
:key="k.StuNo"
@click="tapTimeTable(i, timeTableClass(k.Sort))"
@@ -46,7 +46,7 @@
</view>
</view>
</view>
<view class="timeTableAlert" :class="flag? 'active' : ''">
<view class="timeTableAlert" :class="[flag? 'active' : '']">
<view class="timeTableAlertTop">
<view class="timeTableAlertT">{{ weekData.rows[ind].StuName }}</view>
<view class="timeTableAlertTxt">学号: {{ weekData.rows[ind].StuNo }} </view>
@@ -55,7 +55,7 @@
<view
v-for="(n, i) in Statue"
:key="i"
:class="n.className == className? 'active ' + n.className : n.className"
:class="[n.className == className? 'active ' + n.className : n.className]"
class="timeTableAlertLi"
@click="tapStatus(i)"
><text></text>{{ n.txt }}</view>
@@ -491,6 +491,7 @@ export default{
text-align: center;
font-size: 14px;
color: #1a1a1a;
background-color: #ffffff;
}

.timeTableAlertLi.active {
@@ -500,8 +501,4 @@ export default{
.timeTableAlertLi:nth-child(2n) {
background-color: #fbfdff;
}

.timeTableAlertLi:nth-child(2n - 1) {
background-color: #ffffff;
}
</style>

+ 0
- 1
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/studentSee/list.vue Прегледај датотеку

@@ -72,7 +72,6 @@ export default {
'加载数据时出错'
).then( res => {
this.HIDE_LOADING()
// console.log(res)
if (res == null || JSON.stringify(res) == '{}') {
_this.flag = false;
return;


+ 2
- 2
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/timeTable/list.vue Прегледај датотеку

@@ -28,10 +28,10 @@
<view class="tSec2Box">
<view class="tSec2Con" v-for="(items, i) in weekArr" :key="items.num" v-show="i == num">
<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>
<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="tSec2ListL">第 {{ k.jc }} 节</view>
<view class="tSec2ListR">


+ 99
- 5
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/weixinLogin.vue Прегледај датотеку

@@ -25,13 +25,13 @@
</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-input>
<l-input v-if="ready" v-model="password" placeholder="请输入身份证后八位" password left>
<l-icon slot="title" type="lock" />
</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">
<navigator url="/pages/login" class="textBtn">常规登陆</text></navigator>
</view>
@@ -68,11 +68,14 @@
</template>

<script>
import moment from 'moment';
export default {
data() {
return {
username: '',
password: '',
code:'',

ready: false,
showApiRootSelector: false,
@@ -84,6 +87,9 @@ export default {
},

async onLoad() {
if(this.getHashSearchParam("code")){
this.code = this.getHashSearchParam("code")
}
await this.init()
},

@@ -101,15 +107,103 @@ export default {
this.username = account.username
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() {
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) {
const newApiRoot = this.apiRootList[newIndex]
this.currentApiRoot = newApiRoot
@@ -272,7 +366,7 @@ page {
.otherLogin{
display: flex;
justify-content: right;
justify-content: flex-end;
.textBtn{
width: 100px;
color: #606266;


+ 1
- 0
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/welcome/list.vue Прегледај датотеку

@@ -170,6 +170,7 @@ export default {
this.HTTP_GET('StuInfoFresh/saveStuInfoFresh', this.queryData).then(res => {
this.HIDE_LOADING();
if (res) {
this.NAV_TO("/pages/my/newpassword")
this.TOAST('保存成功');
}
});


+ 27
- 0
Learun.Framework.Ultimate V7/Quanjiang.DigitalScholl.JobService/Quanjiang.DigitalScholl.JobService.csproj Прегледај датотеку

@@ -20,6 +20,21 @@
<SccProvider>
</SccProvider>
<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 Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>x64</PlatformTarget>
@@ -138,5 +153,17 @@
<Name>Learun.DataBase</Name>
</ProjectReference>
</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" />
</Project>

Loading…
Откажи
Сачувај