完善功能

This commit is contained in:
2025-09-22 14:30:54 +08:00
parent fde5919d99
commit 365cd2397a
31 changed files with 1849 additions and 467 deletions

View File

@@ -0,0 +1,540 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>展板数据配置</title>
<link href="layui/css/layui.css" rel="stylesheet">
<style>
.container {
display: flex;
justify-content: center;
align-items: center;
height: 15vh;
}
</style>
</head>
<body>
<div class="container">
<h2>展板数据配置</h2>
</div>
<form class="layui-form" action="">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">时间</label>
<div class="layui-input-inline">
<input type="text" class="layui-input" id="time" name="time" placeholder="HH:mm:ss" lay-verify="required">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">字体大小</label>
<div class="layui-input-inline">
<input type="number" id="timeSize" name="timeSize" lay-verify="required" placeholder="字体大小" lay-verify="required" autocomplete="off" class="layui-input" min="15" max="60" step="1" lay-affix="number">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">负责人</label>
<div class="layui-input-inline">
<input type="text" class="layui-input" id="charger" name="charger" placeholder="负责人" lay-verify="required">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">字体大小</label>
<div class="layui-input-inline">
<input type="number" name="chargerSize" id="chargerSize" lay-verify="required" placeholder="字体大小" autocomplete="off" class="layui-input" min="15" max="60" step="1" lay-affix="number">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">风险等级</label>
<div class="layui-input-inline">
<input type="text" class="layui-input" id="riskLevel" name="riskLevel" placeholder="风险等级" lay-verify="required">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">字体大小</label>
<div class="layui-input-inline">
<input type="number" name="riskLevelSize" id="riskLevelSize" placeholder="字体大小" autocomplete="off" class="layui-input" min="15" max="60" step="1" lay-affix="number">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">工作内容</label>
<div class="layui-input-inline">
<textarea name="content" id="content" class="layui-textarea"></textarea>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">字体大小</label>
<div class="layui-input-inline">
<input type="number" name="contentSize" id="contentSize" placeholder="字体大小" autocomplete="off" class="layui-input" min="15" max="60" step="1" lay-affix="number">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">危险点</label>
<div class="layui-input-inline">
<textarea name="dangerPoint" id="dangerPoint" class="layui-textarea"></textarea>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">字体大小</label>
<div class="layui-input-inline">
<input type="number" name="dangerPointSize" id="dangerPointSize" placeholder="字体大小" autocomplete="off" class="layui-input" min="15" max="60" step="1" lay-affix="number">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">重点管控措施</label>
<div class="layui-input-inline">
<textarea name="measures" id="measures" class="layui-textarea"></textarea>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">字体大小</label>
<div class="layui-input-inline">
<input type="number" name="measuresSize" id="measuresSize" placeholder="字体大小" autocomplete="off" class="layui-input" min="15" max="60" step="1" lay-affix="number">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">党员1姓名</label>
<div class="layui-input-inline">
<input type="text" class="layui-input" id="cpcMember1Name" name="cpcMember1Name" placeholder="党员1姓名" lay-verify="required">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<div class="layui-upload">
<button type="button" class="layui-btn" id="upload1" style="margin-left:30px">
<i class="layui-icon layui-icon-upload"></i> 党员1上传
</button>
<button type="button" class="layui-btn" id="delete1" style="margin-left:30px">
<i class="layui-icon layui-icon-close"></i> 党员1删除
</button>
</div>
</div>
<div style="width: 132px;margin-left:100px">
<div class="layui-upload-list">
<img class="layui-upload-img" id="image1" style="width: 100%; height: 92px;" />
<div id="upload-text1"></div>
</div>
<!--<div class="layui-progress layui-progress-big" lay-showPercent="yes" lay-filter="filter-progress1">
<div class="layui-progress-bar" lay-percent=""></div>
</div>-->
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">党员2姓名</label>
<div class="layui-input-inline">
<input type="text" class="layui-input" id="cpcMember2Name" name="cpcMember2Name" placeholder="党员2姓名" lay-verify="required">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<div class="layui-upload">
<button type="button" class="layui-btn" id="upload2" style="margin-left:30px">
<i class="layui-icon layui-icon-upload"></i> 党员2上传
</button>
<button type="button" class="layui-btn" id="delete2" style="margin-left:30px">
<i class="layui-icon layui-icon-close"></i> 党员2删除
</button>
</div>
</div>
<div style="width: 132px;margin-left:100px">
<div class="layui-upload-list">
<img class="layui-upload-img" id="image2" style="width: 100%; height: 92px;" />
<div id="upload-text2"></div>
</div>
<!--<div class="layui-progress layui-progress-big" lay-showPercent="yes" lay-filter="filter-progress2">
<div class="layui-progress-bar" lay-percent=""></div>
</div>-->
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">党员3姓名</label>
<div class="layui-input-inline">
<input type="text" class="layui-input" id="cpcMember3Name" name="cpcMember3Name" placeholder="党员3姓名" lay-verify="required">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<div class="layui-upload">
<button type="button" class="layui-btn" id="upload3" style="margin-left:30px">
<i class="layui-icon layui-icon-upload"></i> 党员3上传
</button>
<button type="button" class="layui-btn" id="delete3" style="margin-left:30px">
<i class="layui-icon layui-icon-close"></i> 党员3删除
</button>
</div>
</div>
<div style="width: 132px;margin-left:100px">
<div class="layui-upload-list">
<img class="layui-upload-img" id="image3" style="width: 100%; height: 92px;" />
<div id="upload-text3"></div>
</div>
<!--<div class="layui-progress layui-progress-big" lay-showPercent="yes" lay-filter="filter-progress3">
<div class="layui-progress-bar" lay-percent=""></div>
</div>-->
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">党员4姓名</label>
<div class="layui-input-inline">
<input type="text" class="layui-input" id="cpcMember4Name" name="cpcMember4Name" placeholder="党员4姓名" lay-verify="required">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<div class="layui-upload">
<button type="button" class="layui-btn" id="upload4" style="margin-left:30px">
<i class="layui-icon layui-icon-upload"></i> 党员4上传
</button>
<button type="button" class="layui-btn" id="delete4" style="margin-left:30px">
<i class="layui-icon layui-icon-close"></i> 党员4删除
</button>
</div>
</div>
<div style="width: 132px;margin-left:100px">
<div class="layui-upload-list">
<img class="layui-upload-img" id="image4" style="width: 100%; height: 92px;" />
<div id="upload-text4"></div>
</div>
<!--<div class="layui-progress layui-progress-big" lay-showPercent="yes" lay-filter="filter-progress4">
<div class="layui-progress-bar" lay-percent=""></div>
</div>-->
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">字体大小</label>
<div class="layui-input-inline">
<input type="number" name="cpcMemberSize" id="cpcMemberSize" placeholder="字体大小" autocomplete="off" class="layui-input" min="15" max="60" step="1" lay-affix="number">
</div>
</div>
</div>
<div style="margin-left:100px">
<button type="button" id="saveconfig" class="layui-btn" style="margin-left:30px">
<i class="layui-icon layui-icon-set-fill"></i> 保存配置
</button>
</div>
</form>
<!-- 请勿在项目正式环境中引用该 layui.js 地址 -->
<script src="layui/layui.js"></script>
<script src="jquery/jquery-1.9.1.min.js"></script>
<script>
layui.use(['form', 'laydate', 'util'], function () {
var form = layui.form;
var layer = layui.layer;
var laydate = layui.laydate;
var upload = layui.upload;
var util = layui.util;
// 时间选择器
laydate.render({
elem: '#time',
type: 'time'
});
// 单图片上传
var uploadInst1 = upload.render({
elem: '#upload1',
url: '/uploadImage', // 实际使用时改成您自己的上传接口即可。
before: function (obj) {
// 预读本地文件示例不支持ie8
//obj.preview(function (index, file, result) {
// $('#image1').attr('src', result); // 图片链接base64
//});
//element.progress('filter-progress1', '0%'); // 进度条复位
//layer.msg('上传中', { icon: 16, time: 0 });
},
done: function (res) {
// 若上传失败
if (res.state != 1) {
layer.msg('上传失败', { icon: 2 });
return;
}
// 上传成功的一些操作
$('#image1').attr('src', res.data); // 置空上传失败的状态
$('#upload-text1').html(''); // 置空上传失败的状态
layer.msg('上传成功', { icon: 1 });
},
error: function () {
var demoText = $('#upload-text1');
demoText.html('<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-xs" id="reload1">重试</a>');
demoText.find('#reload1').on('click', function () {
uploadInst.upload();
});
},
// 进度条
//progress: function (n, elem, e) {
// element.progress('filter-progress1', n + '%'); // 可配合 layui 进度条元素使用
// if (n == 100) {
// layer.msg('上传完毕', { icon: 1 });
// }
//}
});
var uploadInst2 = upload.render({
elem: '#upload2',
url: '/uploadImage', // 实际使用时改成您自己的上传接口即可。
before: function (obj) {
// 预读本地文件示例不支持ie8
//obj.preview(function (index, file, result) {
// $('#image2').attr('src', result); // 图片链接base64
//});
//element.progress('filter-progress2', '0%'); // 进度条复位
//layer.msg('上传中', { icon: 16, time: 0 });
},
done: function (res) {
// 若上传失败
if (res.state != 1) {
layer.msg('上传失败', { icon: 2 });
return;
}
// 上传成功的一些操作
$('#image2').attr('src', res.data); // 置空上传失败的状态
$('#upload-text2').html(''); // 置空上传失败的状态
layer.msg('上传成功', { icon: 1 });
},
error: function () {
// 演示失败状态,并实现重传
var demoText = $('#upload-text2');
demoText.html('<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-xs" id="reload2">重试</a>');
demoText.find('#reload2').on('click', function () {
uploadInst.upload();
});
},
// 进度条
//progress: function (n, elem, e) {
// element.progress('filter-progress2', n + '%'); // 可配合 layui 进度条元素使用
// if (n == 100) {
// layer.msg('上传完毕', { icon: 1 });
// }
//}
});
var uploadInst3 = upload.render({
elem: '#upload3',
url: '/uploadImage', // 实际使用时改成您自己的上传接口即可。
before: function (obj) {
// 预读本地文件示例不支持ie8
//obj.preview(function (index, file, result) {
// $('#image3').attr('src', result); // 图片链接base64
//});
//element.progress('filter-progress3', '0%'); // 进度条复位
//layer.msg('上传中', { icon: 16, time: 0 });
},
done: function (res) {
// 若上传失败
if (res.state != 1) {
layer.msg('上传失败', { icon: 2 });
return;
}
// 上传成功的一些操作
$('#image3').attr('src', res.data); // 置空上传失败的状态
$('#upload-text3').html(''); // 置空上传失败的状态
layer.msg('上传成功', { icon: 1 });
},
error: function () {
// 演示失败状态,并实现重传
var demoText = $('#upload-text3');
demoText.html('<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-xs" id="reload3">重试</a>');
demoText.find('#reload3').on('click', function () {
uploadInst.upload();
});
},
// 进度条
//progress: function (n, elem, e) {
// element.progress('filter-progress3', n + '%'); // 可配合 layui 进度条元素使用
// if (n == 100) {
// layer.msg('上传完毕', { icon: 1 });
// }
//}
});
var uploadInst4 = upload.render({
elem: '#upload4',
url: '/uploadImage', // 实际使用时改成您自己的上传接口即可。
before: function (obj) {
// 预读本地文件示例不支持ie8
//obj.preview(function (index, file, result) {
// $('#image4').attr('src', result); // 图片链接base64
//});
//element.progress('filter-progress4', '0%'); // 进度条复位
//layer.msg('上传中', { icon: 16, time: 0 });
},
done: function (res) {
// 若上传失败
if (res.state != 1) {
layer.msg('上传失败', { icon: 2 });
return;
}
// 上传成功的一些操作
$('#image4').attr('src', res.data); // 置空上传失败的状态
$('#upload-text4').html(''); // 置空上传失败的状态
layer.msg('上传成功', { icon: 1 });
},
error: function () {
// 演示失败状态,并实现重传
var demoText = $('#upload-text4');
demoText.html('<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-xs" id="reload4">重试</a>');
demoText.find('#reload4').on('click', function () {
uploadInst.upload();
});
},
// 进度条
//progress: function (n, elem, e) {
// element.progress('filter-progress4', n + '%'); // 可配合 layui 进度条元素使用
// if (n == 100) {
// layer.msg('上传完毕', { icon: 1 });
// }
//}
});
init();
$("#delete1").click(function () {
$("#image1").attr("src", "");
});
$("#delete2").click(function () {
$("#image2").attr("src", "");
});
$("#delete3").click(function () {
$("#image3").attr("src", "");
});
$("#delete4").click(function () {
$("#image4").attr("src", "");
});
$("#saveconfig").click(function () {
save();
});
});
function init() {
$.ajax({
url: '/getConfig',
method: 'GET',
dataType: 'json',
success: function (response) {
// 成功处理响应数据
$("#time").val(response.Time);
$("#timeSize").val(response.TimeSize);
$("#charger").val(response.Charger);
$("#chargerSize").val(response.ChargerSize);
$("#riskLevel").val(response.RiskLevel);
$("#riskLevelSize").val(response.RiskLevelSize);
$("#content").text(response.Content);
$("#contentSize").val(response.ContentSize);
$("#dangerPoint").text(response.DangerPoint);
$("#dangerPointSize").val(response.DangerPointSize);
$("#measures").text(response.Measures);
$("#measuresSize").val(response.MeasuresSize);
$("#cpcMember1Name").val(response.CPCMember1Name);
$("#cpcMember2Name").val(response.CPCMember2Name);
$("#cpcMember3Name").val(response.CPCMember3Name);
$("#cpcMember4Name").val(response.CPCMember4Name);
$("#image1").attr("src", response.CPCMember1Path);
$("#image2").attr("src", response.CPCMember2Path);
$("#image3").attr("src", response.CPCMember3Path);
$("#image4").attr("src", response.CPCMember4Path);
$("#cpcMemberSize").val(response.CPCMemberSize);
},
error: function (xhr, status, error) {
// 处理错误
//layer.msg('');
}
});
}
function save() {
var json = {
Time: $("#time").val(),
TimeSize: $("#timeSize").val(),
Charger: $("#charger").val(),
ChargerSize: $("#chargerSize").val(),
RiskLevel: $("#riskLevel").val(),
RiskLevelSize: $("#riskLevelSize").val(),
Content: $("#content").text(),
ContentSize: $("#contentSize").val(),
DangerPoint: $("#dangerPoint").text(),
DangerPointSize: $("#dangerPointSize").val(),
Measures: $("#measures").text(),
MeasuresSize: $("#measuresSize").val(),
CPCMember1Name: $("#cpcMember1Name").val(),
CPCMember2Name: $("#cpcMember2Name").val(),
CPCMember3Name: $("#cpcMember3Name").val(),
CPCMember4Name: $("#cpcMember4Name").val(),
CPCMember1Path: $("#image1").attr("src"),
CPCMember2Path: $("#image2").attr("src"),
CPCMember3Path: $("#image3").attr("src"),
CPCMember4Path: $("#image4").attr("src"),
CPCMemberSize: $("#cpcMemberSize").val(),
};
$.ajax({
url: '/save',
method: 'POST',
dataType: 'json',
data: json,
success: function (response) {
if (response.state == 1) {
layer.msg('保存成功', { icon: 1 });
} else {
layer.msg('保存失败', { icon: 2 });
}
},
error: function (xhr, status, error) {
layer.msg('保存失败', { icon: 2 });
}
});
}
</script>
</body>
</html>

View File

@@ -1,229 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Quick Start - Layui</title>
<link href="layui/css/layui.css" rel="stylesheet">
<style>
.container {
display: flex;
justify-content: center;
align-items: center;
height: 15vh;
}
</style>
</head>
<body>
<div class="container">
<h2>展板数据配置</h2>
</div>
<form class="layui-form" action="">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">时间</label>
<div class="layui-input-inline">
<input type="text" class="layui-input" id="ID-laydate-type-time" placeholder="HH:mm:ss" lay-verify="required">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">字体大小</label>
<div class="layui-input-inline">
<input type="number" name="price_min" lay-verify="required" placeholder="字体大小" lay-verify="required" autocomplete="off" class="layui-input" min="15" max="60" step="1" lay-affix="number">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">负责人</label>
<div class="layui-input-inline">
<input type="text" class="layui-input" placeholder="负责人" lay-verify="required">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">字体大小</label>
<div class="layui-input-inline">
<input type="number" name="price_min" lay-verify="required" placeholder="字体大小" autocomplete="off" class="layui-input" min="15" max="60" step="1" lay-affix="number">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">风险等级</label>
<div class="layui-input-inline">
<input type="text" class="layui-input" placeholder="风险等级" lay-verify="required">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">字体大小</label>
<div class="layui-input-inline">
<input type="number" name="price_min" placeholder="字体大小" autocomplete="off" class="layui-input" min="15" max="60" step="1" lay-affix="number">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">工作内容</label>
<div class="layui-input-inline">
<textarea name="message" class="layui-textarea"></textarea>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">字体大小</label>
<div class="layui-input-inline">
<input type="number" name="price_min" placeholder="字体大小" autocomplete="off" class="layui-input" min="15" max="60" step="1" lay-affix="number">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">危险点</label>
<div class="layui-input-inline">
<textarea name="message" class="layui-textarea"></textarea>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">字体大小</label>
<div class="layui-input-inline">
<input type="number" name="price_min" placeholder="字体大小" autocomplete="off" class="layui-input" min="15" max="60" step="1" lay-affix="number">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">重点管控措施</label>
<div class="layui-input-inline">
<textarea name="message" class="layui-textarea"></textarea>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">字体大小</label>
<div class="layui-input-inline">
<input type="number" name="price_min" placeholder="字体大小" autocomplete="off" class="layui-input" min="15" max="60" step="1" lay-affix="number">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<div class="layui-upload">
<button type="button" class="layui-btn" id="ID-upload-demo-btn-2" style="margin-left:30px">
<i class="layui-icon layui-icon-upload"></i> 党员上传
</button>
</div>
</div>
<blockquote class="layui-elem-quote layui-quote-nm" style="margin-top: 11px;">
预览图:
<div class="layui-upload-list" id="upload-demo-preview"></div>
</blockquote>
</div>
</form>
<!-- 请勿在项目正式环境中引用该 layui.js 地址 -->
<script src="layui/layui.js"></script>
<script>
layui.use(['form', 'laydate', 'util'], function () {
var form = layui.form;
var layer = layui.layer;
var laydate = layui.laydate;
var upload = layui.upload;
var util = layui.util;
// 多图片上传
upload.render({
elem: '#ID-upload-demo-btn-2',
url: '', // 实际使用时改成您自己的上传接口即可。
multiple: true,
before: function (obj) {
// 预读本地文件示例不支持ie8
obj.preview(function (index, file, result) {
$('#upload-demo-preview').append('<img src="' + result + '" alt="' + file.name + '" style="width: 90px; height: 90px;">')
});
},
done: function (res) {
// 上传完毕
// …
}
});
// 时间选择器
laydate.render({
elem: '#ID-laydate-type-time',
type: 'time'
});
// 自定义验证规则
form.verify({
pass: function (value) {
if (!/(.+){6,12}$/.test(value)) {
return '密码必须 6 到 12 位';
}
}
});
// 指定开关事件
form.on('switch(switchTest)', function (data) {
layer.msg('开关 checked' + (this.checked ? 'true' : 'false'), {
offset: '6px'
});
layer.tips('温馨提示:请注意开关状态的文字可以随意定义,而不仅仅是 ON|OFF', data.othis)
});
// 提交事件
form.on('submit(demo1)', function (data) {
var field = data.field; // 获取表单字段值
// 显示填写结果,仅作演示用
layer.alert(JSON.stringify(field), {
title: '当前填写的字段值'
});
// 此处可执行 Ajax 等操作
// …
return false; // 阻止默认 form 跳转
});
// 日期
laydate.render({
elem: '#date'
});
// 普通事件
util.on('lay-on', {
// 获取验证码
"get-vercode": function (othis) {
var isvalid = form.validate('.demo-phone'); // 主动触发验证v2.7.0 新增
// 验证通过
if (isvalid) {
layer.msg('手机号规则验证通过');
// 此处可继续书写「发送验证码」等后续逻辑
// …
}
}
});
});
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,57 @@
using System;
using System.Windows.Input;
namespace .Base
{
public class DelegateCommand : ICommand
{
public Action<object> ExecuteCommand = null;
public event EventHandler CanExecuteChanged;
public DelegateCommand(DelegateCommand focusAdjustToCommand)
{
}
public DelegateCommand(Action<object> Command)
{
ExecuteCommand = Command;
}
public bool CanExecute(object paramter)
{
return true;
}
public void Execute(object paramter)
{
ExecuteCommand?.Invoke(paramter);
}
}
public class DelegateCommand<T> : ICommand
{
public Action<T> ExecuteCommand = null;
public event EventHandler CanExecuteChanged;
public DelegateCommand()
{
}
public DelegateCommand(Action<T> Command)
{
ExecuteCommand = Command;
}
public bool CanExecute(object paramter)
{
return true;
}
public void Execute(object paramter)
{
ExecuteCommand?.Invoke((T)paramter);
}
}
}

View File

@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using .Utility.Core;
using .Utility.Extension;
namespace .Base
{
public class GlobalVariable
{
private static MyConfig _config;
/// <summary>
/// 配置数据
/// </summary>
public static MyConfig Config
{
get
{
if (_config == null)
_config = File.ReadAllText(MyEnvironment.Root("/Configs/Config.json")).ToObject<MyConfig>();
return _config;
}
set
{
_config = value;
}
}
public static void SaveConfig()
{
File.WriteAllText(MyEnvironment.Root("/Configs/Config.json"), Config.ToJson());
}
}
}

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Dynamic;
using System.Runtime.CompilerServices;
using System.Xml.Serialization;
namespace .Base
{
public class ModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([CallerMemberName] string propertyname = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
}
}

View File

@@ -0,0 +1,150 @@
using System;
using System.Linq;
using System.Text;
namespace .Base
{
/// <summary>
/// 配置类
/// </summary>
public class MyConfig : ModelBase
{
/// <summary>
/// 时间
/// </summary>
[Comment("时间")]
public string Time { get; set; }
/// <summary>
/// 时间字体大小
/// </summary>
[Comment("时间字体大小")]
public int TimeSize { get; set; }
/// <summary>
/// 负责人
/// </summary>
[Comment("负责人")]
public string Charger { get; set; }
/// <summary>
/// 负责人字体大小
/// </summary>
[Comment("负责人字体大小")]
public int ChargerSize { get; set; }
/// <summary>
/// 风险等级
/// </summary>
[Comment("风险等级")]
public string RiskLevel { get; set; }
/// <summary>
/// 风险等级字体大小
/// </summary>
[Comment("风险等级字体大小")]
public int RiskLevelSize { get; set; }
/// <summary>
/// 工作内容
/// </summary>
[Comment("工作内容")]
public string Content { get; set; }
/// <summary>
/// 工作内容字体大小
/// </summary>
[Comment("工作内容字体大小")]
public int ContentSize { get; set; }
/// <summary>
/// 危险点
/// </summary>
[Comment("危险点")]
public string DangerPoint { get; set; }
/// <summary>
/// 危险点
/// </summary>
[Comment("危险点字体大小")]
public int DangerPointSize { get; set; }
/// <summary>
/// 重点措施
/// </summary>
[Comment("重点措施")]
public string Measures { get; set; }
[Comment("重点措施字体大小")]
public int MeasuresSize { get; set; }
[Comment("党员1图片路径")]
public string CPCMember1Path { get; set; }
[Comment("党员1姓名")]
public string CPCMember1Name { get; set; }
[Comment("党员2图片路径")]
public string CPCMember2Path { get; set; }
[Comment("党员2姓名")]
public string CPCMember2Name { get; set; }
[Comment("党员3图片路径")]
public string CPCMember3Path { get; set; }
[Comment("党员3姓名")]
public string CPCMember3Name { get; set; }
[Comment("党员4图片路径")]
public string CPCMember4Path { get; set; }
[Comment("党员4姓名")]
public string CPCMember4Name { get; set; }
[Comment("党员字体大小")]
public int CPCMemberSize { get; set;}
/// <summary>
/// 转换成JSON字符串
/// </summary>
/// <returns></returns>
public string ToJson()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("{");
//得到所有的Property
var properties = GetType().GetProperties();
for (int i = 0; i < properties.Length; i++)
{
var property = properties[i];
string endChar = ",";
if (i == properties.Length - 1)
{
endChar = "";
}
var comment = property.GetCustomAttributes(typeof(CommentAttribute), false).FirstOrDefault() as CommentAttribute;
string commentText = "";
if (comment != null)
{
commentText = $" /* {comment.Comment} */";
}
string propertyName = property.Name;
var value = property.GetValue(this, null);
if (value != null)
{
var valueType = value.GetType();
if (valueType == typeof(string))
{
sb.AppendLine($" \"{propertyName}\":\"{value}\"{endChar}{commentText}");
}
else
{
sb.AppendLine($" \"{propertyName}\":{value}{endChar}{commentText}");
}
}
}
sb.AppendLine("}");
return sb.ToString();
}
}
public class CommentAttribute : Attribute
{
public string Comment { get; set; }
public CommentAttribute(string comment)
{
Comment = comment;
}
}
}

View File

@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace .Base
{
public class ViewModelBase : ModelBase
{
public MyConfig Config => GlobalVariable.Config;
public static object _lock = new object();
//获取PLC变量值
//public object GetPlcValue(string plcVariableName, bool isLog = true)
//{
// lock (_lock)
// {
// try
// {
// return adsServer.GetValue(plcVariableName);
// }
// catch
// {
// if (string.IsNullOrEmpty(plcVariableName))
// LogErr($"Error in GetPLCVar() Plc variable is null or empty.");
// else
// LogErr($"Error in GetPLCVar(), PLC variable '{plcVariableName}'");
// }
// return "0";
// }
//}
//public T GetPlcValue<T>(string plcVariableName)
//{
// lock (_lock)
// {
// try
// {
// object value = adsServer.GetValue(plcVariableName);
// return (T)Convert.ChangeType(value, typeof(T));
// }
// catch
// {
// if (string.IsNullOrEmpty(plcVariableName))
// LogErr($"Error in GetPLCVar() Plc variable is null or empty.");
// else
// LogErr($"Error in GetPLCVar(), PLC variable '{plcVariableName}'");
// return default(T);
// }
// }
//}
//设置PLC变量值
//public bool SetPlcValue(string plcVariableName, object plcValue, bool isLog = true)
//{
// lock (_lock)
// {
// bool res = false;
// try
// {
// res = adsServer.SetValue(plcVariableName, plcValue);
// }
// catch
// {
// if (string.IsNullOrEmpty(plcVariableName))
// LogErr($"Error in SetPLCVar() Plc variable is null or empty.");
// else
// LogErr($"Error in SetPLCVar(), PLC variable '{plcVariableName}'");
// }
// return res;
// }
//}
}
}

View File

@@ -1 +1,23 @@

{
"Time": "10:00:00",
"TimeSize": 44,
"Charger": "刘华强",
"ChargerSize": 44,
"RiskLevel": "高",
"RiskLevelSize": 44,
"Content": "1、 负责组织项目开工前的准备工作,按照施工图总平面布置确定所建建筑物位置,复合定位、标高。安排临时道路铺设工作。参与工程技术管理,配合总工程师编制项目部施工生产计划。\r\n2、认真会审施工图纸掌握设计意图严格按图施工。在实际施工中发现设计图纸不能满足实用要求时要及时向领导报告按规定办理设计变更手续",
"ContentSize": 44,
"DangerPoint": "高空作业的安全风险\r\n化学品使用风险",
"DangerPointSize": 44,
"Measures": "1.佩戴个人防护装备:所有高空作业人员必须佩戴符合国家标准的安全帽、安全带、防滑鞋等个人防护装备,并定期检查这些设备的完好性。\r\n2.设置安全设施:在可能坠落的高度处安装安全网、护栏和踢脚板,以防止施工人员意外跌落,并避免小物件掉落伤人。\r\n3.进行安全技术交底:在施工前,必须进行针对性的书面安全交底,确保所有参与人员了解安全技术措施和个人防护要求。",
"MeasuresSize": 44,
"CPCMember1Path": "/Upload/0.jpg",
"CPCMember1Name": "张三",
"CPCMember2Path": "/Upload/0.jpg",
"CPCMember2Name": "李四",
"CPCMember3Path": "/Upload/0.jpg",
"CPCMember3Name": "王五",
"CPCMember4Path": "/Upload/0.jpg",
"CPCMember4Name": "赵六",
"CPCMemberSize": 44
}

View File

@@ -1,17 +1,23 @@
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Web.Http;
using .Base;
using .Utility;
using .Utility.Core;
using .Utility.Extension;
using .Utility.Logs;
using .Utility.Other;
using .Utility.Web;
namespace .Controller
{
public class IndexController : BaseController
{
//[HttpGet, Route("index/error")]
//public ActionResult Error()
//{
// return Html("/Sys/Index/Error");
//}
/// <summary>
/// 后台首页视图。
/// </summary>
@@ -19,7 +25,66 @@ namespace 电子展板.Controller
[HttpGet, Route("")]
public ActionResult Index()
{
return Resouce("/Views/Login.html", "text/html");
return Resouce("/Views/Index.html", "text/html");
}
[HttpGet, Route("getConfig")]
public ActionResult GetConfig()
{
return Json(GlobalVariable.Config);
}
/// <summary>
/// 上传头像。
/// </summary>
/// <returns></returns>
[HttpPost, Route("uploadImage")]
public ActionResult UploadImage()
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string path = MyEnvironment.Root("/Upload");
var provider = new WithExtensionMultipartFormDataStreamProvider(path, UUID.StrSnowId);
var fileData = Request.Content.ReadAsMultipartAsync(provider).Result;
if (fileData.FileData.Count == 0)
{
return Error();
}
var file = fileData.FileData[0];
string virtualPath = "/Upload/" + Path.GetFileName(file.LocalFileName);
return Success("上传成功", virtualPath);
}
[HttpGet, Route("Upload/{id}")]
public ActionResult GetUploadFile([FromUri] string id)
{
string filePath = MyEnvironment.Root($"/Upload/{id}");
string contentType = System.Web.MimeMapping.GetMimeMapping(filePath);
return PhysicalFile(filePath, contentType, id);
}
[HttpPost, Route("save")]
public ActionResult Save([FromBody] MyConfig config)
{
LogHelper.Instance.Info($"用户保存了配置:{JsonHelper.ToJson(config)}");
//保存
PropertyInfo[] propertyInfos = typeof(MyConfig).GetProperties();
foreach (PropertyInfo propertyInfo in propertyInfos)
{
object value = propertyInfo.GetValue(config);
propertyInfo.SetValue(GlobalVariable.Config, value);
}
GlobalVariable.SaveConfig();
EventBus.Instance.Publish("save", "");
return Success();
}
}
}

View File

@@ -50,5 +50,13 @@ namespace 电子展板.Controller
return Resouce("/layui/layui.js", "application/javascript");
}
#endregion
[HttpGet, Route("jquery/jquery-1.9.1.min.js")]
public ActionResult jquery_1_9_1_min()
{
return Resouce("/jquery/jquery-1.9.1.min.js", "application/javascript");
}
}
}

View File

@@ -1,4 +1,4 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<PropertyChanged />
<Costura />
<!--<Costura />-->
</Weavers>

View File

@@ -53,157 +53,6 @@
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="Costura" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="IncludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeRuntimeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="IncludeRuntimeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged32Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>Obsolete, use UnmanagedWinX86Assemblies instead</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="UnmanagedWinX86Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged X86 (32 bit) assembly names to include, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged64Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>Obsolete, use UnmanagedWinX64Assemblies instead.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="UnmanagedWinX64Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged X64 (64 bit) assembly names to include, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="UnmanagedWinArm64Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged Arm64 (64 bit) assembly names to include, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="PreloadOrder" type="xs:string">
<xs:annotation>
<xs:documentation>The order of preloaded assemblies, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:all>
<xs:attribute name="CreateTemporaryAssemblies" type="xs:boolean">
<xs:annotation>
<xs:documentation>This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeDebugSymbols" type="xs:boolean">
<xs:annotation>
<xs:documentation>Controls if .pdbs for reference assemblies are also embedded.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeRuntimeReferences" type="xs:boolean">
<xs:annotation>
<xs:documentation>Controls if runtime assemblies are also embedded.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="UseRuntimeReferencePaths" type="xs:boolean">
<xs:annotation>
<xs:documentation>Controls whether the runtime assemblies are embedded with their full path or only with their assembly name.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="DisableCompression" type="xs:boolean">
<xs:annotation>
<xs:documentation>Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="DisableCleanup" type="xs:boolean">
<xs:annotation>
<xs:documentation>As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="DisableEventSubscription" type="xs:boolean">
<xs:annotation>
<xs:documentation>The attach method no longer subscribes to the `AppDomain.AssemblyResolve` (.NET 4.x) and `AssemblyLoadContext.Resolving` (.NET 6.0+) events.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="LoadAtModuleInit" type="xs:boolean">
<xs:annotation>
<xs:documentation>Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IgnoreSatelliteAssemblies" type="xs:boolean">
<xs:annotation>
<xs:documentation>Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="ExcludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="ExcludeRuntimeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeRuntimeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="Unmanaged32Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>Obsolete, use UnmanagedWinX86Assemblies instead</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="UnmanagedWinX86Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged X86 (32 bit) assembly names to include, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="Unmanaged64Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>Obsolete, use UnmanagedWinX64Assemblies instead</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="UnmanagedWinX64Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged X64 (64 bit) assembly names to include, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="UnmanagedWinArm64Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged Arm64 (64 bit) assembly names to include, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="PreloadOrder" type="xs:string">
<xs:annotation>
<xs:documentation>The order of preloaded assemblies, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>

View File

@@ -1,15 +1,28 @@
<Window xmlns:hc="https://handyorg.github.io/handycontrol" x:Class="电子展板.MainWindow"
<Window xmlns:hc="https://handyorg.github.io/handycontrol"
x:Class="电子展板.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:电子展板"
xmlns:vm="clr-namespace:电子展板.ViewModels"
ResizeMode="NoResize"
WindowStyle="None"
mc:Ignorable="d"
Closing="Window_Closing"
Loaded="Window_Loaded"
x:Name="window"
Title="MainWindow" Background="#E5E5E5">
<Window.DataContext>
<vm:MainWindowViewModel/>
</Window.DataContext>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding LoadedCommand}" CommandParameter="{Binding ElementName=window}"/>
</i:EventTrigger>
<i:EventTrigger EventName="Closing">
<i:InvokeCommandAction Command="{Binding WindowClosingCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid>
<Viewbox Stretch="Uniform" >
<Canvas Width="1920" Height="1080">
@@ -39,7 +52,7 @@
</Grid.ColumnDefinitions>
<TextBlock Text="时间:" Grid.Column="0" FontSize="60" Foreground="#1F7572" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,0,0"/>
<Border Grid.Column="1" Background="#C0E3D9" CornerRadius="20" Height="140">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="55" Foreground="Black" TextWrapping="Wrap" Text="10:00:00"/>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="{Binding Config.TimeSize}" Foreground="Black" TextWrapping="Wrap" Text="{Binding Config.Time}"/>
</Border>
</Grid>
</Grid>
@@ -51,7 +64,7 @@
</Grid.ColumnDefinitions>
<TextBlock Text="负责人:" Grid.Column="0" FontSize="60" Foreground="#1F7572" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,0,0"/>
<Border Grid.Column="1" Background="#C0E3D9" CornerRadius="20" Height="140">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="55" Foreground="Black" TextWrapping="Wrap" Text="刘华强"/>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="{Binding Config.ChargerSize}" Foreground="Black" TextWrapping="Wrap" Text="{Binding Config.Charger}"/>
</Border>
</Grid>
</Grid>
@@ -63,13 +76,13 @@
</Grid.ColumnDefinitions>
<TextBlock Text="风险等级:" Grid.Column="0" FontSize="60" Foreground="#1F7572" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,0,0"/>
<Border Grid.Column="1" Background="#C0E3D9" CornerRadius="20" Height="140">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="55" Foreground="Black" TextWrapping="Wrap" Text="A"/>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="{Binding Config.RiskLevelSize}" Foreground="Black" TextWrapping="Wrap" Text="{Binding Config.RiskLevel}"/>
</Border>
</Grid>
</Grid>
<TextBlock Grid.Row="1" Grid.Column="1" Text="工作内容:" FontSize="60" Foreground="#1F7572" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,0,0"/>
<Border Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="3" Background="#C0E3D9" CornerRadius="20" Margin="0,40,0,40">
<TextBlock HorizontalAlignment="Left" Margin="10" VerticalAlignment="Top" FontSize="55" Foreground="Black" TextWrapping="Wrap" Text="1、 负责组织项目开工前的准备工作,按照施工图总平面布置确定所建建筑物位置,复合定位、标高。安排临时道路铺设工作。参与工程技术管理,配合总工程师编制项目部施工生产计划。&#xA;2、认真会审施工图纸掌握设计意图严格按图施工。在实际施工中发现设计图纸不能满足实用要求时要及时向领导报告按规定办理设计变更手续"/>
<TextBlock HorizontalAlignment="Left" Margin="10" VerticalAlignment="Top" FontSize="{Binding Config.ContentSize}" Foreground="Black" TextWrapping="Wrap" Text="{Binding Config.Content}"/>
</Border>
</Grid>

View File

@@ -22,26 +22,5 @@ namespace 电子展板
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
int screenIndex = 0;
this.Left = (int)(Screen.AllScreens[screenIndex].Bounds.Left / GetDpiScaleX());
this.Top = (int)(Screen.AllScreens[screenIndex].Bounds.Top / GetDpiScaleX());
this.Width = (int)(Screen.AllScreens[screenIndex].Bounds.Width / GetDpiScaleX());
this.Height = (int)(Screen.AllScreens[screenIndex].Bounds.Height / GetDpiScaleX());
WebServer.Start();
}
public double GetDpiScaleX()
{
return VisualTreeHelper.GetDpi(this).DpiScaleX;
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
WebServer.Stop();
Environment.Exit(0);
}
}
}

View File

@@ -3,13 +3,25 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:电子展板"
xmlns:vm="clr-namespace:电子展板.ViewModels"
ResizeMode="NoResize"
Closing="Window_Closing"
WindowStyle="None"
x:Name="window"
mc:Ignorable="d"
Loaded="Window_Loaded"
Title="MainWindow" Background="#E5E5E5">
<Window.DataContext>
<vm:MainWindow2ViewModel/>
</Window.DataContext>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding LoadedCommand}" CommandParameter="{Binding ElementName=window}"/>
</i:EventTrigger>
<i:EventTrigger EventName="Closing">
<i:InvokeCommandAction Command="{Binding WindowClosingCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid>
<Viewbox Stretch="Uniform" >
<Canvas Width="1920" Height="1080">
@@ -31,10 +43,10 @@
<TextBlock Text="党员亮身份" Grid.Row="1" Grid.Column="3" FontSize="60" Foreground="#1F7572" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0,0,0,0"/>
<Border Grid.Row="2" Grid.Column="1" Background="#C0E3D9" CornerRadius="20" Margin="0,20,20,50">
<TextBlock Margin="10" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="55" Foreground="Black" TextWrapping="Wrap" Text="1、 负责组织项目开工前的准备工作,按照施工图总平面布置确定所建建筑物位置,复合定位、标高。安排临时道路铺设工作。参与工程技术管理,配合总工程师编制项目部施工生产计划。"/>
<TextBlock Margin="10" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="{Binding Config.DangerPointSize}" Foreground="Black" TextWrapping="Wrap" Text="{Binding Config.DangerPoint}"/>
</Border>
<Border Grid.Row="2" Grid.Column="2" Background="#C0E3D9" CornerRadius="20" Margin="25,20,20,50">
<TextBlock Margin="10" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="55" Foreground="Black" TextWrapping="Wrap" Text="1、 负责组织项目开工前的准备工作,按照施工图总平面布置确定所建建筑物位置,复合定位、标高。安排临时道路铺设工作。参与工程技术管理,配合总工程师编制项目部施工生产计划。"/>
<TextBlock Margin="10" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="{Binding Config.MeasuresSize}" Foreground="Black" TextWrapping="Wrap" Text="{Binding Config.Measures}"/>
</Border>
<Grid Grid.Row="2" Grid.Column="3" Margin="20,20,0,50">
<Grid.ColumnDefinitions>
@@ -51,8 +63,8 @@
<RowDefinition Height="*"/>
<RowDefinition Height="80"/>
</Grid.RowDefinitions>
<Image Margin="10" Source="/Assets/0.jpg" Stretch="Uniform" />
<TextBlock Text="陈龙" Grid.Row="1" FontSize="40" Foreground="Black" TextWrapping="Wrap" TextAlignment="Center"/>
<Image Margin="10" Source="{Binding Image1}" Stretch="Uniform" />
<TextBlock Text="{Binding Config.CPCMember1Name}" Grid.Row="1" FontSize="{Binding Config.CPCMemberSize}" Foreground="Black" TextWrapping="Wrap" TextAlignment="Center"/>
</Grid>
</Border>
@@ -62,8 +74,8 @@
<RowDefinition Height="*"/>
<RowDefinition Height="80"/>
</Grid.RowDefinitions>
<Image Margin="10" Source="/Assets/0.jpg" Stretch="Uniform" />
<TextBlock Text="陶陶" Grid.Row="1" FontSize="40" Foreground="Black" TextWrapping="Wrap" TextAlignment="Center"/>
<Image Margin="10" Source="{Binding Image2}" Stretch="Uniform" />
<TextBlock Text="{Binding Config.CPCMember2Name}" Grid.Row="1" FontSize="{Binding Config.CPCMemberSize}" Foreground="Black" TextWrapping="Wrap" TextAlignment="Center"/>
</Grid>
</Border>
<Border Grid.Row="1" Grid.Column="0" Background="#C0E3D9" CornerRadius="20" Margin="10,5,5,0">
@@ -72,8 +84,8 @@
<RowDefinition Height="*"/>
<RowDefinition Height="80"/>
</Grid.RowDefinitions>
<Image Margin="10" Source="/Assets/0.jpg" Stretch="Uniform" />
<TextBlock Text="陈龙" Grid.Row="1" FontSize="40" Foreground="Black" TextWrapping="Wrap" TextAlignment="Center"/>
<Image Margin="10" Source="{Binding Image3}" Stretch="Uniform" />
<TextBlock Text="{Binding Config.CPCMember3Name}" Grid.Row="1" FontSize="{Binding Config.CPCMemberSize}" Foreground="Black" TextWrapping="Wrap" TextAlignment="Center"/>
</Grid>
</Border>
<Border Grid.Row="1" Grid.Column="1" Background="#C0E3D9" CornerRadius="20" Margin="5,5,10,0">
@@ -82,8 +94,8 @@
<RowDefinition Height="*"/>
<RowDefinition Height="80"/>
</Grid.RowDefinitions>
<Image Margin="10" Source="/Assets/0.jpg" Stretch="Uniform" />
<TextBlock Text="陶陶" Grid.Row="1" FontSize="40" Foreground="Black" TextWrapping="Wrap" TextAlignment="Center"/>
<Image Margin="10" Source="{Binding Image4}" Stretch="Uniform" />
<TextBlock Text="{Binding Config.CPCMember4Name}" Grid.Row="1" FontSize="{Binding Config.CPCMemberSize}" Foreground="Black" TextWrapping="Wrap" TextAlignment="Center"/>
</Grid>
</Border>

View File

@@ -24,36 +24,5 @@ namespace 电子展板
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Screen[] screens = Screen.AllScreens;
if (screens.Length > 1)
{
int screenIndex = 1;
this.Left = (int)(Screen.AllScreens[screenIndex].Bounds.Left / GetDpiScaleX());
this.Top = (int)(Screen.AllScreens[screenIndex].Bounds.Top / GetDpiScaleX());
this.Width = (int)(Screen.AllScreens[screenIndex].Bounds.Width / GetDpiScaleX());
this.Height = (int)(Screen.AllScreens[screenIndex].Bounds.Height / GetDpiScaleX());
}
else
{
this.Close();
}
}
public double GetDpiScaleX()
{
return VisualTreeHelper.GetDpi(this).DpiScaleX;
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
WebServer.Stop();
Screen[] screens = Screen.AllScreens;
if (screens.Length > 1)
{
Environment.Exit(0);
}
}
}
}

BIN
电子展板/Upload/0.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace .Utility
{
public class ContentTypeUtils
{
public static string GetContentType(string fileName)
{
return System.Web.MimeMapping.GetMimeMapping(fileName);
}
}
}

View File

@@ -0,0 +1,215 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace .Utility
{
public class EventBus
{
private static object _lock = new object();
private List<CallBacks> list;
private List<StrCallBacks> strlist;
/// <summary>
/// 单例,防止实例化
/// </summary>
private EventBus()
{
list = new List<CallBacks>();
strlist = new List<StrCallBacks>();
}
private static EventBus _instance;
/// <summary>
/// 获取实例
/// </summary>
public static EventBus Instance
{
get
{
if (_instance == null)
{
_instance = new EventBus();
return _instance;
}
return _instance;
}
}
/// <summary>
/// 订阅消息obj这个对象订阅T这个消息发布消息时调用回调方法
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <param name="callBackFunc"></param>
public void Subscribe<T>(object obj, Action<T> callBackFunc) where T : IEvent
{
try
{
//判断有没有注册过,注册过就不能再注册。疑惑点,一个类中多次注册行不行??
if (list.Any(it => it.Subscriber == obj && it.EventType == typeof(T)))
{
return;
}
list.Add(new CallBacks
{
Subscriber = obj,
EventType = typeof(T),
Action = new Action<object>(o => callBackFunc((T)o))
});
}
catch (Exception ex)
{
}
}
/// <summary>
/// 取消订阅obj这个对象取消订阅T这个消息
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
public void UnSubscribe<T>(object obj) where T : IEvent
{
try
{
list.RemoveAll(it => it.Subscriber == obj && it.EventType == typeof(T));
}
catch (Exception ex)
{
}
}
/// <summary>
/// 发布消息
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="data"></param>
public void Publish<T>(T data) where T : IEvent
{
list.Where(it => it.EventType == typeof(T)).ToList().ForEach(it =>
{
//Task.Run(() => it.Action(data));
try
{
it.Action(data);
}
catch (Exception ex)
{
}
});
}
public void Subscribe(object obj, string eventName, Action<string> callBackFunc)
{
try
{
//判断有没有注册过,注册过就不能再注册。疑惑点,一个类中多次注册行不行??
if (strlist.Any(it => it.Subscriber == obj && it.EventName == eventName))
{
return;
}
strlist.Add(new StrCallBacks
{
Subscriber = obj,
EventName = eventName,
Action = callBackFunc
});
}
catch (Exception ex)
{
}
}
public void UnSubscribe(object obj, string eventName)
{
try
{
strlist.RemoveAll(it => it.Subscriber == obj && it.EventName == eventName);
}
catch (Exception ex)
{
}
}
public void Publish(string eventName, string data)
{
try
{
strlist.Where(it => it.EventName == eventName).ToList().ForEach(it =>
{
it.Action(data);
});
}
catch (Exception ex)
{
}
}
/// <summary>
/// 内部类
/// </summary>
class CallBacks
{
/// <summary>
/// T的类型
/// </summary>
public Type EventType { get; set; }
/// <summary>
/// 谁订阅对象
/// </summary>
public object Subscriber { get; set; }
public Action<object> Action { get; set; }
}
class StrCallBacks
{
/// <summary>
/// T的类型
/// </summary>
public string EventName { get; set; }
/// <summary>
/// 谁订阅对象
/// </summary>
public object Subscriber { get; set; }
public Action<string> Action { get; set; }
}
}
public interface IEvent { }
public class ConsoleLogEvent : IEvent
{
public DateTime DateTime { get; set; }
public string Message { get; set; }
public string Type { get; set; }
public ConsoleLogEvent(string message) : this("I", message)
{
}
public ConsoleLogEvent(string type, string message)
{
this.Type = type;
this.Message = message;
this.DateTime = DateTime.Now;
}
public override string ToString()
{
return $"{DateTime.ToString("yyyy-MM-dd HH:mm:ss.fff")}[{Type}]->{Message}";
}
}
public class ClearLogEvent : IEvent
{
}
}

View File

@@ -18,6 +18,8 @@ namespace 电子展板.Utility.Extension
}
public static string Root(string vPath)
{
if (vPath == null)
vPath = "";
string path = Environment.CurrentDirectory.Replace("/", "\\");
if (!path.EndsWith("\\")) path += "\\";
vPath = vPath.Replace("/", "\\");

View File

@@ -0,0 +1,53 @@
using System;
namespace .Utility.Other
{
public class CalcUtils
{
/// <summary>
/// 计算两个坐标的距离
/// </summary>
/// <param name="long1">经度1</param>
/// <param name="lat1">纬度1</param>
/// <param name="long2">经度2</param>
/// <param name="lat2">纬度2</param>
/// <returns></returns>
public static double getDistance(double long1, double lat1, double long2, double lat2)
{
double a, b, R;
R = 6371393; // 地球半径
lat1 = lat1 * Math.PI / 180.0;
lat2 = lat2 * Math.PI / 180.0;
a = lat1 - lat2;
b = (long1 - long2) * Math.PI / 180.0;
double d;
double sa2, sb2;
sa2 = Math.Sin(a / 2.0);
sb2 = Math.Sin(b / 2.0);
d = 2 * R * Math.Asin(Math.Sqrt(sa2 * sa2 + Math.Cos(lat1) * Math.Cos(lat2) * sb2 * sb2));
return d;
}
public static double algorithm(double longitude1, double latitude1, double longitude2, double latitude2)
{
double Lat1 = rad(latitude1); // 纬度
double Lat2 = rad(latitude2);
double a = Lat1 - Lat2;//两点纬度之差
double b = rad(longitude1) - rad(longitude2); //经度之差
double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) + Math.Cos(Lat1) * Math.Cos(Lat2) * Math.Pow(Math.Sin(b / 2), 2)));//计算两点距离的公式
s = s * 6378137.0;//弧长乘地球半径(半径为米)
s = Math.Round(s * 10000d) / 10000d;//精确距离的数值
return s;
}
private static double rad(double d)
{
return d * Math.PI / 180.00; //角度转换成弧度
}
public static double getVectorAngle(double x1, double y1, double x2, double y2)
{
return Math.Acos((x1 * x2 + y1 * y2) / (Math.Sqrt(x1 * x1 + y1 * y1) * Math.Sqrt(x2 * x2 + y2 * y2))) * 180.0 / Math.PI;
}
}
}

View File

@@ -0,0 +1,40 @@
using System;
namespace .Utility.Other
{
public class PositionUtils
{
private static double pi = 3.1415926535897932384626;
private static double a = 6378245.0;
private static double ee = 0.00669342162296594323;
private static double bd_pi = 3.14159265358979324 * 3000.0 / 180.0;
/// <summary>
/// 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 将 GCJ-02 坐标转换成 BD-09 坐标
/// </summary>
/// <param name="lat"></param>
/// <param name="lon"></param>
public static void gcj02_To_Bd09(ref double lat, ref double lon)
{
double x = lon, y = lat;
double z = Math.Sqrt(x * x + y * y) + 0.00002 * Math.Sin(y * bd_pi);
double theta = Math.Atan2(y, x) + 0.000003 * Math.Cos(x * bd_pi);
lon = z * Math.Cos(theta) + 0.0065;
lat = z * Math.Sin(theta) + 0.006;
}
/// <summary>
/// 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 * * 将 BD-09 坐标转换成GCJ-02 坐标
/// </summary>
/// <param name="lat"></param>
/// <param name="lon"></param>
public static void bd09_To_Gcj02(ref double lat, ref double lon)
{
double x = lon - 0.0065, y = lat - 0.006;
double z = Math.Sqrt(x * x + y * y) - 0.00002 * Math.Sin(y * bd_pi);
double theta = Math.Atan2(y, x) - 0.000003 * Math.Cos(x * bd_pi);
lon = z * Math.Cos(theta);
lat = z * Math.Sin(theta);
}
}
}

View File

@@ -0,0 +1,13 @@
using System;
namespace .Utility.Other
{
public class RandomUtils
{
public static int GetRandomInt(int start, int end)
{
Random rand = new Random();
return rand.Next(start, end);
}
}
}

View File

@@ -0,0 +1,203 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace .Utility.Other
{
public class SnowFlakeHelper
{
private static readonly object _obj = new object();
private static SnowFlakeHelper Instance;
private SnowFlakeHelper()
{
}
/// <summary>
/// 获取雪花帮助类对象
/// </summary>
/// <param name="datacenterId">数据中心ID</param>
/// <param name="workerId">工作机器Id</param>
/// <returns></returns>
public static SnowFlakeHelper GetSnowInstance(long datacenterId = 1, long workerId = 1)
{
//双if 加锁
if (Instance == null)
{
lock (_obj)
{
if (Instance == null)
{
Instance = new SnowFlakeHelper(datacenterId, workerId);
}
}
}
return Instance;
}
// 开始时间截((new DateTime(2020, 1, 1, 0, 0, 0, DateTimeKind.Utc)-Jan1st1970).TotalMilliseconds)
private const long twepoch = 1577836800000L;
// 机器id所占的位数
private const int workerIdBits = 5;
// 数据标识id所占的位数
private const int datacenterIdBits = 5;
// 支持的最大机器id结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数)
private const long maxWorkerId = -1L ^ (-1L << workerIdBits);
// 支持的最大数据标识id结果是31
private const long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
// 序列在id中占的位数
private const int sequenceBits = 12;
// 数据标识id向左移17位(12+5)
private const int datacenterIdShift = sequenceBits + workerIdBits;
// 机器ID向左移12位
private const int workerIdShift = sequenceBits;
// 时间截向左移22位(5+5+12)
private const int timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
// 生成序列的掩码这里为4095 (0b111111111111=0xfff=4095)
private const long sequenceMask = -1L ^ (-1L << sequenceBits);
// 数据中心ID(0~31)
public long datacenterId { get; private set; }
// 工作机器ID(0~31)
public long workerId { get; private set; }
// 毫秒内序列(0~4095)
public long sequence { get; private set; }
// 上次生成ID的时间截
public long lastTimestamp { get; private set; }
/// <summary>
/// 雪花ID
/// </summary>
/// <param name="datacenterId">数据中心ID</param>
/// <param name="workerId">工作机器ID</param>
private SnowFlakeHelper(long datacenterId, long workerId)
{
if (datacenterId > maxDatacenterId || datacenterId < 0)
{
throw new Exception(string.Format("datacenter Id can't be greater than {0} or less than 0", maxDatacenterId));
}
if (workerId > maxWorkerId || workerId < 0)
{
throw new Exception(string.Format("worker Id can't be greater than {0} or less than 0", maxWorkerId));
}
this.workerId = workerId;
this.datacenterId = datacenterId;
this.sequence = 0L;
this.lastTimestamp = -1L;
}
/// <summary>
/// 获得下一个ID
/// </summary>
/// <returns></returns>
public long NextId()
{
lock (this)
{
long timestamp = GetCurrentTimestamp();
if (timestamp > lastTimestamp) //时间戳改变,毫秒内序列重置
{
sequence = 0L;
}
else if (timestamp == lastTimestamp) //如果是同一时间生成的,则进行毫秒内序列
{
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) //毫秒内序列溢出
{
timestamp = GetNextTimestamp(lastTimestamp); //阻塞到下一个毫秒,获得新的时间戳
}
}
else //当前时间小于上一次ID生成的时间戳证明系统时钟被回拨此时需要做回拨处理
{
sequence = (sequence + 1) & sequenceMask;
if (sequence > 0)
{
timestamp = lastTimestamp; //停留在最后一次时间戳上,等待系统时间追上后即完全度过了时钟回拨问题。
}
else //毫秒内序列溢出
{
timestamp = lastTimestamp + 1; //直接进位到下一个毫秒
}
//throw new Exception(string.Format("Clock moved backwards. Refusing to generate id for {0} milliseconds", lastTimestamp - timestamp));
}
lastTimestamp = timestamp; //上次生成ID的时间截
//移位并通过或运算拼到一起组成64位的ID
var id = ((timestamp - twepoch) << timestampLeftShift)
| (datacenterId << datacenterIdShift)
| (workerId << workerIdShift)
| sequence;
return id;
}
}
/// <summary>
/// 解析雪花ID
/// </summary>
/// <returns></returns>
public static string AnalyzeId(long Id)
{
StringBuilder sb = new StringBuilder();
var timestamp = (Id >> timestampLeftShift);
var time = Jan1st1970.AddMilliseconds(timestamp + twepoch);
sb.Append(time.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss:fff"));
var datacenterId = (Id ^ (timestamp << timestampLeftShift)) >> datacenterIdShift;
sb.Append("_" + datacenterId);
var workerId = (Id ^ ((timestamp << timestampLeftShift) | (datacenterId << datacenterIdShift))) >> workerIdShift;
sb.Append("_" + workerId);
var sequence = Id & sequenceMask;
sb.Append("_" + sequence);
return sb.ToString();
}
/// <summary>
/// 阻塞到下一个毫秒,直到获得新的时间戳
/// </summary>
/// <param name="lastTimestamp">上次生成ID的时间截</param>
/// <returns>当前时间戳</returns>
private static long GetNextTimestamp(long lastTimestamp)
{
long timestamp = GetCurrentTimestamp();
while (timestamp <= lastTimestamp)
{
timestamp = GetCurrentTimestamp();
}
return timestamp;
}
/// <summary>
/// 获取当前时间戳
/// </summary>
/// <returns></returns>
private static long GetCurrentTimestamp()
{
return (long)(DateTime.UtcNow - Jan1st1970).TotalMilliseconds;
}
private static readonly DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
}
}

View File

@@ -0,0 +1,47 @@
using System;
namespace .Utility.Other
{
public class UUID
{
public static long SnowId
{
get
{
return SnowFlakeHelper.GetSnowInstance().NextId();
}
}
public static string StrSnowId
{
get
{
return Convert.ToString(SnowId);
}
}
public static string NewTimeUUID
{
get
{
return DateTime.Today.ToString("yyyyMMdd") + Guid.NewGuid().ToString().Replace("-", "").ToUpper().Substring(0, 10);
}
}
public static string NewTimeUUID2
{
get
{
return DateTime.Today.ToString("yyyyMMdd") + Guid.NewGuid().ToString().Replace("-", "").ToUpper();
}
}
public static string NewUUID
{
get
{
return Guid.NewGuid().ToString().Replace("-", "").ToUpper();
}
}
}
}

View File

@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace .Utility.Web
{
public class WithExtensionMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
{
public string guid { get; set; }
public string OriginalName { get; set; }
public string Ext { get; set; }
public WithExtensionMultipartFormDataStreamProvider(string rootPath, string guidStr) : base(rootPath)
{
guid = guidStr;
}
public override string GetLocalFileName(System.Net.Http.Headers.HttpContentHeaders headers)
{
OriginalName = !string.IsNullOrWhiteSpace(headers.ContentDisposition.FileName) ? GetValidFileName(headers.ContentDisposition.FileName) : "";
Ext = !string.IsNullOrWhiteSpace(OriginalName) ? Path.GetExtension(GetValidFileName(OriginalName)) : "";
return guid + Ext;
}
private string GetValidFileName(string filePath)
{
char[] invalids = System.IO.Path.GetInvalidFileNameChars();
return string.Join("_", filePath.Split(invalids, StringSplitOptions.RemoveEmptyEntries)).TrimEnd('.');
}
}
}

View File

@@ -0,0 +1,139 @@
using System;
using System.ComponentModel;
using System.IO;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using .Base;
using .Utility;
using .Utility.Extension;
namespace .ViewModels
{
public class MainWindow2ViewModel : ViewModelBase
{
private Window window;
public DelegateCommand<Window> LoadedCommand { get; set; }
public DelegateCommand<CancelEventArgs> WindowClosingCommand { get; set; }
public ImageSource Image1 { get; set; }
public ImageSource Image2 { get; set; }
public ImageSource Image3 { get; set; }
public ImageSource Image4 { get; set; }
public MainWindow2ViewModel()
{
LoadedCommand = new DelegateCommand<Window>(Loaded);
WindowClosingCommand = new DelegateCommand<CancelEventArgs>(WindowClosing);
EventBus.Instance.Subscribe(this, "save", ReloadImage);
InitImage();
}
private void ReloadImage(string obj)
{
App.Current.Dispatcher.Invoke(() =>
{
InitImage();
});
}
private void InitImage()
{
try
{
BitmapImage image1 = new BitmapImage();
image1.BeginInit();
image1.CacheOption = BitmapCacheOption.OnLoad;
image1.StreamSource = new MemoryStream(File.ReadAllBytes(MyEnvironment.Root(Config.CPCMember1Path)));
image1.EndInit();
image1.Freeze();
Image1 = image1;
}
catch (Exception ex)
{
Image1 = null;
}
try
{
BitmapImage image2 = new BitmapImage();
image2.BeginInit();
image2.CacheOption = BitmapCacheOption.OnLoad;
image2.StreamSource = new MemoryStream(File.ReadAllBytes(MyEnvironment.Root(Config.CPCMember2Path)));
image2.EndInit();
image2.Freeze();
Image2 = image2;
}
catch (Exception ex)
{
Image2 = null;
}
try
{
BitmapImage image3 = new BitmapImage();
image3.BeginInit();
image3.CacheOption = BitmapCacheOption.OnLoad;
image3.StreamSource = new MemoryStream(File.ReadAllBytes(MyEnvironment.Root(Config.CPCMember3Path)));
image3.EndInit();
image3.Freeze();
Image3 = image3;
}
catch (Exception ex)
{
Image3 = null;
}
try
{
BitmapImage image4 = new BitmapImage();
image4.BeginInit();
image4.CacheOption = BitmapCacheOption.OnLoad;
image4.StreamSource = new MemoryStream(File.ReadAllBytes(MyEnvironment.Root(Config.CPCMember4Path)));
image4.EndInit();
image4.Freeze();
Image4 = image4;
}
catch (Exception ex)
{
Image4 = null;
}
}
private void Loaded(Window window)
{
this.window = window;
Screen[] screens = Screen.AllScreens;
if (screens.Length > 1)
{
int screenIndex = 1;
this.window.Left = (int)(Screen.AllScreens[screenIndex].Bounds.Left / GetDpiScaleX());
this.window.Top = (int)(Screen.AllScreens[screenIndex].Bounds.Top / GetDpiScaleX());
this.window.Width = (int)(Screen.AllScreens[screenIndex].Bounds.Width / GetDpiScaleX());
this.window.Height = (int)(Screen.AllScreens[screenIndex].Bounds.Height / GetDpiScaleX());
}
else
{
window.Close();
}
}
/// <summary>
/// 界面关闭时
/// </summary>
public void WindowClosing(CancelEventArgs args)
{
WebServer.Stop();
Screen[] screens = Screen.AllScreens;
if (screens.Length > 1)
{
Environment.Exit(0);
}
}
public double GetDpiScaleX()
{
return VisualTreeHelper.GetDpi(this.window).DpiScaleX;
}
}
}

View File

@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Media;
using .Base;
namespace .ViewModels
{
public class MainWindowViewModel : ViewModelBase
{
private Window window;
public DelegateCommand<Window> LoadedCommand { get; set; }
public DelegateCommand<CancelEventArgs> WindowClosingCommand { get; set; }
public MainWindowViewModel()
{
LoadedCommand = new DelegateCommand<Window>(Loaded);
WindowClosingCommand = new DelegateCommand<CancelEventArgs>(WindowClosing);
}
private void Loaded(Window window)
{
this.window = window;
int screenIndex = 0;
this.window.Left = (int)(Screen.AllScreens[screenIndex].Bounds.Left / GetDpiScaleX());
this.window.Top = (int)(Screen.AllScreens[screenIndex].Bounds.Top / GetDpiScaleX());
this.window.Width = (int)(Screen.AllScreens[screenIndex].Bounds.Width / GetDpiScaleX());
this.window.Height = (int)(Screen.AllScreens[screenIndex].Bounds.Height / GetDpiScaleX());
WebServer.Start();
}
private void WindowClosing(CancelEventArgs args)
{
WebServer.Stop();
Environment.Exit(0);
}
public double GetDpiScaleX()
{
return VisualTreeHelper.GetDpi(this.window).DpiScaleX;
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

View File

@@ -16,12 +16,13 @@
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Costura.Fody" Version="6.0.0">
<!--<PackageReference Include="Costura.Fody" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</PackageReference>-->
<PackageReference Include="HandyControl" Version="3.5.1" />
<PackageReference Include="PropertyChanged.Fody" Version="4.1.0" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
</ItemGroup>
<ItemGroup>
@@ -47,8 +48,8 @@
<PackageReference Include="Microsoft.AspNet.Mvc" Version="5.3.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="ViewModels\" />
<Content Include="Upload\0.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>