first commit
This commit is contained in:
@@ -0,0 +1,266 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
<!-- 主体 -->
|
||||
{block name="body"}
|
||||
<form class="layui-form p-page">
|
||||
<h3 class="pb-3">新建项目</h3>
|
||||
<table class="layui-table layui-table-form">
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目名称<font>*</font></td>
|
||||
<td colspan="3"><input type="text" name="name" lay-verify="required" lay-reqText="请输入项目名称" placeholder="请输入项目名称" class="layui-input" value=""></td>
|
||||
<td class="layui-td-gray">项目类别<font>*</font></td>
|
||||
<td>
|
||||
<select name="cate_id" lay-filter="cate" lay-verify="required" lay-reqText="请选择项目类别">
|
||||
<option value="">请选择</option>
|
||||
{volist name = ":get_base_data('ProjectCate')" id="vo"}
|
||||
<option value="{$vo.id}">{$vo.title}</option>
|
||||
{/volist}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目经理<font>*</font></td>
|
||||
<td>
|
||||
<input type="text" name="director_name" placeholder="请选择项目经理(负责人)" readonly class="layui-input" value="" lay-verify="required" readonly lay-reqText="请选择项目经理(负责人)">
|
||||
<input type="hidden" name="director_uid" value="0">
|
||||
<input type="hidden" name="did" value="0">
|
||||
</td>
|
||||
<td class="layui-td-gray">归属部门<font>*</font></td>
|
||||
<td><input type="text" name="department" value="" autocomplete="off" readonly class="layui-input"></td>
|
||||
<td class="layui-td-gray">始止日期<span style="color: red">*</span></td>
|
||||
<td><input type="text" name="range_time" class="layui-input tool-time" data-range="到" readonly placeholder="开始 到 结束" lay-verify="required" lay-reqText="请选择计划完成周期"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目成员<span style="color: red">*</span></td>
|
||||
<td colspan="5">
|
||||
<input type="text" name="team_admin_names" placeholder="请选择项目成员" readonly class="layui-input picker-admin" data-type="2" value="" lay-verify="required" lay-reqText="请完善项目成员">
|
||||
<input type="hidden" name="team_admin_ids" class="layui-input" value="">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">关联合同</td>
|
||||
<td colspan="5">
|
||||
<input type="text" class="layui-input picker-oa" data-types="contract" name="contract_name" placeholder="请选择需要关联的合同" readonly value="">
|
||||
<input type="hidden" class="layui-input" name="contract_id" value="0">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目简介</td>
|
||||
<td colspan="5">
|
||||
<textarea name="content" class="layui-textarea"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6" style="background-color:#FAFAFA;">
|
||||
<strong>项目阶段</strong><span style="color: red">*</span>
|
||||
<span class="layui-btn layui-btn-sm" id="stepAdd">+ 添加阶段</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6">
|
||||
<table id="stepTable" class="layui-table layui-table-min" style="margin:0">
|
||||
<tr>
|
||||
<th width="60">序号</th>
|
||||
<th width="200">阶段名称</th>
|
||||
<th width="80">阶段负责人</th>
|
||||
<th width="180">阶段成员</th>
|
||||
<th width="162">阶段周期</th>
|
||||
<th>阶段说明</th>
|
||||
<th width="120">操作</th>
|
||||
</tr>
|
||||
{volist name = ":get_base_data('step')" id="vo" key="k"}
|
||||
<tr class="step-tr">
|
||||
<td class="step-key">第 <strong>{$k}</strong> 阶段</td>
|
||||
<td>
|
||||
<div class="layui-input-group">
|
||||
<input type="text" name="step_title[]" value="{$vo.title}" class="layui-input" lay-verify="required" lay-reqText="请输入阶段名称">
|
||||
<div class="layui-input-split layui-input-suffix picker-diy" style="cursor: pointer;"><i class="layui-icon layui-icon-search"></i></div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" value="" class="layui-input layui-input-readonly picker-admin" lay-verify="required" lay-reqText="请选择阶段负责人" readonly>
|
||||
<input type="hidden" name="step_director_uid[]" value="0" readonly>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" value="" class="layui-input layui-input-readonly picker-admin" data-type="2">
|
||||
<input type="hidden" name="step_uids[]" value="">
|
||||
</td>
|
||||
<td><input type="text" name="step_cycle_time[]" value="" class="layui-input layui-input-readonly tool-time" data-range="到" lay-verify="required" lay-reqText="请选择阶段周期" readonly></td>
|
||||
<td><input type="text" name="step_remark[]" value="" class="layui-input"></td>
|
||||
<td>
|
||||
<input type="hidden" name="step_id[]" value="0" class="layui-input">
|
||||
<div class="layui-btn-group">
|
||||
<span class="layui-btn layui-btn-xs step-up">上移</span>
|
||||
<span class="layui-btn layui-btn-normal layui-btn-xs step-down">下移</span>
|
||||
<span class="layui-btn layui-btn-danger layui-btn-xs step-del" data-id="0">删除</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{/volist}
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="pt-3">
|
||||
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
|
||||
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
|
||||
</div>
|
||||
</form>
|
||||
{/block}
|
||||
<!-- /主体 -->
|
||||
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script>
|
||||
var moduleInit = ['tool','oaPicker'];
|
||||
|
||||
function gouguInit() {
|
||||
var form = layui.form, tool = layui.tool,oaPicker = layui.oaPicker;
|
||||
//选择项目经理
|
||||
$('body').on('click','[name="director_name"]',function () {
|
||||
var ids=$('[name="director_uid"]').val(),names=$('[name="director_name"]').val();
|
||||
oaPicker.employeeInit({
|
||||
ids:ids,
|
||||
names:names,
|
||||
type:1,
|
||||
callback:function(data){
|
||||
let select_id=[],select_name=[],select_did=[],select_dname=[];
|
||||
for(var a=0; a<data.length;a++){
|
||||
select_id.push(data[a].id);
|
||||
select_name.push(data[a].name);
|
||||
select_did.push(data[a].did);
|
||||
select_dname.push(data[a].department);
|
||||
}
|
||||
$('[name="director_uid"]').val(select_id.join(','));
|
||||
$('[name="director_name"]').val(select_name.join(','));
|
||||
$('[name="did"]').val(select_did.join(','));
|
||||
$('[name="department"]').val(select_dname.join(','));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//添加阶段信息表格
|
||||
$('#stepAdd').on('click',function(){
|
||||
var html = '';
|
||||
html += '<tr class="step-tr">\
|
||||
<td class="step-key">第 <strong>0</strong> 阶段</td>\
|
||||
<td>\
|
||||
<div class="layui-input-group">\
|
||||
<input type="text" name="step_title[]" value="" class="layui-input" lay-verify="required" lay-reqText="请输入阶段名称">\
|
||||
<div class="layui-input-split layui-input-suffix picker-diy" style="cursor: pointer;"><i class="layui-icon layui-icon-search"></i></div>\
|
||||
</div>\
|
||||
</td>\
|
||||
<td>\
|
||||
<input type="text" value="" class="layui-input layui-input-readonly picker-admin" lay-verify="required" lay-reqText="请选择阶段负责人" readonly>\
|
||||
<input type="hidden" name="step_director_uid[]" value="0" readonly>\
|
||||
</td>\
|
||||
<td>\
|
||||
<input type="text" value="" class="layui-input layui-input-readonly picker-admin" data-type="2">\
|
||||
<input type="hidden" name="step_uids[]" value="">\
|
||||
</td>\
|
||||
<td><input type="text" name="step_cycle_time[]" value="" class="layui-input layui-input-readonly tool-time" data-range="到" lay-verify="required" lay-reqText="请选择服务周期" readonly></td>\
|
||||
<td><input type="text" name="step_remark[]" value="" class="layui-input"></td>\
|
||||
<td>\
|
||||
<input type="hidden" name="step_id[]" value="0" class="layui-input">\
|
||||
<div class="layui-btn-group">\
|
||||
<span class="layui-btn layui-btn-xs step-up">上移</span>\
|
||||
<span class="layui-btn layui-btn-normal layui-btn-xs step-down">下移</span>\
|
||||
<span class="layui-btn layui-btn-danger layui-btn-xs step-del" data-id="0">删除</span>\
|
||||
</div>\
|
||||
</td>\
|
||||
</tr>';
|
||||
$('#stepTable').append(html).find('.tr-none').remove();
|
||||
$('#stepTable').find('.step-key').each(function(index,item){
|
||||
$(this).html('第 <strong>'+(index+1)+'</strong> 阶段');
|
||||
})
|
||||
form.render();
|
||||
});
|
||||
$('#stepTable').on('click','.step-del',function(){
|
||||
if($('.step-tr').length<2){
|
||||
layer.msg('至少保留一个项目阶段');
|
||||
return false;
|
||||
}
|
||||
$(this).parents('.step-tr').remove();
|
||||
$('#stepTable').find('.step-key').each(function(index,item){
|
||||
$(this).html('第 <strong>'+(index+1)+'</strong> 阶段');
|
||||
})
|
||||
});
|
||||
|
||||
$('#stepTable').on('click','.step-up',function(e){
|
||||
let obj = $(e.target).closest('tr');
|
||||
tr_pre($(obj[0]));
|
||||
})
|
||||
|
||||
$('#stepTable').on('click','.step-down',function(e){
|
||||
var obj = $(e.target).closest('tr');
|
||||
tr_next($(obj[0]));
|
||||
})
|
||||
|
||||
|
||||
function tr_pre(o) {
|
||||
var pres = o.prevAll('tr.step-tr');
|
||||
if (pres.length > 0) {
|
||||
var tmp = o.clone(true);
|
||||
var oo = pres[0];
|
||||
o.remove();
|
||||
$(oo).before(tmp);
|
||||
$('#stepTable').find('.step-key').each(function(index,item){
|
||||
$(this).html('第 <strong>'+(index+1)+'</strong> 阶段');
|
||||
})
|
||||
}
|
||||
else{
|
||||
layer.msg('已经第一个了');
|
||||
}
|
||||
}
|
||||
|
||||
function tr_next(o) {
|
||||
var nexts = o.nextAll('tr.step-tr');
|
||||
if (nexts.length > 0) {
|
||||
var tmp = o.clone(true);
|
||||
var oo = nexts[0];
|
||||
o.remove();
|
||||
$(oo).after(tmp);
|
||||
$('#stepTable').find('.step-key').each(function(index,item){
|
||||
$(this).html('第 <strong>'+(index+1)+'</strong> 阶段');
|
||||
})
|
||||
}else{
|
||||
layer.msg('已经最后一个了');
|
||||
}
|
||||
}
|
||||
|
||||
$('body').on('click','.picker-diy',function () {
|
||||
let that = $(this),ids = [],titles=[],map = {};
|
||||
let callback = function(data){
|
||||
for ( var i = 0; i <data.length; i++){
|
||||
ids.push(data[i].id);
|
||||
titles.push(data[i].title);
|
||||
}
|
||||
that.prev().val(titles.join(','));
|
||||
}
|
||||
let opts={
|
||||
"title":"选择项目阶段",
|
||||
"url": "/project/api/get_project_step",
|
||||
"ids":"",
|
||||
"titles":"",
|
||||
"area": ['600px', '580px'],
|
||||
"cols":[{field: 'id',width: 80,title:'序号',align:'center'},{field:'title',title:'项目阶段'}]
|
||||
}
|
||||
oaPicker.picker(opts,1,callback,map);//单选
|
||||
});
|
||||
|
||||
|
||||
//监听提交
|
||||
form.on('submit(webform)', function (data) {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
tool.sideClose(1000);
|
||||
}
|
||||
}
|
||||
let clickbtn = $(this);
|
||||
tool.post("/project/index/add", data.field, callback,clickbtn);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /脚本 -->
|
||||
@@ -0,0 +1,154 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
<!-- 主体 -->
|
||||
{block name="body"}
|
||||
|
||||
<div class="p-page">
|
||||
<form class="layui-form gg-form-bar border-t border-x" lay-filter="barsearchform">
|
||||
<div class="layui-input-inline" style="width:100px;">
|
||||
<select name="status">
|
||||
<option value="">项目状态</option>
|
||||
<option value="1">未开始</option>
|
||||
<option value="2">进行中</option>
|
||||
<option value="3">已完成</option>
|
||||
<option value="4">已关闭</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width:136px;">
|
||||
<select name="cate_id">
|
||||
<option value="">项目类别</option>
|
||||
{volist name = ":get_base_data('ProjectCate')" id="vo"}
|
||||
<option value="{$vo.id}">{$vo.title}</option>
|
||||
{/volist}
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width:160px;">
|
||||
<input type="text" name="director" placeholder="项目负责人,可多选" readonly class="layui-input picker-admin" data-type="2" autocomplete="off" />
|
||||
<input name="director_uid" style="display: none;" value="" />
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width:300px">
|
||||
<input type="text" name="keywords" placeholder="关键字,项目名称/项目描述" class="layui-input" autocomplete="off" />
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width:150px">
|
||||
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="table-search"><i class="layui-icon layui-icon-search mr-1"></i>搜索</button>
|
||||
<button type="reset" class="layui-btn layui-btn-reset" lay-filter="table-reset">清空</button>
|
||||
</div>
|
||||
</form>
|
||||
<table class="layui-hide" id="table_project" lay-filter="table_project"></table>
|
||||
</div>
|
||||
|
||||
<script type="text/html" id="toolbarDemo">
|
||||
<div class="layui-btn-container">
|
||||
<button class="layui-btn layui-btn-sm tool-add" type="button" data-href="/project/index/add">+ 添加项目</button>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
{/block}
|
||||
<!-- /主体 -->
|
||||
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script>
|
||||
const auth = {$auth};
|
||||
const moduleInit = ['tool','tablePlus','oaPicker'];
|
||||
function gouguInit() {
|
||||
var table = layui.tablePlus, tool = layui.tool;
|
||||
|
||||
layui.pageTable = table.render({
|
||||
elem: "#table_project"
|
||||
, toolbar: "#toolbarDemo"
|
||||
,url: "/project/index/datalist"
|
||||
,page: true
|
||||
,limit: 20
|
||||
,cellMinWidth: 80
|
||||
,height: 'full-114'
|
||||
,cols: [[
|
||||
{field:'id',width:80, title: 'ID号', align:'center'}
|
||||
,{ field: 'status', title: '项目状态', align: 'center', width: 90, templet: function (d) {
|
||||
var html = '<span class="check-status-color-' + d.status + '">『' + d.status_name + '』</span>';
|
||||
return html;
|
||||
}
|
||||
}
|
||||
,{field:'cate',title: '项目类别',width:100,align:'center'}
|
||||
,{field:'name',title: '项目名称',minWidth:240}
|
||||
,{field:'director_name',title: '负责人',width:80,align:'center'}
|
||||
,{ field:'range_time', title: '项目计划周期', align: 'center', width: 200}
|
||||
,{field:'step',title: '当前阶段及负责人',align: 'center',width: 180}
|
||||
,{field:'tasks_unfinish', align: 'center', style: 'color: #91CC75;', width: 90, 'title': '进行中任务' }
|
||||
,{field:'tasks_finish', align: 'center', style: 'color: #FAC858;', width: 90, 'title': '已完成任务' }
|
||||
,{field:'tasks_pensent', align: 'center', style: 'color: #EE6666;', width: 90, 'title': '任务完成率' }
|
||||
,{field:'admin_name',title: '创建人',width:80,align:'center'}
|
||||
,{field:'create_time', title: '创建时间',width:150,align:'center'}
|
||||
,{width:120,fixed:'right',title: '操作', align:'center',ignoreExport:true,templet: function(d){
|
||||
var html='';
|
||||
var btn1='<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详细</a>';
|
||||
var btn2='<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>';
|
||||
var btn3='<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>';
|
||||
if(d.status==3){
|
||||
btn2='';
|
||||
btn3='<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="affirm">反确认完成</a>';
|
||||
}
|
||||
if(auth == 1 || d.admin_id == login_admin || d.director_uid == login_admin){
|
||||
return '<div class="layui-btn-group">'+btn1+btn2+btn3+'</div>';
|
||||
}
|
||||
else{
|
||||
return btn1
|
||||
}
|
||||
}}
|
||||
]]
|
||||
});
|
||||
|
||||
table.on('tool(table_project)',function (obj) {
|
||||
var checkStatus = table.checkStatus(obj.config.id); //获取选中行状态
|
||||
var data = obj.data;
|
||||
if (obj.event === 'view') {
|
||||
tool.side("/project/index/view?id="+data.id);
|
||||
return;
|
||||
}
|
||||
if (obj.event === 'edit') {
|
||||
tool.side("/project/index/add?id="+data.id);
|
||||
return;
|
||||
}
|
||||
if (obj.event === 'affirm') {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if(e.code==0){
|
||||
layui.pageTable.reload();
|
||||
}
|
||||
}
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: '请输入反确认的原因或理由',
|
||||
area: ['500px', '252px'],
|
||||
content: '<div style="padding:5px;"><textarea class="layui-textarea" id="remarkTextarea" style="width: 100%; height:132px;"></textarea></div>',
|
||||
btnAlign: 'c',
|
||||
btn: ['确认操作'],
|
||||
yes: function (index) {
|
||||
let remark = $("#remarkTextarea").val();
|
||||
if (remark != '') {
|
||||
tool.post("/project/api/step_check", {id: data.id,check:3,content:remark}, callback);
|
||||
layer.close(index);
|
||||
} else {
|
||||
layer.msg('请输入原因或理由');
|
||||
}
|
||||
}
|
||||
})
|
||||
return;
|
||||
}
|
||||
if (obj.event === 'del') {
|
||||
layer.confirm('确定要删除该项目吗?', { icon: 3, title: '提示' }, function (index) {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
obj.del();
|
||||
}
|
||||
}
|
||||
tool.delete("/project/index/del", { id: data.id }, callback);
|
||||
layer.close(index);
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /脚本 -->
|
||||
@@ -0,0 +1,297 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
<!-- 主体 -->
|
||||
{block name="body"}
|
||||
<form class="layui-form p-page">
|
||||
<h3 class="pb-3">编辑项目</h3>
|
||||
<table class="layui-table layui-table-form">
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目名称<font>*</font></td>
|
||||
<td colspan="3"><input type="text" name="name" lay-verify="required" lay-reqText="请输入项目名称" placeholder="请输入项目名称" class="layui-input" value="{$detail.name}"></td>
|
||||
<td class="layui-td-gray">项目类别<font>*</font></td>
|
||||
<td>
|
||||
<select name="cate_id" lay-verify="required" lay-reqText="请选择项目类别">
|
||||
<option value="">请选择</option>
|
||||
{volist name = ":get_base_data('ProjectCate')" id="vo"}
|
||||
<option value="{$vo.id}" {eq name="$vo.id" value="$detail.cate_id"} selected{/eq}>{$vo.title}</option>
|
||||
{/volist}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目经理<font>*</font></td>
|
||||
<td>
|
||||
<input type="text" name="director_name" placeholder="请选择项目经理(负责人)" readonly class="layui-input" value="{$detail.director_name}" lay-verify="required" readonly lay-reqText="请选择项目经理(负责人)">
|
||||
<input type="hidden" name="director_uid" value="{$detail.director_uid}">
|
||||
<input type="hidden" name="did" value="{$detail.did}">
|
||||
</td>
|
||||
<td class="layui-td-gray">归属部门<font>*</font></td>
|
||||
<td><input type="text" name="department" value="{$detail.department}" autocomplete="off" readonly class="layui-input"></td>
|
||||
<td class="layui-td-gray">始止日期<span style="color: red">*</span></td>
|
||||
<td><input type="text" name="range_time" value="{$detail.start_time|date='Y-m-d'} 到 {$detail.end_time|date='Y-m-d'}" class="layui-input tool-time" data-range="到" readonly placeholder="开始 到 结束" lay-verify="required" lay-reqText="请选择计划完成周期"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">关联合同</td>
|
||||
<td colspan="5">
|
||||
<input type="text" class="layui-input picker-oa" data-types="contract" name="contract_name" placeholder="请选择需要关联的合同" readonly value="{$detail.contract_name|default=''}">
|
||||
<input type="hidden" class="layui-input" name="contract_id" value="{$detail.contract_id}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目简介</td>
|
||||
<td colspan="5">
|
||||
<textarea name="content" class="layui-textarea">{$detail.content|default=''}</textarea>
|
||||
</td>
|
||||
</tr>
|
||||
{lt name="$detail.status" value="3"}
|
||||
<tr>
|
||||
<td colspan="6" style="background-color:#FAFAFA;"><strong>项目阶段</strong><span style="color: red">*</span> <span class="layui-btn layui-btn-xs" id="stepAdd">+ 添加阶段</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6">
|
||||
<table id="stepTable" class="layui-table layui-table-min" style="margin:0">
|
||||
<tr>
|
||||
<th width="60">序号</th>
|
||||
<th width="180">阶段名称</th>
|
||||
<th width="80">阶段负责人</th>
|
||||
<th width="180">阶段成员</th>
|
||||
<th width="162">阶段周期</th>
|
||||
<th>阶段说明</th>
|
||||
<th width="120">操作</th>
|
||||
</tr>
|
||||
{volist name="$detail.step_array" id="vo" key="k"}
|
||||
{egt name="$vo.sort" value="$detail.current_step"}
|
||||
<tr class="step-tr">
|
||||
<td class="step-key">第 <strong>{$k}</strong> 阶段</td>
|
||||
<td>
|
||||
<div class="layui-input-group">
|
||||
<input type="text" name="step_title[]" value="{$vo.title}" class="layui-input" lay-verify="required" lay-reqText="请输入阶段名称">
|
||||
<div class="layui-input-split layui-input-suffix picker-diy" style="cursor: pointer;"><i class="layui-icon layui-icon-search"></i></div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" value="{$vo.director_name}" class="layui-input layui-input-readonly picker-admin" lay-verify="required" lay-reqText="请选择阶段负责人" readonly>
|
||||
<input type="hidden" name="step_director_uid[]" value="{$vo.director_uid}" readonly>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" value="{$vo.unames}" class="layui-input layui-input-readonly picker-admin" data-type="2">
|
||||
<input type="hidden" name="step_uids[]" value="{$vo.uids}">
|
||||
</td>
|
||||
<td><input type="text" name="step_cycle_time[]" value="{$vo.start_time|date='Y-m-d'} 到 {$vo.end_time|date='Y-m-d'}" class="layui-input layui-input-readonly tool-time" data-range="到" lay-verify="required" lay-reqText="请选择阶段周期" readonly></td>
|
||||
<td><input type="text" name="step_remark[]" value="{$vo.remark|default=''}" class="layui-input"></td>
|
||||
<td>
|
||||
<input type="hidden" name="step_id[]" value="{$vo.id}" class="layui-input">
|
||||
<div class="layui-btn-group">
|
||||
<span class="layui-btn layui-btn-xs step-up">上移</span>
|
||||
<span class="layui-btn layui-btn-normal layui-btn-xs step-down">下移</span>
|
||||
<span class="layui-btn layui-btn-danger layui-btn-xs step-del" data-id="{$vo.id}">删除</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{else/}
|
||||
<tr>
|
||||
<td class="step-key">第 <strong>{$k}</strong> 阶段</td>
|
||||
<td><input type="text" name="step_title[]" value="{$vo.title}" class="layui-input layui-input-readonly" readonly lay-verify="required" lay-reqText="请输入阶段名称"></td>
|
||||
<td>
|
||||
<input type="text" value="{$vo.director_name}" class="layui-input layui-input-readonly" lay-verify="required" lay-reqText="请选择阶段负责人" readonly>
|
||||
<input type="hidden" name="step_director_uid[]" value="{$vo.director_uid}" readonly>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" value="{$vo.unames}" class="layui-input layui-input-readonly" data-type="2">
|
||||
<input type="hidden" name="step_uids[]" value="{$vo.uids}">
|
||||
</td>
|
||||
<td><input type="text" name="step_cycle_time[]" value="{$vo.start_time|date='Y-m-d'} 到 {$vo.end_time|date='Y-m-d'}" class="layui-input layui-input-readonly" data-range="到" lay-verify="required" lay-reqText="请选择阶段周期" readonly></td>
|
||||
<td><input type="text" name="step_remark[]" value="{$vo.remark|default=''}" readonly class="layui-input layui-input-readonly"></td>
|
||||
<td>
|
||||
<input type="hidden" name="step_id[]" value="{$vo.id}" class="layui-input">
|
||||
-
|
||||
</td>
|
||||
</tr>
|
||||
{/egt}
|
||||
{/volist}
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
{/lt}
|
||||
</table>
|
||||
<div class="pt-3">
|
||||
<input type="hidden" name="id" value="{$detail.id|default=0}"/>
|
||||
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
|
||||
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
|
||||
</div>
|
||||
</form>
|
||||
{/block}
|
||||
<!-- /主体 -->
|
||||
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script>
|
||||
var moduleInit = ['tool','oaPicker'];
|
||||
|
||||
function gouguInit() {
|
||||
var form = layui.form, tool = layui.tool,oaPicker = layui.oaPicker;
|
||||
//选择项目经理
|
||||
$('body').on('click','[name="director_name"]',function () {
|
||||
var ids=$('[name="director_uid"]').val(),names=$('[name="director_name"]').val();
|
||||
oaPicker.employeeInit({
|
||||
ids:ids,
|
||||
names:names,
|
||||
type:1,
|
||||
callback:function(data){
|
||||
let select_id=[],select_name=[],select_did=[],select_dname=[];
|
||||
for(var a=0; a<data.length;a++){
|
||||
select_id.push(data[a].id);
|
||||
select_name.push(data[a].name);
|
||||
select_did.push(data[a].did);
|
||||
select_dname.push(data[a].department);
|
||||
}
|
||||
$('[name="director_uid"]').val(select_id.join(','));
|
||||
$('[name="director_name"]').val(select_name.join(','));
|
||||
$('[name="did"]').val(select_did.join(','));
|
||||
$('[name="department"]').val(select_dname.join(','));
|
||||
}
|
||||
});
|
||||
});
|
||||
//添加阶段信息表格
|
||||
$('#stepAdd').on('click',function(){
|
||||
var html = '';
|
||||
html += '<tr class="step-tr">\
|
||||
<td class="step-key">第 <strong>0</strong> 阶段</td>\
|
||||
<td>\
|
||||
<div class="layui-input-group">\
|
||||
<input type="text" name="step_title[]" value="" class="layui-input" lay-verify="required" lay-reqText="请输入阶段名称">\
|
||||
<div class="layui-input-split layui-input-suffix picker-diy" style="cursor: pointer;"><i class="layui-icon layui-icon-search"></i></div>\
|
||||
</div>\
|
||||
</td>\
|
||||
<td>\
|
||||
<input type="text" value="" class="layui-input layui-input-readonly picker-admin" lay-verify="required" lay-reqText="请选择阶段负责人" readonly>\
|
||||
<input type="hidden" name="step_director_uid[]" value="0" readonly>\
|
||||
</td>\
|
||||
<td>\
|
||||
<input type="text" value="" class="layui-input layui-input-readonly picker-admin" data-type="2">\
|
||||
<input type="hidden" name="step_uids[]" value="">\
|
||||
</td>\
|
||||
<td><input type="text" name="step_cycle_time[]" value="" class="layui-input layui-input-readonly tool-time" data-range="到" lay-verify="required" lay-reqText="请选择服务周期" readonly></td>\
|
||||
<td><input type="text" name="step_remark[]" value="" class="layui-input"></td>\
|
||||
<td>\
|
||||
<input type="hidden" name="step_id[]" value="0" class="layui-input">\
|
||||
<div class="layui-btn-group">\
|
||||
<span class="layui-btn layui-btn-xs step-up">上移</span>\
|
||||
<span class="layui-btn layui-btn-normal layui-btn-xs step-down">下移</span>\
|
||||
<span class="layui-btn layui-btn-danger layui-btn-xs step-del" data-id="0">删除</span>\
|
||||
</div>\
|
||||
</td>\
|
||||
</tr>';
|
||||
$('#stepTable').append(html).find('.tr-none').remove();
|
||||
$('#stepTable').find('.step-key').each(function(index,item){
|
||||
$(this).html('第 <strong>'+(index+1)+'</strong> 阶段');
|
||||
})
|
||||
form.render();
|
||||
});
|
||||
$('#stepTable').on('click','.layui-btn-danger',function(){
|
||||
if($('.step-tr').length<2){
|
||||
layer.msg('至少保留一个项目阶段');
|
||||
return false;
|
||||
}
|
||||
let that=$(this);
|
||||
let id = that.data('id');
|
||||
if(id==0){
|
||||
that.parents('.step-tr').remove();
|
||||
$('#stepTable').find('.step-key').each(function(index,item){
|
||||
$(this).html('第 <strong>'+(index+1)+'</strong> 阶段');
|
||||
})
|
||||
}
|
||||
else{
|
||||
layer.confirm('确定要删除该项目阶段吗?', { icon: 3, title: '提示' }, function (index) {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
that.parents('.step-tr').remove();
|
||||
$('#stepTable').find('.step-key').each(function(index,item){
|
||||
$(this).html('第 <strong>'+(index+1)+'</strong> 阶段');
|
||||
})
|
||||
}
|
||||
}
|
||||
tool.delete("/project/api/step_del", { id: id }, callback);
|
||||
layer.close(index);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('#stepTable').on('click','.step-up',function(e){
|
||||
let obj = $(e.target).closest('tr');
|
||||
tr_pre($(obj[0]));
|
||||
})
|
||||
|
||||
$('#stepTable').on('click','.step-down',function(e){
|
||||
var obj = $(e.target).closest('tr');
|
||||
tr_next($(obj[0]));
|
||||
})
|
||||
|
||||
|
||||
function tr_pre(o) {
|
||||
var pres = o.prevAll('tr.step-tr');
|
||||
if (pres.length > 0) {
|
||||
var tmp = o.clone(true);
|
||||
var oo = pres[0];
|
||||
o.remove();
|
||||
$(oo).before(tmp);
|
||||
$('#stepTable').find('.step-key').each(function(index,item){
|
||||
$(this).html('第 <strong>'+(index+1)+'</strong> 阶段');
|
||||
})
|
||||
}
|
||||
else{
|
||||
layer.msg('已经第一个了');
|
||||
}
|
||||
}
|
||||
|
||||
function tr_next(o) {
|
||||
var nexts = o.nextAll('tr.step-tr');
|
||||
if (nexts.length > 0) {
|
||||
var tmp = o.clone(true);
|
||||
var oo = nexts[0];
|
||||
o.remove();
|
||||
$(oo).after(tmp);
|
||||
$('#stepTable').find('.step-key').each(function(index,item){
|
||||
$(this).html('第 <strong>'+(index+1)+'</strong> 阶段');
|
||||
})
|
||||
}else{
|
||||
layer.msg('已经最后一个了');
|
||||
}
|
||||
}
|
||||
|
||||
$('body').on('click','.picker-diy',function () {
|
||||
let that = $(this),ids = [],titles=[],map = {};
|
||||
let callback = function(data){
|
||||
for ( var i = 0; i <data.length; i++){
|
||||
ids.push(data[i].id);
|
||||
titles.push(data[i].title);
|
||||
}
|
||||
that.prev().val(titles.join(','));
|
||||
}
|
||||
let opts={
|
||||
"title":"选择项目阶段",
|
||||
"url": "/project/api/get_project_step",
|
||||
"ids":"",
|
||||
"titles":"",
|
||||
"area": ['600px', '580px'],
|
||||
"cols":[{field: 'id',width: 80,title:'序号',align:'center'},{field:'title',title:'项目阶段'}]
|
||||
}
|
||||
oaPicker.picker(opts,1,callback,map);//单选
|
||||
});
|
||||
|
||||
//监听提交
|
||||
form.on('submit(webform)', function (data) {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
tool.sideClose(1000);
|
||||
}
|
||||
}
|
||||
let clickbtn = $(this);
|
||||
tool.post("/project/index/add", data.field, callback,clickbtn);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /脚本 -->
|
||||
@@ -0,0 +1,552 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
{block name="style"}
|
||||
<style>
|
||||
.layui-tab-title .layui-this{background-color:#fff;}
|
||||
.layui-tab-card,.layui-card{box-shadow:0 0 0 0 rgb(0 0 0 / 10%); border-radius:0;}
|
||||
.layui-card-tips {color: #969696;}
|
||||
.layui-card-value {padding: 4px 0 5px;font-size: 18px;color: #1E9FFF;}
|
||||
|
||||
.check-items{overflow-x: auto; padding: 2px 0;}
|
||||
|
||||
.check-item .check-item-icon strong{margin-right:3px; font-size:36px;}
|
||||
.check-item strong.blue,.check-item strong.gray{display:none;}
|
||||
.check-item.blue strong.black,.check-item.gray strong.black{display:none;}
|
||||
.check-item.blue strong.blue{display:block;}
|
||||
.check-item.gray strong.gray{display:block;}
|
||||
|
||||
.flow-flex-row {box-direction: row;
|
||||
box-orient: horizontal;
|
||||
-webkit-box-orient: horizontal;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
}
|
||||
.flow-flexbox { width: 100%;text-align: left;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
display: -webkit-flex;
|
||||
box-align: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.check-item{width: auto; -ms-flex-negative: 0; flex-shrink: 0; padding:8px 0;}
|
||||
.check-item i{font-size:20px; margin-right:3px;}
|
||||
.layui-icon[data-ok]{color:#34a853}
|
||||
.layui-icon[data-no]{color:#FF5722;}
|
||||
.layui-icon[data-on]{color:#4285f4;}
|
||||
.check-item-time{color:#969696; font-size:12px; margin-left:3px;}
|
||||
.check-item .layui-icon.layui-icon-right{font-size:20px;}
|
||||
.check-item:last-child .layui-icon-right{display:none;}
|
||||
.file-card{line-height:normal;}
|
||||
</style>
|
||||
{/block}
|
||||
<!-- 主体 -->
|
||||
{block name="body"}
|
||||
<div class="p-page">
|
||||
<h2 class="pb-3">
|
||||
<span class="font20">{$detail.name}</span>
|
||||
{gt name="$role" value="0"}
|
||||
{eq name="$detail.status" value="4"}
|
||||
<span class="layui-btn layui-btn-xs" data-event="open">开启</span>
|
||||
{else/}
|
||||
<span class="layui-btn layui-btn-danger layui-btn-xs" data-event="close">关闭</span>
|
||||
{/eq}
|
||||
{/gt}
|
||||
</h2>
|
||||
<div class="pb-2">
|
||||
<span class="layui-badge layui-bg-gray">#T{$detail.id}</span>
|
||||
<span class="mx-2">{$detail.admin_name}</span>
|
||||
<span class="gray">创建于{$detail.create_time}<span>{gt name="$detail.update_time" value="0"},最近更新于 {$detail.update_time}{/gt}</span></span>
|
||||
</div>
|
||||
<div class="layui-tabs layui-tab-brief" id="projectTab">
|
||||
<ul class="layui-tabs-header border-t border-x bg-white">
|
||||
<li class="layui-this" data-load="true">项目概览</li>
|
||||
<li data-load="">项目任务</li>
|
||||
<li data-load="">工作记录</li>
|
||||
<li data-load="">项目文档</li>
|
||||
<li data-load="">项目人员</li>
|
||||
<li data-load="">项目动态</li>
|
||||
<li data-load="">项目评论</li>
|
||||
</ul>
|
||||
<div class="layui-tabs-body" style="padding:0">
|
||||
<div class="layui-tabs-item layui-show">
|
||||
{include file="/index/view_overview" /}
|
||||
</div>
|
||||
|
||||
<div class="layui-tabs-item">
|
||||
{include file="/index/view_task" /}
|
||||
</div>
|
||||
|
||||
<div class="layui-tabs-item">
|
||||
{include file="/index/view_schedule" /}
|
||||
</div>
|
||||
|
||||
<div class="layui-tabs-item">
|
||||
{include file="/index/view_document" /}
|
||||
</div>
|
||||
|
||||
<div class="layui-tabs-item">
|
||||
{include file="/index/view_user" /}
|
||||
</div>
|
||||
|
||||
<div class="layui-tabs-item">
|
||||
{include file="/index/view_log" /}
|
||||
</div>
|
||||
|
||||
<div class="layui-tabs-item">
|
||||
{include file="/index/view_comment" /}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
<!-- /主体 -->
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script src="{__GOUGU__}/third_party/echart/echarts.min.js"></script>
|
||||
<script>
|
||||
const project_id = '{$detail.id}';
|
||||
const project_start_time = "{$detail.start_time|date='Y-m-d'}";
|
||||
var chartProgress = document.getElementById('progress');
|
||||
var progressChart = echarts.init(chartProgress);
|
||||
var optionA;
|
||||
optionA = {
|
||||
backgroundColor: "#ffffff",
|
||||
title: {
|
||||
text: '67.45%',//主标题文本
|
||||
subtext: '任务完成率',//副标题文本
|
||||
x: 'center',
|
||||
y: '39%',
|
||||
textStyle: {
|
||||
fontWeight: 'normal',
|
||||
fontSize: 18,
|
||||
color: '#FF974C',
|
||||
align: 'center'
|
||||
},
|
||||
subtextStyle: {
|
||||
fontSize: 12,
|
||||
color: '#6c7a89',
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "item",
|
||||
formatter: '{b}:<br/><strong>{c}</strong>',
|
||||
show: true,
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['60%', '80%'],
|
||||
center: ['50%', '50%'],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{ value: 1048, name: '待处理' },
|
||||
{ value: 735, name: '已完成' }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
var chartDelay = document.getElementById('delay');
|
||||
var delayChart = echarts.init(chartDelay);
|
||||
var optionB;
|
||||
optionB = {
|
||||
backgroundColor: "#ffffff",
|
||||
title: {
|
||||
text: '40.25%',//主标题文本
|
||||
subtext: '任务延迟率',//副标题文本
|
||||
x: 'center',
|
||||
y: '39%',
|
||||
textStyle: {
|
||||
fontWeight: 'normal',
|
||||
fontSize: 18,
|
||||
color: '#FF974C',
|
||||
align: 'center',
|
||||
marginLeft: '-10px'
|
||||
},
|
||||
subtextStyle: {
|
||||
fontSize: 12,
|
||||
color: '#6c7a89',
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "item",
|
||||
formatter: '{b}:<br/><strong>{c}</strong>',
|
||||
show: true,
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['60%', '80%'],
|
||||
center: ['50%', '50%'],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
data: [{
|
||||
value: 1048,
|
||||
name: '延迟',
|
||||
itemStyle: {
|
||||
color: "#ED6666",
|
||||
}
|
||||
},
|
||||
{
|
||||
value: 735,
|
||||
name: '未延迟',
|
||||
itemStyle: {
|
||||
color: "#91CC75",
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
var chartCross = document.getElementById('cross');
|
||||
var crossChart = echarts.init(chartCross);
|
||||
var optionD;
|
||||
optionD = {
|
||||
backgroundColor: "#ffffff",
|
||||
color: ['#8C92A4', '#2C7EF8'],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross',
|
||||
label: {
|
||||
backgroundColor: '#6a7985'
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: ['任务计划剩余', '任务实际剩余']
|
||||
},
|
||||
grid: {
|
||||
top: 36,
|
||||
left: 8,
|
||||
right: 36,
|
||||
bottom: 0,
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
type: 'dashed'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
yAxis: [{
|
||||
axisLine: {
|
||||
show: true
|
||||
},
|
||||
boundaryGap: false,
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
type: 'dashed'
|
||||
}
|
||||
},
|
||||
type: 'value'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
var chartPlan = document.getElementById('plan');
|
||||
var planChart = echarts.init(chartPlan);
|
||||
var optionE;
|
||||
|
||||
optionE = {
|
||||
backgroundColor: "#ffffff",
|
||||
title: {
|
||||
top: 0,
|
||||
left: 0,
|
||||
text: ''
|
||||
},
|
||||
tooltip: {
|
||||
padding: 6,
|
||||
formatter: function (obj) {
|
||||
var value = obj.value;
|
||||
var tips = '<div style="font-size: 12px;">' + value[0] + '<br>';
|
||||
tips += '共 ' + value[1] + ' 个工作任务';
|
||||
tips += '</div>';
|
||||
return tips;
|
||||
}
|
||||
},
|
||||
visualMap: {
|
||||
min: 0,
|
||||
max: 10,
|
||||
show: false,
|
||||
inRange: {
|
||||
color: ['#fafafa', '#20BF3F']
|
||||
}
|
||||
},
|
||||
calendar: {
|
||||
top: 24,
|
||||
left: 36,
|
||||
right: 4,
|
||||
cellSize: ['auto', 16],
|
||||
range: ['2022-03-01', '2022-08-01'],
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: '#333',
|
||||
type: 'dashed',
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
borderWidth: 0.5
|
||||
},
|
||||
yearLabel: { show: false },
|
||||
monthLabel: {
|
||||
nameMap: 'cn',
|
||||
fontSize: 12
|
||||
},
|
||||
dayLabel: {
|
||||
show: true,
|
||||
formatter: '{start} 1st',
|
||||
fontWeight: 'lighter',
|
||||
nameMap: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
|
||||
fontSize: 12
|
||||
}
|
||||
},
|
||||
series: {
|
||||
type: 'heatmap',
|
||||
coordinateSystem: 'calendar',
|
||||
data: []
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var chartWork = document.getElementById('work');
|
||||
var workChart = echarts.init(chartWork);
|
||||
var optionF;
|
||||
|
||||
optionF = {
|
||||
backgroundColor: "#ffffff",
|
||||
title: {
|
||||
top: 0,
|
||||
left: 0,
|
||||
text: ''
|
||||
},
|
||||
tooltip: {
|
||||
padding: 6,
|
||||
formatter: function (obj) {
|
||||
var value = obj.value;
|
||||
var tips = '<div style="font-size: 12px;">' + value[0] + '<br>';
|
||||
tips += '共 ' + value[1] + ' 个工时';
|
||||
tips += '</div>';
|
||||
return tips;
|
||||
}
|
||||
},
|
||||
visualMap: {
|
||||
min: 0,
|
||||
max: 10,
|
||||
show: false,
|
||||
inRange: {
|
||||
color: ['#fafafa', '#359AEF']
|
||||
}
|
||||
},
|
||||
calendar: {
|
||||
top: 24,
|
||||
left: 36,
|
||||
right: 4,
|
||||
cellSize: ['auto', 16],
|
||||
range: ['2022-03-01', '2022-08-01'],
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: '#333',
|
||||
type: 'dashed',
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
borderWidth: 0.5
|
||||
},
|
||||
yearLabel: { show: false },
|
||||
monthLabel: {
|
||||
nameMap: 'cn',
|
||||
fontSize: 12
|
||||
},
|
||||
dayLabel: {
|
||||
show: true,
|
||||
formatter: '{start} 1st',
|
||||
fontWeight: 'lighter',
|
||||
nameMap: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
|
||||
fontSize: 12
|
||||
}
|
||||
},
|
||||
series: {
|
||||
type: 'heatmap',
|
||||
coordinateSystem: 'calendar',
|
||||
data: []
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function getCalendarData(arr) {
|
||||
var rangeArray = [];
|
||||
for (var property in arr) {
|
||||
rangeArray.push(property);
|
||||
}
|
||||
var rangeArray = [rangeArray[0], rangeArray[rangeArray.length - 1]];
|
||||
var start = +echarts.number.parseDate(rangeArray[0]);
|
||||
var end = +echarts.number.parseDate(rangeArray[1]);
|
||||
if (start + 7776000000 > end) {
|
||||
end = start + 8640000000;
|
||||
rangeArray[1] = echarts.format.formatTime('yyyy-MM-dd', end);
|
||||
}
|
||||
var dayTime = 3600 * 24 * 1000;
|
||||
var data = [];
|
||||
for (var time = start; time < end; time += dayTime) {
|
||||
var this_date = echarts.format.formatTime('yyyy-MM-dd', time);
|
||||
if (arr[this_date]) {
|
||||
data.push([this_date, arr[this_date]]);
|
||||
} else {
|
||||
data.push([this_date, 0]);
|
||||
}
|
||||
}
|
||||
var res = { 'range': rangeArray, 'data': data };
|
||||
return res;
|
||||
}
|
||||
|
||||
//燃尽图统计
|
||||
function cross_count(arr, arr2) {
|
||||
var planArray = [], doArray = [];
|
||||
var today = new Date();
|
||||
var todayStr = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
|
||||
for (var a in arr) {
|
||||
planArray.push(a);
|
||||
}
|
||||
var rangeArray = [planArray[0], planArray[planArray.length - 1]];
|
||||
if (arr2 instanceof Array == false) {
|
||||
for (var b in arr2) {
|
||||
doArray.push(b);
|
||||
}
|
||||
if ((+echarts.number.parseDate(doArray[doArray.length - 1])) < (+echarts.number.parseDate(todayStr))) {
|
||||
doArray.push(todayStr);
|
||||
}
|
||||
if ((+echarts.number.parseDate(planArray[planArray.length - 1])) < (+echarts.number.parseDate(doArray[doArray.length - 1]))) {
|
||||
rangeArray[1] = doArray[doArray.length - 1];
|
||||
}
|
||||
}
|
||||
var start = +echarts.number.parseDate(rangeArray[0]);
|
||||
var end = +echarts.number.parseDate(rangeArray[1]);
|
||||
var todayInt = +echarts.number.parseDate(todayStr);
|
||||
var dayTime = 3600 * 24 * 1000;
|
||||
var xArray = [], yArray = [], yArray2 = [], done = 0, doneArray = [];
|
||||
for (var time = start; time <= end; time += dayTime) {
|
||||
var this_date = echarts.format.formatTime('yyyy-MM-dd', time);
|
||||
xArray.push(this_date);
|
||||
var plan = cross_recursion(time, end, arr);
|
||||
yArray.push(plan);
|
||||
|
||||
if (arr2[this_date]) {
|
||||
done += arr2[this_date];
|
||||
}
|
||||
if (time <= todayInt) {
|
||||
doneArray.push(done);
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < doneArray.length; i++) {
|
||||
yArray2.push(yArray[0] - doneArray[i]);
|
||||
}
|
||||
var start_time = +echarts.number.parseDate(project_start_time), tem_x_array = [], tem_y_array = [];
|
||||
if (start_time < start) {
|
||||
for (var tem_time = start_time; tem_time < start; tem_time += dayTime) {
|
||||
var this_date = echarts.format.formatTime('yyyy-MM-dd', tem_time);
|
||||
tem_x_array.push(this_date);
|
||||
tem_y_array.push(yArray[0]);
|
||||
}
|
||||
xArray = tem_x_array.concat(xArray);
|
||||
yArray = tem_y_array.concat(yArray);
|
||||
yArray2 = tem_y_array.concat(yArray2);
|
||||
}
|
||||
return { 'x': xArray, 'y': yArray, 'y2': yArray2 };
|
||||
}
|
||||
|
||||
function cross_recursion(start, end, arr) {
|
||||
var count = 0;
|
||||
var dayTime = 3600 * 24 * 1000;
|
||||
for (var time = start; time <= end; time += dayTime) {
|
||||
var this_date = echarts.format.formatTime('yyyy-MM-dd', time);
|
||||
if (arr[this_date]) {
|
||||
count += arr[this_date];
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
//
|
||||
const moduleInit = ['tool','oaPicker','uploadPlus','tablePlus','oaComment','oaSchedule','oaEdit'];
|
||||
|
||||
function gouguInit() {
|
||||
var tool = layui.tool,tabs = layui.tabs,comment = layui.oaComment;
|
||||
|
||||
comment.init({
|
||||
"box":'commentBox',//容器id
|
||||
"input": 'commentInput',
|
||||
"topic_id":project_id,
|
||||
"module": 'project',
|
||||
});
|
||||
|
||||
$('body').on('click','[data-event="close"]',function(){
|
||||
tool.ask('确定要关闭该项目?',function(){
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if(e.code==0){
|
||||
parent.layui.pageTable.reload();
|
||||
setTimeout(function(){
|
||||
location.reload();
|
||||
},2000)
|
||||
}
|
||||
}
|
||||
tool.post("/project/api/close", { 'id': project_id}, callback);
|
||||
})
|
||||
})
|
||||
$('body').on('click','[data-event="open"]',function(){
|
||||
tool.ask('确定要开启该项目?',function(){
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if(e.code==0){
|
||||
parent.layui.pageTable.reload();
|
||||
setTimeout(function(){
|
||||
location.reload();
|
||||
},2000)
|
||||
}
|
||||
}
|
||||
tool.post("/project/api/open", { 'id': project_id}, callback);
|
||||
})
|
||||
})
|
||||
|
||||
overview();
|
||||
tabs.on('afterChange(projectTab)', function(data){
|
||||
let index = data.index;
|
||||
if(index == 1){
|
||||
project_task();
|
||||
}
|
||||
else if(index == 2){
|
||||
project_schedule();
|
||||
}
|
||||
else if(index == 3){
|
||||
project_document();
|
||||
}
|
||||
else if(index == 4){
|
||||
project_user();
|
||||
}
|
||||
else if(index == 5){
|
||||
project_log();
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /脚本 -->
|
||||
@@ -0,0 +1,6 @@
|
||||
<div class="px-3 pt-3 border bg-white">
|
||||
<div class="comment-input">
|
||||
<input type="text" id="commentInput" readonly placeholder="发表一下你的看法" class="layui-input" value="">
|
||||
</div>
|
||||
<div id="commentBox" class="pt-3"></div>
|
||||
</div>
|
||||
@@ -0,0 +1,86 @@
|
||||
<div class="bg-white">
|
||||
<table class="layui-hide" id="document" lay-filter="document"></table>
|
||||
</div>
|
||||
<script type="text/html" id="toolbardocument">
|
||||
<div class="layui-btn-container">
|
||||
<button class="layui-btn layui-btn-sm" lay-event="add">+ 新建文档</button>
|
||||
</div>
|
||||
</script>
|
||||
<script>
|
||||
function project_document(){
|
||||
if($('#projectTab').find('li').eq(3).data('load') =='true'){
|
||||
return false;
|
||||
}
|
||||
$('#projectTab').find('li').eq(3).data('load','true');
|
||||
let tool = layui.tool, table = layui.tablePlus;
|
||||
//项目任务
|
||||
parent.layui.documentTable = table.render({
|
||||
elem: '#document',
|
||||
title: '文档列表',
|
||||
toolbar: '#toolbardocument',
|
||||
cellMinWidth:80,
|
||||
url: "/project/document/datalist",
|
||||
where:{'project_id':project_id},
|
||||
page: true, //开启分页
|
||||
limit: 20,
|
||||
cols: [[
|
||||
{field: 'id', title: '文档编号', width: 80, align: 'center', templet: function (d) {
|
||||
return 'D' + d.id;
|
||||
}
|
||||
}
|
||||
,{field: 'title', title: '文档主题'}
|
||||
,{field:'admin_name',title: '创建人', align:'center',width: 80}
|
||||
,{field:'create_time',title: '创建时间', align:'center', width: 150}
|
||||
,{
|
||||
field: 'right',
|
||||
fixed:'right',
|
||||
title: '操作',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
templet: function (d) {
|
||||
var html = '<div class="layui-btn-group">';
|
||||
var btn1='<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详细</a>'
|
||||
var btn2='<span class="layui-btn layui-btn-xs" lay-event="edit">编辑</span>';
|
||||
var btn3='<span class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</span>';
|
||||
return html+btn1+btn2+btn3+'</div>';
|
||||
}
|
||||
}
|
||||
]]
|
||||
});
|
||||
|
||||
//触发事件
|
||||
table.on('toolbar(document)', function(obj){
|
||||
if (obj.event === 'add') {
|
||||
tool.side('/project/document/add?project_id='+project_id);
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
table.on('tool(document)', function(obj){
|
||||
var data = obj.data; //获得当前行数据
|
||||
if(obj.event === 'view'){ //查看
|
||||
let url = '/project/document/view/id/'+data.id;
|
||||
tool.side(url);
|
||||
}
|
||||
if(obj.event === 'edit'){
|
||||
tool.side('/project/document/add?id='+data.id);
|
||||
return;
|
||||
}
|
||||
if (obj.event === 'del') {
|
||||
layer.confirm('确定要删除吗?', {
|
||||
icon: 3,
|
||||
title: '提示'
|
||||
}, function(index) {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
obj.del();
|
||||
}
|
||||
}
|
||||
tool.delete("/project/document/delete", {id: data.id}, callback);
|
||||
layer.close(index);
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,9 @@
|
||||
<div class="border">
|
||||
<div id="logList" class="log-timeline p-3"></div>
|
||||
</div>
|
||||
<script>
|
||||
function project_log(){
|
||||
let oaEdit = layui.oaEdit;
|
||||
oaEdit.log('logList','Project',project_id);
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,415 @@
|
||||
<table class="layui-table layui-table-form">
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目状态</td>
|
||||
<td><span class="check-status-color-{$detail.status}">『{$detail.status_name}』</span></td>
|
||||
<td class="layui-td-gray">项目类别</td>
|
||||
<td>{$detail.cate}</td>
|
||||
<td class="layui-td-gray">始止日期</td>
|
||||
<td>{$detail.start_time|date='Y-m-d'} 到 {$detail.end_time|date='Y-m-d'}</td>
|
||||
<td class="layui-td-gray">所属部门</td>
|
||||
<td>{$detail.department|default='-'}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目经理</td>
|
||||
<td>{$detail.director_name}</td>
|
||||
<td class="layui-td-gray">项目成员</td>
|
||||
<td colspan="5">{$detail.team_admin_names|default='-'}</td>
|
||||
</tr>
|
||||
{gt name="$detail.contract_id" value="0"}
|
||||
<tr>
|
||||
<td class="layui-td-gray">关联合同</td>
|
||||
<td colspan="7">{$detail.contract_name}</td>
|
||||
</tr>
|
||||
{/gt}
|
||||
{notempty name="$detail.content"}
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目简介</td>
|
||||
<td colspan="7">{$detail.content}</td>
|
||||
</tr>
|
||||
{/notempty}
|
||||
</table>
|
||||
|
||||
<div class="layui-card border" style="margin-top:16px;">
|
||||
<div class="layui-card-header" style="height:43px; line-height:43px;">
|
||||
<strong>项目阶段</strong>
|
||||
</div>
|
||||
<div class="px-3 py-1 border-b">
|
||||
<div class="flow-flexbox check-items flow-flex-row">
|
||||
{volist name="$detail.step_array" id="vo"}
|
||||
<div class='flow-flexbox flow-flex-row check-item {eq name="$vo.is_current" value="1"} blue{/eq} {notempty name="$step"}{lt name="$vo.sort" value="$step.sort"} gray{/lt}{else/} gray{/notempty}'>
|
||||
<div class="check-item-icon">
|
||||
<strong class="iconfont icon-bianji blue"></strong>
|
||||
<strong class="iconfont icon-kaoheguanli gray"></strong>
|
||||
<strong class="iconfont icon-genjinjilu black"></strong>
|
||||
</div>
|
||||
<div>
|
||||
<div class="check-item-name"><strong class="f16">{$vo.title}</strong> {$vo.director_name|default=''}</div>
|
||||
<div class="check-item-time">{$vo.start_time|date='Y-m-d'} 到 {$vo.end_time|date='Y-m-d'}</div>
|
||||
</div>
|
||||
<div class="layui-icon layui-icon-right"></div>
|
||||
</div>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
{notempty name="$step"}
|
||||
<div class="p-3 border-b">
|
||||
<div>
|
||||
<span class="gray">当前阶段:</span>{$step.title}
|
||||
<span class="gray" style="margin-left:20px">阶段周期:</span>{$step.start_time|date='Y-m-d'} 到 {$step.end_time|date='Y-m-d'}
|
||||
<span class="gray" style="margin-left:20px">负责人:</span>{$step.director_name}
|
||||
{eq name="$step.director_uid" value="$login_admin.id"}
|
||||
<span class="layui-btn layui-btn-normal layui-btn-xs" data-event="step" data-check="1">确认完成</span>
|
||||
<span class="layui-btn layui-btn-danger layui-btn-xs" data-event="step" data-check="2">退回上一阶段</span>
|
||||
{/eq}
|
||||
</div>
|
||||
{notempty name="$step.unames"}
|
||||
<div class="pt-2">
|
||||
<span class="gray">阶段成员:</span>{$step.unames|default=''}
|
||||
</div>
|
||||
{/notempty}
|
||||
{notempty name="$step.remark"}
|
||||
<div class="pt-2">
|
||||
<span class="gray">阶段说明:</span>{$step.remark|default=''}
|
||||
</div>
|
||||
{/notempty}
|
||||
</div>
|
||||
{/notempty}
|
||||
<div class="p-3">
|
||||
<p><strong>阶段流转记录</strong></p>
|
||||
{notempty name="$step_record"}
|
||||
<ul class="layui-timeline pt-2">
|
||||
{volist name="$step_record" id="vo"}
|
||||
<li class="layui-timeline-item delete_{$vo.delete_time}">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
{if ($vo.status == 1)}
|
||||
<p style="padding-left:24px">{$vo.check_time_str}<span class="black mx-1">{$vo.check_name}</span><span class="mr-1 green">{$vo.status_str}</span>了『{$vo.title}』的工作。操作意见:<span class="green">{$vo.content|default='-'}</span></p>
|
||||
{else /}
|
||||
<p style="padding-left:24px">{$vo.check_time_str}<span class="black mx-1">{$vo.check_name}</span>在阶段『{$vo.title}』执行了<span class="mx-1 red">{$vo.status_str}</span>操作。操作意见:<span class="red">{$vo.content|default='-'}</span></p>
|
||||
{/if}
|
||||
</li>
|
||||
{/volist}
|
||||
</ul>
|
||||
{else/}
|
||||
<div class="layui-data-none">暂无阶段流转记录</div>
|
||||
{/notempty}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card border">
|
||||
<div class="layui-card-header" style="height:45px; line-height:45px;">
|
||||
<strong>项目附件</strong>
|
||||
<button type="button" class="layui-btn layui-btn-xs" id="uploadBtn">上传附件</button>
|
||||
</div>
|
||||
<div class="layui-row p-2" id="uploadBox">
|
||||
{volist name="file_array" id="vo"}
|
||||
<div class="layui-col-md4" id="fileItem{$vo.id}">{:file_card($vo)}</div>
|
||||
{/volist}
|
||||
{empty name="$file_array" }
|
||||
<div class="layui-data-none">暂无项目附件</div>
|
||||
{/empty}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-row mb-4 border">
|
||||
<div class="layui-col-xs6 layui-col-md3">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header" style="height:45px; line-height:45px;">
|
||||
<strong>项目概况</strong>
|
||||
</div>
|
||||
<div class="p-3">
|
||||
<dl>
|
||||
<dt>任务 <span class="gray">(已完成/全部)</span></dt>
|
||||
<dd class="layui-card-value" title="已完成/总任务">{$detail.tasks_finish} / {$detail.tasks}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="pt-2 px-3">
|
||||
<dl>
|
||||
<dt>项目工时 <span class="gray">(实际/计划)</span></dt>
|
||||
<dd class="layui-card-value" title="实际工时/计划工时">{$detail.hours} / {$detail.plan_hours}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="pt-2 px-3">
|
||||
<dl>
|
||||
<dt>工作记录</dt>
|
||||
<dd class="layui-card-value" title="工作记录数">{$detail.schedules}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-xs6 layui-col-md9">
|
||||
<div class="layui-card border-l">
|
||||
<div class="layui-card-header" style="height:45px; line-height:45px;">
|
||||
<strong>项目进度</strong>
|
||||
</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">
|
||||
<div class="layui-card-header" style="height:45px; line-height:45px;">
|
||||
<strong>项目燃尽图</strong>
|
||||
</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">
|
||||
<div class="layui-col-xs6 layui-col-md6">
|
||||
<div class="layui-card border-r">
|
||||
<div class="layui-card-header" style="height:45px; line-height:45px;">
|
||||
<strong>任务分配情况</strong>
|
||||
</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" style="height:45px; line-height:45px;">
|
||||
<strong>工时登记情况</strong>
|
||||
</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,uploadPlus = layui.uploadPlus;
|
||||
|
||||
$('body').on('click','[data-event="step"]',function(){
|
||||
let check = $(this).data('check');
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if(e.code==0){
|
||||
setTimeout(function(){
|
||||
location.reload();
|
||||
},2000)
|
||||
parent.layui.pageTable.reload();
|
||||
}
|
||||
}
|
||||
if(check == 2){
|
||||
$(parent.$('.express-close')).addClass('parent-colse');
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: '请输入退回的原因或理由',
|
||||
area: ['500px', '252px'],
|
||||
content: '<div style="padding:5px;"><textarea class="layui-textarea" id="remarkTextarea" style="width: 100%; height:132px;"></textarea></div>',
|
||||
btnAlign: 'c',
|
||||
btn: ['确认回退'],
|
||||
end: function(){
|
||||
$(parent.$('.express-close')).removeClass('parent-colse');
|
||||
},
|
||||
yes: function () {
|
||||
let remark = $("#remarkTextarea").val();
|
||||
if (remark != '') {
|
||||
tool.post("/project/api/step_check", {id: project_id,check:check,content:remark}, callback);
|
||||
} else {
|
||||
layer.msg('请输入原因或理由');
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
else{
|
||||
$(parent.$('.express-close')).addClass('parent-colse');
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: '请输入操作意见',
|
||||
area: ['500px', '252px'],
|
||||
content: '<div style="padding:5px;"><textarea class="layui-textarea" id="remarkTextarea" style="width: 100%; height:132px;"></textarea></div>',
|
||||
btnAlign: 'c',
|
||||
btn: ['确认完成'],
|
||||
end: function(){
|
||||
$(parent.$('.express-close')).removeClass('parent-colse');
|
||||
},
|
||||
yes: function () {
|
||||
let remark = $("#remarkTextarea").val();
|
||||
if (remark != '') {
|
||||
tool.post("/project/api/step_check", {id: project_id,check:check,content:remark}, callback);
|
||||
} else {
|
||||
layer.msg('请输入操作意见');
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
var attachment = new uploadPlus({
|
||||
"target":'uploadBtn',
|
||||
"targetBox":'uploadBox',
|
||||
"attachment":{
|
||||
"type":1,//0ajax多文件模式,1ajax单文件单记录模式
|
||||
"uidDelete":true,//是否开启只有上传人自己才能删除自己的附件
|
||||
"ajaxSave":function(res){
|
||||
let callback = function (e) {
|
||||
layer.msg('上传成功');
|
||||
setTimeout(function(){
|
||||
location.reload();
|
||||
},2000)
|
||||
}
|
||||
tool.post("/project/api/add_file", { 'topic_id': project_id, 'file_id': res.data.id, 'file_name': res.data.name, 'module': 'project' }, callback);
|
||||
},
|
||||
"ajaxDelete":function(file_id){
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
$('#fileItem' + file_id).remove();
|
||||
}
|
||||
}
|
||||
tool.delete("/project/api/delete_file", {id: file_id}, 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: dataF.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>
|
||||
@@ -0,0 +1,64 @@
|
||||
<div class="bg-white">
|
||||
<table class="layui-hide" id="scheduleApi" lay-filter="schedule"></table>
|
||||
</div>
|
||||
<script type="text/html" id="toolbarschedule">
|
||||
<div class="layui-btn-container">
|
||||
<span class="yellow">如需创建工作日志,请到项目任务的详情页创建</span>
|
||||
</div>
|
||||
</script>
|
||||
<script>
|
||||
function project_schedule(){
|
||||
if($('#projectTab').find('li').eq(2).data('load') =='true'){
|
||||
return false;
|
||||
}
|
||||
$('#projectTab').find('li').eq(2).data('load','true');
|
||||
let form = layui.form,tool = layui.tool,table = layui.tablePlus,work = layui.oaSchedule,oaPicker = layui.oaPicker;
|
||||
//项目工作记录
|
||||
layui.scheduleTable = table.render({
|
||||
elem: '#scheduleApi',
|
||||
title: '工作记录列表',
|
||||
toolbar: '#toolbarschedule',
|
||||
cellMinWidth: 80,
|
||||
url: "/oa/api/get_schedule", //数据接口
|
||||
where: { 'project_id': project_id },
|
||||
cols: [[ //表头
|
||||
{ field: 'id', title: '序号', width: 60, align: 'center' }
|
||||
, {
|
||||
field: 'start_time', title: '工作时间范围', align: 'center', width: 180, templet: function (d) {
|
||||
var html = d.start_time + '至' + d.end_time;
|
||||
return html;
|
||||
}
|
||||
}
|
||||
, { field: 'labor_time', title: '工时', style: 'color: #91CC75;', align: 'center', width: 60 }
|
||||
, { field: 'labor_type_string', title: '工作类型', align: 'center', width: 90,templet:function(d){
|
||||
var html = '<span class="layui-color-'+d.labor_type+'">'+d.labor_type_string+'</span>';
|
||||
return html;
|
||||
}}
|
||||
, { field: 'work_cate', title: '工作类别', align: 'center', width: 100 }
|
||||
, { field: 'title', title: '工作内容' }
|
||||
, { field: 'name', title: '执行员工', align: 'center', width: 80 }
|
||||
, { field: 'department', title: '所在部门', align: 'center', width: 100 }
|
||||
, { field: 'create_time', title: '记录时间', align: 'center', width: 150 }
|
||||
, {title: '操作',fixed:'right', align: 'center', width: 100, templet: function (d) {
|
||||
if(d.admin_id == login_admin){
|
||||
return '<div class="layui-btn-group"><span class="layui-btn layui-btn-xs" lay-event="edit">修改</span><span class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详细</span></div>';
|
||||
}
|
||||
else{
|
||||
return '<span class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详细</span>';
|
||||
}
|
||||
}
|
||||
}
|
||||
]]
|
||||
});
|
||||
//监听行工具事件
|
||||
table.on('tool(schedule)', function (obj) {
|
||||
if (obj.event === 'edit') {
|
||||
work.add(0, obj.data);
|
||||
}
|
||||
if (obj.event === 'view') {
|
||||
work.view(obj.data);
|
||||
}
|
||||
return false;
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,64 @@
|
||||
<div class="bg-white">
|
||||
<table class="layui-hide" id="task" lay-filter="task"></table>
|
||||
</div>
|
||||
<script type="text/html" id="toolbartask">
|
||||
<div class="layui-btn-container">
|
||||
<button class="layui-btn layui-btn-sm" lay-event="add">+ 新建任务</button>
|
||||
</div>
|
||||
</script>
|
||||
<script>
|
||||
function project_task(){
|
||||
if($('#projectTab').find('li').eq(1).data('load') =='true'){
|
||||
return false;
|
||||
}
|
||||
$('#projectTab').find('li').eq(1).data('load','true');
|
||||
let tool = layui.tool, table = layui.tablePlus;
|
||||
//项目任务
|
||||
parent.layui.taskTable = table.render({
|
||||
elem: '#task',
|
||||
title: '任务列表',
|
||||
toolbar: '#toolbartask',
|
||||
cellMinWidth:80,
|
||||
url: "/project/api/get_task",
|
||||
where:{'project_id':project_id},
|
||||
page: true, //开启分页
|
||||
limit: 20,
|
||||
cols: [[
|
||||
{field: 'id', title: '任务编号', width: 80, align: 'center', fixed: 'left', templet: function (d) {
|
||||
return 'T' + d.id;
|
||||
}
|
||||
}
|
||||
,{ field: 'status', title: '任务状态', align: 'center', width: 90, templet: function (d) {
|
||||
var html = '<span class="check-status-color-' + d.status + '">『' + d.status_name + '』</span>';
|
||||
return html;
|
||||
}
|
||||
}
|
||||
, { field: 'cate_name', title: '工作类型', width: 90, align: 'center'}
|
||||
,{field:'title',title: '任务主题', minWidth: 300,templet:function(d){
|
||||
var html = '<span class="layui-badge layui-bg-'+d.priority+'">'+d.priority_name+'</span> <a data-href="/project/task/view/id/'+d.id+'.html" class="side-a">'+d.title+'</a>';
|
||||
return html;
|
||||
}}
|
||||
,{field:'director_name',title: '负责人', align:'center',width: 80}
|
||||
,{field:'assist_admin_names',title: '协作人',width: 160}
|
||||
,{field:'plan_hours',title: '预估工时', align:'center',width: 80}
|
||||
,{field:'end_time',title: '预计结束日期', width: 150,templet:function(d){
|
||||
var html = d.end_time;
|
||||
if(d.delay>0){
|
||||
html+= '<span class="red ml-1" style="font-size:12px;">逾期'+d.delay+'天</span>';
|
||||
}
|
||||
return html;
|
||||
}}
|
||||
]]
|
||||
});
|
||||
|
||||
//触发事件
|
||||
table.on('toolbar(task)', function(obj){
|
||||
var checkStatus = table.checkStatus(obj.config.id);
|
||||
switch(obj.event){
|
||||
case 'add':
|
||||
tool.side('/project/task/add?project_id='+project_id);
|
||||
break;
|
||||
};
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,116 @@
|
||||
<div class="bg-white">
|
||||
<table class="layui-hide" id="user" lay-filter="user"></table>
|
||||
</div>
|
||||
<script type="text/html" id="toolbaruser">
|
||||
<div class="layui-btn-container">
|
||||
<button class="layui-btn layui-btn-sm" lay-event="add">+ 新增项目成员</button>
|
||||
</div>
|
||||
</script>
|
||||
<script>
|
||||
function project_user(){
|
||||
if($('#projectTab').find('li').eq(4).data('load') =='true'){
|
||||
return false;
|
||||
}
|
||||
$('#projectTab').find('li').eq(4).data('load','true');
|
||||
let tool = layui.tool, table = layui.tablePlus,oaPicker = layui.oaPicker;
|
||||
//项目成员
|
||||
layui.userTable = table.render({
|
||||
elem: '#user',
|
||||
title: '项目成员列表',
|
||||
cellMinWidth: 60,
|
||||
toolbar: '#toolbaruser',
|
||||
url: "/project/api/project_user", //数据接口
|
||||
where: { 'tid': project_id },
|
||||
page: false, //开启分页
|
||||
limit: 20,
|
||||
cols: [[ //表头
|
||||
{ field: 'name', fixed: 'left', title: '成员姓名', width: 90, align: 'center', rowspan: 2 }
|
||||
, { field: 'create_time', title: '进入项目日期', width: 110, align: 'center', rowspan: 2 }
|
||||
, { field: 'role', title: '角色', align: 'center', width: 90, rowspan: 2, templet: function (d) {
|
||||
var html='<span style="color: #4285F4;">普通成员</span>';
|
||||
if(d.role==1){
|
||||
html='<span style="color: #EE6666;">项目创建人</span>';
|
||||
}
|
||||
if(d.role==2){
|
||||
html='<span style="color: #91CC75;">项目负责人</span>';
|
||||
}
|
||||
return html;
|
||||
}}
|
||||
, { field: 'position', title: '职位', align: 'center', width: 100, rowspan: 2 }
|
||||
, { field: 'department', title: '所在部门', align: 'center', width: 120, rowspan: 2 }
|
||||
, { field: 'mobile', title: '手机号码', align: 'center', width: 110, rowspan: 2 }
|
||||
, { align: 'center', title: '工作记录', colspan: 2 }
|
||||
, { align: 'center', title: '项目任务', colspan: 3 }
|
||||
, { field: 'delete_time', title: '移除日期', align: 'center', minWidth: 120, rowspan: 2 }
|
||||
, { field: 'status',fixed: 'right', title: '状态', align: 'center', width: 60, rowspan: 2, templet: function (d) {
|
||||
var html = '<span style="color:#EE6666">✘</span>';
|
||||
if(d.delete_time == '-')
|
||||
html = '<span style="color:#91CC75">✔</span>';
|
||||
return html;
|
||||
}}
|
||||
, {title: '操作',fixed: 'right', align: 'center', width: 60, rowspan: 2, templet: function (d) {
|
||||
var html = '<span class="layui-btn layui-btn-xs" lay-event="recover">恢复</span>';
|
||||
if(d.delete_time == '-')
|
||||
html = '<span class="layui-btn layui-btn-danger layui-btn-xs" lay-event="remove">移除</span>';
|
||||
return html;
|
||||
}
|
||||
}
|
||||
], [
|
||||
{ field: 'schedules', align: 'center', style: 'color: #91CC75;', width: 72, 'title': '记录' }
|
||||
, { field: 'labor_times', align: 'center', style: 'color: #4285F4;', width: 70, 'title': '工时' }
|
||||
, { field: 'tasks_unfinish', align: 'center', style: 'color: #91CC75;', width: 72, 'title': '进行中' }
|
||||
, { field: 'tasks_finish', align: 'center', style: 'color: #FAC858;', width: 70, 'title': '已完成' }
|
||||
, { field: 'tasks_pensent', align: 'center', style: 'color: #EE6666;', width: 72, 'title': '完成率' }
|
||||
]]
|
||||
});
|
||||
|
||||
//触发事件
|
||||
table.on('toolbar(user)', function(obj){
|
||||
var checkStatus = table.checkStatus(obj.config.id);
|
||||
switch(obj.event){
|
||||
case 'add':
|
||||
oaPicker.employeeInit({
|
||||
type: 1,
|
||||
callback: function (data) {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if(e.code == 0){
|
||||
layui.userTable.reload();
|
||||
}
|
||||
}
|
||||
let select_id=[];
|
||||
for(var a=0; a<data.length;a++){
|
||||
select_id.push(data[a].id);
|
||||
}
|
||||
let ids = select_id.join(',');
|
||||
tool.post("/project/api/add_user", {uid: ids,project_id: project_id}, callback);
|
||||
}
|
||||
})
|
||||
break;
|
||||
};
|
||||
});
|
||||
|
||||
//监听行工具事件
|
||||
table.on('tool(user)', function (obj) {
|
||||
let postData = { "id": obj.data.id };
|
||||
let callback = function (e) {
|
||||
layer.closeAll();
|
||||
layer.msg(e.msg);
|
||||
if(e.code == 0){
|
||||
layui.userTable.reload();
|
||||
}
|
||||
}
|
||||
if (obj.event === 'remove') {
|
||||
tool.ask('确定要移除该项目成员吗?', function (index) {
|
||||
tool.delete("/project/api/remove_user", postData, callback);
|
||||
});
|
||||
}
|
||||
if (obj.event === 'recover') {
|
||||
tool.ask('确定要恢复该项目成员吗?', function (index) {
|
||||
tool.post("/project/api/recover_user", postData, callback);
|
||||
});
|
||||
}
|
||||
return;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user