422 lines
12 KiB
HTML
422 lines
12 KiB
HTML
<div class="layui-card border-b">
|
|
<div class='layui-card-body {$role=="0"?"hover-view":"hover-edit"}'>
|
|
<div class="py-1">
|
|
<span class="gray">项目状态:</span>
|
|
<span class="layui-color-{$detail.status}" id="status_{$detail.id}"
|
|
data-val="{$detail.status}">{$detail.status_name}</span><i
|
|
class="iconfont icon-wodedianping" title="编辑" data-name="status"></i>
|
|
<span class="gray" style="margin-left:32px">负责人:</span>
|
|
<span id="director_uid_{$detail.id}" data-val="{$detail.director_uid}">{$detail.director_name}</span>
|
|
<i class="iconfont icon-wodedianping" title="编辑" data-id="{$detail.id}" data-name="director_uid"></i>
|
|
<span class="gray" style="margin-left:32px">项目成员:</span>{$detail.team_admin_names}
|
|
</div>
|
|
<div class="py-1">
|
|
<span class="gray">计划完成周期:</span>
|
|
<span id="start_time_{$detail.id}" data-val="">{$detail.start_time}</span>
|
|
<i class="iconfont icon-wodedianping" title="修改计划开始日期" data-name="start_time"></i> 至 <span id="end_time_{$detail.id}"
|
|
data-val="">{$detail.end_time}</span><i class="iconfont icon-wodedianping"
|
|
title="修改计划结束日期" data-name="end_time"></i>
|
|
</div>
|
|
<div class="py-1">
|
|
<span class="gray">项目简介:</span>
|
|
<span id="content_{$detail.id}" data-val="{$detail.content}">{$detail.content}</span>
|
|
<i class="iconfont icon-wodedianping" title="编辑" data-id="{$detail.id}" data-name="content"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="layui-card border-y">
|
|
<div class="layui-card-header" style="height:45px;">
|
|
<div class="layui-row">
|
|
<div class="layui-col-md6">
|
|
<h5>项目附件</h5>
|
|
</div>
|
|
<div class="layui-col-md6" style="text-align:right">
|
|
<button type="button" class="layui-btn layui-btn-normal layui-btn-sm" id="fileBtn">上传附件</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="layui-row p-2" id="fileList">
|
|
{volist name="file_array" id="vo"}
|
|
<div class="layui-col-md4">
|
|
<div class="file-card">
|
|
<i class="file-icon iconfont icon-ziyuan"></i>
|
|
<div class="file-title" title="上传人:{$vo.admin_name}">
|
|
{$vo.name}
|
|
</div>
|
|
<div class="file-tool">
|
|
<a href="{$vo.filepath}" download="{$vo.name}" data-id="{$vo.id}" target="_blank" title="大小:{$vo.filesize/1048576|round=2}MB">
|
|
<i class="iconfont icon-shujudaoru" style="color: #12bb37;"></i>
|
|
</a>
|
|
<i class="btn-delete iconfont icon-shanchu" data-id="{$vo.id}" style="color: #FF5722;"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{/volist}
|
|
{empty name="$file_array" }
|
|
<div class="layui-data-none">暂无附件</div>
|
|
{/empty}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="layui-row mb-3 border-y">
|
|
<div class="layui-col-xs6 layui-col-md4">
|
|
<div class="layui-card border-l">
|
|
<div class="layui-card-header">
|
|
<h5>项目概况</h5>
|
|
</div>
|
|
<div class="layui-card-body">
|
|
<div style="width:100%; height:200px;">
|
|
<dl>
|
|
<dt>任务 <span class="gray">(已完成/总任务)</span></dt>
|
|
<dd class="layui-card-value" title="已完成/总任务">{$detail.tasks_finish} / {$detail.tasks}</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt>项目工时 <span class="gray">(实际工时/计划工时)</span></dt>
|
|
<dd class="layui-card-value" title="实际工时/计划工时">{$detail.hours} / {$detail.plan_hours}</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt>工作记录</dt>
|
|
<dd class="layui-card-value" title="工作记录数">{$detail.schedules}</dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="layui-col-xs6 layui-col-md8">
|
|
<div class="layui-card">
|
|
<div class="layui-card-header">
|
|
<h5>项目进度</h5>
|
|
</div>
|
|
<div class="layui-card-body">
|
|
<div class="layui-row">
|
|
<div class="layui-col-md6">
|
|
<div id="progress" class="gougu-data-none" style="width:100%; height:200px;"></div>
|
|
</div>
|
|
<div class="layui-col-md6">
|
|
<div id="delay" class="gougu-data-none" style="width:100%; height:200px;"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="layui-card border-y">
|
|
<div class="layui-card-header">
|
|
<h5>项目燃尽图</h5>
|
|
</div>
|
|
<div class="layui-card-body">
|
|
<div id="cross" class="gougu-data-none" style="width:100%; height:360px;"
|
|
data-tips="任务数:{$detail.tasks},已完成:{$detail.tasks_finish},未完成:{$detail.tasks_unfinish}">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="layui-row border-y">
|
|
<div class="layui-col-xs6 layui-col-md6">
|
|
<div class="layui-card border-r">
|
|
<div class="layui-card-header">
|
|
<h5>任务分配情况</h5>
|
|
</div>
|
|
<div class="layui-card-body">
|
|
<div id="plan" class="gougu-data-none" style="width:100%; height:150px;"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="layui-col-xs6 layui-col-md6">
|
|
<div class="layui-card">
|
|
<div class="layui-card-header">
|
|
<h5>工时登记情况</h5>
|
|
</div>
|
|
<div class="layui-card-body">
|
|
<div id="work" class="gougu-data-none" style="width:100%; height:150px;"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
function overview(){
|
|
let form = layui.form,tool = layui.tool, edit = layui.oaEdit,upload = layui.upload;
|
|
$('.hover-edit').hover(function () {
|
|
$(this).addClass('hover-on');
|
|
}, function () {
|
|
$(this).removeClass('hover-on');
|
|
})
|
|
|
|
$('.hover-edit').on('click', 'i', function () {
|
|
let name = $(this).data('name');
|
|
let show_txt = $('#' + name + '_' + project_id).text().replace(/[\r\n\t]/g, "");
|
|
let real_txt = $('#' + name + '_' + project_id).data('val');
|
|
if (real_txt === '') {
|
|
real_txt = show_txt;
|
|
}
|
|
editShow(project_id, name, show_txt, real_txt);
|
|
})
|
|
|
|
let loading = false;
|
|
let editPost = function (id, name, show_val, real_val) {
|
|
let callback = function (e) {
|
|
layer.closeAll();
|
|
layer.msg(e.msg);
|
|
if (e.code == 0) {
|
|
setTimeout(function () {
|
|
location.reload();
|
|
}, 1000)
|
|
}
|
|
}
|
|
let postData = { id: id };
|
|
postData[name] = real_val;
|
|
tool.post("/project/index/add", postData, callback);
|
|
}
|
|
|
|
function editShow(id, name, show_txt, real_txt) {
|
|
if (loading == true) {
|
|
return false;
|
|
}
|
|
if (name == "name") {
|
|
edit.text(id, name, real_txt, editPost);
|
|
}
|
|
if (name == "start_time" || name == "end_time") {
|
|
edit.date(id, name, real_txt, editPost);
|
|
}
|
|
if (name == "director_uid") {
|
|
edit.employee_one(id, name, show_txt, real_txt, editPost);
|
|
}
|
|
if (name == "status") {
|
|
edit.dropdown(id, name, real_txt, opsData[name], editPost);
|
|
}
|
|
if (name == "product_id") {
|
|
loading = true;
|
|
gougu.get("/api/index/get_product", {}, function (res) {
|
|
let data = res.data;
|
|
loading = false;
|
|
edit.dropdown(id, name, real_txt, data, editPost, 1);
|
|
});
|
|
}
|
|
if (name == "content") {
|
|
edit.textarea(id, name, real_txt, editPost);
|
|
}
|
|
}
|
|
|
|
|
|
$('#delProject').on('click', function () {
|
|
layer.confirm('确定要删除该项目吗?请慎重', { icon: 3, title: '提示' }, function (index) {
|
|
let callback = function (e) {
|
|
layer.closeAll();
|
|
layer.msg(e.msg);
|
|
if(e.code==0){
|
|
setTimeout(function () {
|
|
location.href='/project/index/index';
|
|
}, 1000)
|
|
}
|
|
}
|
|
let postData = { "id": project_id };
|
|
tool.delete("/project/index/delete", postData, callback);
|
|
});
|
|
})
|
|
|
|
upload.render({
|
|
elem: '#fileBtn'
|
|
, url: '/api/index/upload'
|
|
, accept: 'file' //普通文件
|
|
, exts: 'jpeg|jpg|png|gif|doc|docx|ppt|pptx|xls|xlsx|pdf|zip|rar|7z' //只允许上传文件
|
|
, before: function (obj) {
|
|
layer.msg('上传中...', { time: 3600000 });
|
|
}
|
|
, done: function (res, index, upload) {
|
|
let callback = function (e) {
|
|
layer.msg('上传成功');
|
|
setTimeout(function(){
|
|
location.reload();
|
|
},2000)
|
|
}
|
|
let postData = { 'topic_id': project_id, 'file_id': res.data.id, 'file_name': res.data.name, 'module': 'project' };
|
|
if(res.code>0){
|
|
layer.msg(res.msg);
|
|
}
|
|
else{
|
|
tool.post("/project/api/add_file", postData, callback);
|
|
}
|
|
}
|
|
, error: function (index, upload) {
|
|
layer.msg('上传失败');
|
|
}
|
|
});
|
|
|
|
$('#fileList').on('click', '.btn-delete', function () {
|
|
let id = $(this).data('id');
|
|
layer.confirm('确定要删除该附件吗?', { icon: 3, title: '提示' }, function (index) {
|
|
let callback = function (e) {
|
|
layer.closeAll();
|
|
layer.msg(e.msg);
|
|
setTimeout(function(){
|
|
location.reload();
|
|
},2000)
|
|
}
|
|
let postData = { "id": id };
|
|
tool.delete("/project/api/delete_file", postData, callback);
|
|
});
|
|
})
|
|
|
|
$('#linkBtn').on('click', function () {
|
|
comment.addLink(0, project_id, 'project', '', '');
|
|
})
|
|
$('#linkList').on('click', '.link-edit', function () {
|
|
let id = $(this).data('id');
|
|
let url = $(this).data('url');
|
|
let desc = $(this).data('desc');
|
|
comment.addLink(id, project_id, 'project', url, desc);
|
|
})
|
|
$('#linkList').on('click', '.link-delete', function () {
|
|
let id = $(this).data('id');
|
|
layer.confirm('确定要删除该链接吗?', { icon: 3, title: '提示' }, function (index) {
|
|
let callback = function (e) {
|
|
layer.closeAll();
|
|
layer.msg(e.msg);
|
|
setTimeout(function(){
|
|
location.reload();
|
|
},2000)
|
|
}
|
|
let postData = { "id": id };
|
|
tool.delete("/api/appendix/delete_link", postData, callback);
|
|
});
|
|
})
|
|
|
|
let callback = function (res) {
|
|
if (res.data.date_tasks instanceof Array == false) {
|
|
optionA.title.text = res.data.task_pie.ok_lv + '%';
|
|
optionA.series = [
|
|
{
|
|
type: 'pie',
|
|
radius: ['60%', '80%'],
|
|
center: ['50%', '50%'],
|
|
avoidLabelOverlap: false,
|
|
label: {
|
|
show: false
|
|
},
|
|
data: [
|
|
{ value: res.data.task_pie.count - res.data.task_pie.count_ok, name: '待处理' },
|
|
{ value: res.data.task_pie.count_ok, name: '已完成' }
|
|
]
|
|
}
|
|
];
|
|
optionA && progressChart.setOption(optionA);
|
|
|
|
optionB.title.text = res.data.task_pie.delay_lv + '%';
|
|
optionB.series = [
|
|
{
|
|
type: 'pie',
|
|
radius: ['60%', '80%'],
|
|
center: ['50%', '50%'],
|
|
avoidLabelOverlap: false,
|
|
label: {
|
|
show: false
|
|
},
|
|
data: [{
|
|
value: res.data.task_pie.delay,
|
|
name: '延误',
|
|
itemStyle: {
|
|
color: "#ED6666",
|
|
}
|
|
},
|
|
{
|
|
value: res.data.task_pie.count - res.data.task_pie.delay,
|
|
name: '按时完成',
|
|
itemStyle: {
|
|
color: "#91CC75",
|
|
}
|
|
}
|
|
]
|
|
}
|
|
];
|
|
optionB && delayChart.setOption(optionB);
|
|
|
|
var dataD = cross_count(res.data.date_tasks, res.data.date_tasks_ok);
|
|
var tips = $('#cross').data('tips');
|
|
optionD.title = {
|
|
text: '',
|
|
subtext: tips,
|
|
top: -10,
|
|
},
|
|
optionD.xAxis = {
|
|
type: 'category',
|
|
boundaryGap: false,
|
|
splitLine: {
|
|
show: true,
|
|
lineStyle: {
|
|
type: 'dashed'
|
|
}
|
|
},
|
|
data: dataD.x,
|
|
axisLabel: {
|
|
rotate: 30,
|
|
formatter: function (value, index) {
|
|
return value.slice(5);
|
|
}
|
|
}
|
|
};
|
|
optionD.series = [
|
|
{
|
|
name: '任务计划剩余',
|
|
type: 'line',
|
|
showSymbol: false,
|
|
markLine: {
|
|
data: [{ type: 'average', name: 'Avg' }],
|
|
},
|
|
lineStyle: {
|
|
width: 2
|
|
},
|
|
data: dataD.y
|
|
},
|
|
{
|
|
name: '任务实际剩余',
|
|
type: 'line',
|
|
showSymbol: false,
|
|
areaStyle: {
|
|
opacity: 0.1
|
|
},
|
|
markLine: {
|
|
data: [{ type: 'average', name: 'Avg' }],
|
|
},
|
|
lineStyle: {
|
|
width: 2
|
|
},
|
|
data: dataD.y2
|
|
}
|
|
]
|
|
optionD && crossChart.setOption(optionD)
|
|
|
|
var dataE = getCalendarData(res.data.date_tasks);
|
|
optionE.calendar.range = dataE.range,
|
|
optionE.series = {
|
|
type: 'heatmap',
|
|
coordinateSystem: 'calendar',
|
|
data: dataE.data
|
|
}
|
|
optionE && planChart.setOption(optionE);
|
|
|
|
if (res.data.date_schedules instanceof Array == false) {
|
|
var dataF = getCalendarData(res.data.date_schedules);
|
|
optionF.calendar.range = dataF.range,
|
|
optionF.series = {
|
|
type: 'heatmap',
|
|
coordinateSystem: 'calendar',
|
|
data: dataE.data
|
|
}
|
|
optionF && workChart.setOption(optionF);
|
|
}
|
|
}
|
|
}
|
|
tool.get('/project/api/get_chart_data', { 'project_id': project_id }, callback);
|
|
|
|
window.onresize = function () {
|
|
progressChart.resize();
|
|
delayChart.resize();
|
|
crossChart.resize();
|
|
planChart.resize();
|
|
workChart.resize();
|
|
}
|
|
}
|
|
</script> |