Browse Source

提交FTE工作计划

Lijy 1 month ago
parent
commit
737adec5e1

+ 473 - 247
fhKeeper/formulahousekeeper/timesheet/src/components/taskComponent.vue

@@ -2,54 +2,76 @@
   <div>
     <div style="height: 72vh;overflow: auto;">
         <el-form ref="form1" :model="addForm" :rules="taskRules" label-width="120px">
-            <el-form-item :label="$t('subordinatetotheproject')" v-if="showOrNot" prop="projectId">
-                <el-select v-model="addForm.projectId" :placeholder="$t('defaultText.pleaseChoose')" @change="agentCreatesEvents(1)" filterable="true" style="width:100%;">
-                    <el-option-group v-for="group in integrationProjectList" :key="group.label" :label="group.label">
-                        <el-option v-for="item in group.peojectList" :key="item.id" :label="item.projectName + '\u3000' + item.projectCode" :value="item.id">
-                            <span style="float: left; color: #8492a6; font-size: 13px;">{{ item.projectCode }}</span>
-                            <span style="float: right;">{{ item.projectName }}</span>
-                        </el-option>
-                    </el-option-group>
-                </el-select>
-            </el-form-item>
-            <el-form-item :label="$t('suoShuRenWuFenZu')" v-if="showOrNot" prop="groupId">
-                <el-select v-model="addForm.groupId" :placeholder="$t('defaultText.pleaseChoose')" @change="agentCreatesEvents(2)" filterable="true" style="width:100%;">
-                    <el-option v-for="item in groupList" :key="item.id" :label="item.name" :value="item.id"></el-option>
-                </el-select>
-            </el-form-item>
-            <el-form-item :label="$t('suoShuRenWuLieBiao')" v-if="showOrNot" prop="stagesId">
-                <el-select v-model="addForm.stagesId" :placeholder="$t('defaultText.pleaseChoose')" filterable="true" style="width:100%;">
-                    <el-option v-for="item in stageList" :key="item.id" :label="item.stagesName" :value="item.id"></el-option>
-                </el-select>
-            </el-form-item>
-            <!--子任务需要选择任务列表 -->
-            <el-form-item :label="$t('tasklist')" prop="stages" v-if="addForm.parentTid != null">
-                <el-select v-model="addForm.stagesId" style="width:100%;" >
-                    <el-option v-for="item in stageList" :key="item.id" :label="item.stagesName" :value="item.id"></el-option>
+            <el-form-item :label="'类型'" v-if="showMmeiLaiDe" prop="taskPlanType">
+                <el-select v-model="addForm.taskPlanType" :placeholder="$t('defaultText.pleaseChoose')" style="width:100%;" :disabled="doYouWantToDisableAll">
+                    <el-option label="出差" :value="1"></el-option>
+                    <el-option label="在办公事处" :value="2"></el-option>
+                    <el-option label="请假" :value="3"></el-option>
                 </el-select>
             </el-form-item>
-            <el-form-item :label="$t('qianZhiRenWu')" prop="aheadTidList" >
-                <el-select v-model="addForm.aheadTidList" style="width:100%;" multiple filterable @change="$forceUpdate()">
-                    <el-option v-for="item in relationdata" :key="item.id" :label="item.name" :value="item.id"></el-option>
-                </el-select>
-            </el-form-item>
-            <el-form-item :label="$t('types')">
-                <el-select v-model="addForm.taskType" style="width:100%;" :disabled="((this.addForm.id != null && user.id != this.addForm.createrId && currentProject.inchargerId != user.id) && !permissions.projectManagement && !permissions.editAnyTask) && !(groupResponsibleId == user.id)" @change="selchg()">
-                    <el-option v-for="item in taskTypeList" :key="item.id" :label="item.name" :value="item.id">
-                        <i :class="item.icon" ></i>
-                        <span>{{item.name}}</span>
-                    </el-option>
-                </el-select>
-            </el-form-item>
-            <el-form-item label="任务完成校验" v-if="user.timeType.taskFileCharge">
-                <el-checkbox v-model="addForm.attachFileRequired" >是否必须上传成果文件</el-checkbox>
-            </el-form-item>
-            <el-form-item  :label="$t('taskdefinition')" prop="name">
-                <el-input v-model="addForm.name" :maxlength="40" :disabled="(this.addForm.id != null && user.id != this.addForm.createrId && currentProject.inchargerId != user.id) && !permissions.projectManagement && !permissions.editAnyTask && !(groupResponsibleId == user.id)" :placeholder="$t('enterthetaskcontent')" clearable></el-input>
-            </el-form-item>
-            <el-form-item  :label="$t('planCost')" prop="planCost" v-if="user.timeType.taskPlanCost">
-                <el-input v-model.number="addForm.planCost" :maxlength="40" :disabled="(this.addForm.id != null && user.id != this.addForm.createrId && currentProject.inchargerId != user.id) && !permissions.projectManagement && !permissions.editAnyTask && !(groupResponsibleId == user.id)" :placeholder="$t('planCostHint')" clearable></el-input>
-            </el-form-item>
+            <template v-if="addForm.taskPlanType != 3">
+                <el-form-item :label="$t('subordinatetotheproject')" v-if="showOrNot" prop="projectId">
+                    <el-select v-model="addForm.projectId" :placeholder="$t('defaultText.pleaseChoose')" @change="agentCreatesEvents(1)" filterable="true" style="width:100%;" :disabled="doYouWantToDisableAll">
+                        <el-option-group v-for="group in integrationProjectList" :key="group.label" :label="group.label">
+                            <el-option v-for="item in group.peojectList" :key="item.id" :label="item.projectName + '\u3000' + item.projectCode" :value="item.id">
+                                <span style="float: left; color: #8492a6; font-size: 13px;">{{ item.projectCode }}</span>
+                                <span style="float: right;">{{ item.projectName }}</span>
+                            </el-option>
+                        </el-option-group>
+                    </el-select>
+                </el-form-item>
+                <el-form-item :label="$t('suoShuRenWuFenZu')" v-if="showOrNot" prop="groupId">
+                    <el-select v-model="addForm.groupId" :placeholder="$t('defaultText.pleaseChoose')" @change="agentCreatesEvents(2)" filterable="true" style="width:100%;" :disabled="doYouWantToDisableAll">
+                        <el-option v-for="item in groupList" :key="item.id" :label="item.name" :value="item.id"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item :label="$t('suoShuRenWuLieBiao')" v-if="showOrNot" prop="stagesId">
+                    <el-select v-model="addForm.stagesId" :placeholder="$t('defaultText.pleaseChoose')" filterable="true" style="width:100%;" :disabled="doYouWantToDisableAll">
+                        <el-option v-for="item in stageList" :key="item.id" :label="item.stagesName" :value="item.id"></el-option>
+                    </el-select>
+                </el-form-item>
+                <!--子任务需要选择任务列表 -->
+                <el-form-item :label="$t('tasklist')" prop="stages" v-if="addForm.parentTid != null">
+                    <el-select v-model="addForm.stagesId" style="width:100%;" >
+                        <el-option v-for="item in stageList" :key="item.id" :label="item.stagesName" :value="item.id"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item :label="$t('qianZhiRenWu')" prop="aheadTidList" >
+                    <el-select v-model="addForm.aheadTidList" style="width:100%;" multiple filterable @change="$forceUpdate()" :disabled="doYouWantToDisableAll">
+                        <el-option v-for="item in relationdata" :key="item.id" :label="item.name" :value="item.id"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item :label="$t('types')" v-if="!showMmeiLaiDe">
+                    <el-select v-model="addForm.taskType" style="width:100%;" :disabled="((this.addForm.id != null && user.id != this.addForm.createrId && currentProject.inchargerId != user.id) && !permissions.projectManagement && !permissions.editAnyTask) && !(groupResponsibleId == user.id)" @change="selchg()">
+                        <el-option v-for="item in taskTypeList" :key="item.id" :label="item.name" :value="item.id">
+                            <i :class="item.icon" ></i>
+                            <span>{{item.name}}</span>
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="任务完成校验" v-if="user.timeType.taskFileCharge">
+                    <el-checkbox v-model="addForm.attachFileRequired" >是否必须上传成果文件</el-checkbox>
+                </el-form-item>
+                <el-form-item label="审核人" v-if="showMmeiLaiDe && user.roleId != 2283" prop="checkSecondId">
+                    <div class="customizedReviewer">
+                        <el-select v-model="addForm.checkFirstId" :disabled="true" size="small">
+                            <el-option v-for="item in users" :key="item.id" :label="item.name" :value="item.id"></el-option>
+                        </el-select>
+                        <div style="margin: 0 20px;"> ------------------ > </div> 
+                        <el-select v-model="addForm.checkSecondId" :disabled="!addForm.checkFirstId || doYouWantToDisableAll" size="small">
+                            <el-option v-for="item in pmUserList" :key="item.id" :label="item.name" :value="item.id"></el-option>
+                        </el-select>
+                    </div>
+                    
+                </el-form-item>
+                <el-form-item  :label="$t('taskdefinition')" prop="name">
+                    <el-input v-model="addForm.name" :maxlength="40" :disabled="(this.addForm.id != null && user.id != this.addForm.createrId && currentProject.inchargerId != user.id) && !permissions.projectManagement && !permissions.editAnyTask && !(groupResponsibleId == user.id)" :placeholder="$t('enterthetaskcontent')" clearable></el-input>
+                </el-form-item>
+                <el-form-item  :label="$t('planCost')" prop="planCost" v-if="user.timeType.taskPlanCost">
+                    <el-input v-model.number="addForm.planCost" :maxlength="40" :disabled="(this.addForm.id != null && user.id != this.addForm.createrId && currentProject.inchargerId != user.id) && !permissions.projectManagement && !permissions.editAnyTask && !(groupResponsibleId == user.id)" :placeholder="$t('planCostHint')" clearable></el-input>
+                </el-form-item>
+            </template>
+           
             <!-- {{timelabel}}{{mileageCup}} -->
             <el-form-item :label="!timelabel ? $t('starttimes') : $t('jie-zhi-shi-jian')" prop="startDate">
                 <el-date-picker v-model="addForm.startDate" type="date" style="width:40%;" value-format="yyyy-MM-dd"  
@@ -137,216 +159,220 @@
             groupResponsibleId == user.id)" 
             style="margin:0 0 10px 35px;position: relative;z-index: 999;" @click.stop="addExecutorLine">{{ $t('addinganexecutor') }}</el-link>
             </div>
-            <el-form-item :label="$t('priority')">
-                <el-select v-model="addForm.taskLevel" style="width:100%;" >
-                    <el-option v-for="item in importanceList" :key="item.id" :label="item.name" :value="item.id"></el-option>
-                </el-select>
-            </el-form-item>
-            <!-- 富文本 -->
-            <el-form-item :label="$t('detaileddescription')" style="height: 200px">
-                <!-- <Editor id="tinymce" v-model="tinymceHtml" :init="editorInit"></Editor> -->
-                <!-- <el-input type="textarea" v-model="addForm.taskDesc" :rows="3"></el-input> -->
-                <!-- <quill-edito v-model="addForm.taskDesc"></quill-edito> -->
-                <quill-editor style="height: 150px" ref="text" v-model="addForm.taskDesc" class="myQuillEditor" :options="editorOption" @blur="onEditorBlur($event)" @focus="onEditorFocus($event)"/>
-            </el-form-item>
-            <!-- 富文本 -->
-            <div v-if="addForm.id != null">
-                <el-divider ></el-divider>
-                <!-- 任务进展 -->
-                <template v-if="!timelabel || isRelationItem">
-                
-                <p ><i class="iconfont firerock-icontree themeFontColor" style="margin-left:10px;">{{ $t('taskprogress') }}</i>
-                    <span ref="addPro" style="display: block; float:right;"><el-link @click="addprogress">{{ $t('addtaskprogress') }}</el-link></span>
-                </p>
-                <!-- 任务进展展示 -->
-                <div style="display: none;" ref="proBox" class="progress">
-                    <!-- <el-form :model="> -->
-                    <el-radio-group v-model="radio">
-                        <el-radio :label="0" class="rala1">{{ $t('normals') }}</el-radio>
-                        <el-radio :label="1" class="rala2">{{ $t('atrisk') }}</el-radio>
-                        <el-radio :label="2" class="rala3">{{ $t('withinthetimelimit') }}</el-radio>
-                    </el-radio-group>
-                    <el-input
-                    type="textarea"
-                    border="0"
-                    :autosize="{ minRows: 2, maxRows: 6}"
-                    :placeholder="$t('detailedprogressdescription')"
-                    v-model="text2"
-                    style="margin:10px 0 0 0">
-                    </el-input>
-                    <h4 style="font-weight: normal;">{{ $t('tixiang') }}{{checkLists.length}}</h4>
-                    <i class="el-icon-circle-plus pron_i themeFontColor" style="font-size: 28px;" @click="addI(0)"></i>
-                    <div class="remind" ref="addRem" style="display: none">
-                        <el-checkbox-group v-model="checkboxGrounp" v-for="item in users" :key="item.id">
-                            <p>
-                                <el-checkbox :label="item.name" @change="kkk(item)">
-                                    <span>
-                                        <span v-if="user.userNameNeedTranslate != '1'">
-                                            {{item.name}}
-                                        </span>
-                                        <span v-if="user.userNameNeedTranslate == '1'">
-                                            <TranslationOpenDataText type='userName' :openid='item.name'></TranslationOpenDataText>
+
+            <template v-if="addForm.taskPlanType != 3">
+                <el-form-item :label="$t('priority')">
+                    <el-select v-model="addForm.taskLevel" style="width:100%;" :disabled="doYouWantToDisableAll">
+                        <el-option v-for="item in importanceList" :key="item.id" :label="item.name" :value="item.id"></el-option>
+                    </el-select>
+                </el-form-item>
+                <!-- 富文本 -->
+                <el-form-item :label="$t('detaileddescription')" style="height: 200px">
+                    <!-- <Editor id="tinymce" v-model="tinymceHtml" :init="editorInit"></Editor> -->
+                    <!-- <el-input type="textarea" v-model="addForm.taskDesc" :rows="3"></el-input> -->
+                    <!-- <quill-edito v-model="addForm.taskDesc"></quill-edito> -->
+                    <quill-editor style="height: 150px" ref="text" v-model="addForm.taskDesc" class="myQuillEditor" :options="editorOption" @blur="onEditorBlur($event)" @focus="onEditorFocus($event)" :disabled="doYouWantToDisableAll"/>
+                </el-form-item>
+                <!-- 富文本 -->
+                <div v-if="addForm.id != null">
+                    <el-divider ></el-divider>
+                    <!-- 任务进展 -->
+                    <template v-if="!timelabel || isRelationItem">
+                    
+                    <p ><i class="iconfont firerock-icontree themeFontColor" style="margin-left:10px;">{{ $t('taskprogress') }}</i>
+                        <span ref="addPro" style="display: block; float:right;"><el-link @click="addprogress">{{ $t('addtaskprogress') }}</el-link></span>
+                    </p>
+                    <!-- 任务进展展示 -->
+                    <div style="display: none;" ref="proBox" class="progress">
+                        <!-- <el-form :model="> -->
+                        <el-radio-group v-model="radio">
+                            <el-radio :label="0" class="rala1">{{ $t('normals') }}</el-radio>
+                            <el-radio :label="1" class="rala2">{{ $t('atrisk') }}</el-radio>
+                            <el-radio :label="2" class="rala3">{{ $t('withinthetimelimit') }}</el-radio>
+                        </el-radio-group>
+                        <el-input
+                        type="textarea"
+                        border="0"
+                        :autosize="{ minRows: 2, maxRows: 6}"
+                        :placeholder="$t('detailedprogressdescription')"
+                        v-model="text2"
+                        style="margin:10px 0 0 0">
+                        </el-input>
+                        <h4 style="font-weight: normal;">{{ $t('tixiang') }}{{checkLists.length}}</h4>
+                        <i class="el-icon-circle-plus pron_i themeFontColor" style="font-size: 28px;" @click="addI(0)"></i>
+                        <div class="remind" ref="addRem" style="display: none">
+                            <el-checkbox-group v-model="checkboxGrounp" v-for="item in users" :key="item.id">
+                                <p>
+                                    <el-checkbox :label="item.name" @change="kkk(item)">
+                                        <span>
+                                            <span v-if="user.userNameNeedTranslate != '1'">
+                                                {{item.name}}
+                                            </span>
+                                            <span v-if="user.userNameNeedTranslate == '1'">
+                                                <TranslationOpenDataText type='userName' :openid='item.name'></TranslationOpenDataText>
+                                            </span>
                                         </span>
-                                    </span>
-                                </el-checkbox>
-                            </p>
-                        </el-checkbox-group>
-                    </div>
-                    <div class="ssp" @click="sss"></div>
-                    <!-- </el-form> -->
-                    <div class="pro_btn">
-                        <el-button size="mini" @click="shutPro">{{ $t('btn.cancel') }}</el-button>
-                        <el-button size="mini" type="primary" @click="addTaskProgress">{{ $t('fa-bu') }}</el-button>
+                                    </el-checkbox>
+                                </p>
+                            </el-checkbox-group>
+                        </div>
+                        <div class="ssp" @click="sss"></div>
+                        <!-- </el-form> -->
+                        <div class="pro_btn">
+                            <el-button size="mini" @click="shutPro">{{ $t('btn.cancel') }}</el-button>
+                            <el-button size="mini" type="primary" @click="addTaskProgress">{{ $t('fa-bu') }}</el-button>
+                        </div>
                     </div>
-                </div>
-                
-                <div class="ddl" v-if="recentProgressInfo != null && recentProgressInfo.id != null">
-                    <div class="elCard" style="margin-bottom: 10px; height:" >
-                        <i class="el-icon-success" style="color: #43d14f;" v-if="recentProgressInfo.status == 0"></i>
-                        <i class="el-icon-success" style="color: #fd7624;" v-else-if="recentProgressInfo.status == 1"></i>
-                        <i class="el-icon-success" style="color: #fd4d47;" v-else></i>
-                        <span v-if="recentProgressInfo.status == 0">{{ $t('normals') }}</span>
-                        <span v-else-if="recentProgressInfo.status == 1">{{ $t('normals') }}</span>
-                        <span v-else>{{ $t('withinthetimelimit') }}</span>
-                        <el-dropdown trigger="click" style="float:right;cursor:pointer; float: right;">
-                                <i class="el-icon-more" ></i>
-                                <el-dropdown-menu slot="dropdown">
-                                    <el-dropdown-item divided>
-                                        <span @click="deleteTaskProgress(recentProgressInfo.id)"><i class="el-icon-delete"></i>{{ $t('deleteList ') }}</span></el-dropdown-item>
-                                </el-dropdown-menu>
-                        </el-dropdown>
-                        <!-- <div class="elCard_qu">{{recentProgressInfo.creatorName}}{{ $t('geng-xin-yu') }}{{recentProgressInfo.indate | relativeTime}}</div> -->
-                        <div class="elCard_qu">
-                            <span>
-                                <span v-if="user.userNameNeedTranslate != '1'">
-                                    {{recentProgressInfo.creatorName}}
-                                </span>
-                                <span v-if="user.userNameNeedTranslate == '1'">
-                                    <TranslationOpenDataText type='userName' :openid='recentProgressInfo.creatorName'></TranslationOpenDataText>
+                    
+                    <div class="ddl" v-if="recentProgressInfo != null && recentProgressInfo.id != null">
+                        <div class="elCard" style="margin-bottom: 10px; height:" >
+                            <i class="el-icon-success" style="color: #43d14f;" v-if="recentProgressInfo.status == 0"></i>
+                            <i class="el-icon-success" style="color: #fd7624;" v-else-if="recentProgressInfo.status == 1"></i>
+                            <i class="el-icon-success" style="color: #fd4d47;" v-else></i>
+                            <span v-if="recentProgressInfo.status == 0">{{ $t('normals') }}</span>
+                            <span v-else-if="recentProgressInfo.status == 1">{{ $t('normals') }}</span>
+                            <span v-else>{{ $t('withinthetimelimit') }}</span>
+                            <el-dropdown trigger="click" style="float:right;cursor:pointer; float: right;">
+                                    <i class="el-icon-more" ></i>
+                                    <el-dropdown-menu slot="dropdown">
+                                        <el-dropdown-item divided>
+                                            <span @click="deleteTaskProgress(recentProgressInfo.id)"><i class="el-icon-delete"></i>{{ $t('deleteList ') }}</span></el-dropdown-item>
+                                    </el-dropdown-menu>
+                            </el-dropdown>
+                            <!-- <div class="elCard_qu">{{recentProgressInfo.creatorName}}{{ $t('geng-xin-yu') }}{{recentProgressInfo.indate | relativeTime}}</div> -->
+                            <div class="elCard_qu">
+                                <span>
+                                    <span v-if="user.userNameNeedTranslate != '1'">
+                                        {{recentProgressInfo.creatorName}}
+                                    </span>
+                                    <span v-if="user.userNameNeedTranslate == '1'">
+                                        <TranslationOpenDataText type='userName' :openid='recentProgressInfo.creatorName'></TranslationOpenDataText>
+                                    </span>
                                 </span>
-                            </span>
-                            {{ $t('geng-xin-yu') }}{{recentProgressInfo.indate | relativeTime}}
+                                {{ $t('geng-xin-yu') }}{{recentProgressInfo.indate | relativeTime}}
+                            </div>
+                            <p style="padding-left: 20px;">{{recentProgressInfo.content}}</p>
+                            <div class="examine"><el-button type="text" @click="innerVisibless = true" style="color: #8F87A3;">{{ $t('viewingHistory') }}</el-button></div>
                         </div>
-                        <p style="padding-left: 20px;">{{recentProgressInfo.content}}</p>
-                        <div class="examine"><el-button type="text" @click="innerVisibless = true" style="color: #8F87A3;">{{ $t('viewingHistory') }}</el-button></div>
                     </div>
-                </div>
-                <!-- 任务列表没有数据的时候展示 -->
-                <div class="nones" v-if="ProgressList.length <= 0">
-                    {{ $t('nodata') }} 
-                </div>
-                <!-- 任务进展完整状态 -->
-                <el-dialog :title="$t('other.prompts')" :visible.sync="innerVisibless" append-to-body width="500px">
-                <div class="integrity">
-                    <h3 style="font-weight: normal;display: inline-block;margin: 0 0 20px 0;">{{ $t('taskprogress') }} :{{ProgressList.length}}</h3>
-                    <!-- <span class="write"><i class="el-icon-circle-plus"></i>填写进展</span> -->
-                    <el-divider></el-divider>
-                    <!--  -->
-                        <div class="block" style="height: 200px;">
-                            <el-timeline style="padding:20px 0 0 0;">
-                                <el-timeline-item
-                                v-for="(activity, index) in ProgressList"
-                                :key="index">
-                                <div class="tb">
-                                    <span v-if="activity.status == 0" style="color: #43D14F" class="icon"></span>
-                                    <span v-if="activity.status == 1" style="color: #FD7624" class="icon"></span>
-                                    <span v-if="activity.status == 2" style="color: red" class="icon"></span>
-                                    <div>
-                                        <span v-if="activity.status == 0" style="color: #43D14F">{{ $t('normals') }}</span>
-                                        <span v-if="activity.status == 1" style="color: #FD7624">{{ $t('atrisk') }}</span>
-                                        <span v-if="activity.status == 2" style="color: red">{{ $t('withinthetimelimit') }}</span>
-                                        <span style="display: inline-block; float: right; color: #8C8C8C">{{activity.indate | relativeTime}}</span>
+                    <!-- 任务列表没有数据的时候展示 -->
+                    <div class="nones" v-if="ProgressList.length <= 0">
+                        {{ $t('nodata') }} 
+                    </div>
+                    <!-- 任务进展完整状态 -->
+                    <el-dialog :title="$t('other.prompts')" :visible.sync="innerVisibless" append-to-body width="500px">
+                    <div class="integrity">
+                        <h3 style="font-weight: normal;display: inline-block;margin: 0 0 20px 0;">{{ $t('taskprogress') }} :{{ProgressList.length}}</h3>
+                        <!-- <span class="write"><i class="el-icon-circle-plus"></i>填写进展</span> -->
+                        <el-divider></el-divider>
+                        <!--  -->
+                            <div class="block" style="height: 200px;">
+                                <el-timeline style="padding:20px 0 0 0;">
+                                    <el-timeline-item
+                                    v-for="(activity, index) in ProgressList"
+                                    :key="index">
+                                    <div class="tb">
+                                        <span v-if="activity.status == 0" style="color: #43D14F" class="icon"></span>
+                                        <span v-if="activity.status == 1" style="color: #FD7624" class="icon"></span>
+                                        <span v-if="activity.status == 2" style="color: red" class="icon"></span>
+                                        <div>
+                                            <span v-if="activity.status == 0" style="color: #43D14F">{{ $t('normals') }}</span>
+                                            <span v-if="activity.status == 1" style="color: #FD7624">{{ $t('atrisk') }}</span>
+                                            <span v-if="activity.status == 2" style="color: red">{{ $t('withinthetimelimit') }}</span>
+                                            <span style="display: inline-block; float: right; color: #8C8C8C">{{activity.indate | relativeTime}}</span>
+                                        </div>
+                                        <p style="color: #8C8C8C">{{activity.content}}</p>
+                                        
                                     </div>
-                                    <p style="color: #8C8C8C">{{activity.content}}</p>
-                                    
-                                </div>
-                                </el-timeline-item>
-                            </el-timeline>
-                        </div>
-                    <!--  -->
-                </div>
-                <span slot="footer" class="dialog-footer foooot">
-                    <el-button type="primary" @click="innerVisibless = false">{{ $t('Shutdown') }}</el-button>
-                </span>
-                </el-dialog>
-                </template>
-                <!-- 子任务/关联任务 -->
-                <p ><i class="iconfont firerock-icontree themeFontColor" style="margin-left:10px;">{{timelabel && !isRelationItem ? $t('guanlian') : $t('zirwu')}}</i>
-                    <el-link style="float:right;" @click="addRelation" v-if="timelabel && !isRelationItem">{{ $t('associatedTask') }}</el-link>
-                    <el-link style="float:right;" @click="addSubTask" v-else>{{ $t('addingsubtask') }}</el-link>
-                </p>
-                <!-- 关联任务列表 -->
-                <el-table key="guanlian" :data="relationSubTaskList" v-if="timelabel && !isRelationItem"
-                :header-cell-style="{'font-weight':'normal'}"
-                highlight-current-row
-                v-loading="listLoading"
-                style="width: 100%;margin-top:10px;"
-                @row-click="relationTaskClick">
-                    <el-table-column prop="taskStatus" :label="$t('wan-cheng')" width="50" >
-                        <template slot-scope="scope">
-                            <el-checkbox :disabled="scope.row.taskStatus==2" :checked="scope.row.taskStatus==1?true:false" size="large" class="cb" @change="relationFinishTask(scope.row)"></el-checkbox>
-                        </template>
-                    </el-table-column>
-                    <el-table-column prop="taskName" :label="$t('biao-ti')" >
-                        <template slot-scope="scope">
-                            <el-tooltip class="item themeFontColor" effect="dark" :content="scope.row.taskName" placement="top" style="cursor:pointer;">
-                                <span style="overflow: hidden;text-overflow:ellipsis;white-space: nowrap;" > {{scope.row.taskName}}</span>
-                            </el-tooltip>
-                        </template>
-                    </el-table-column>
-                    <el-table-column :label="$t('operation')" width="130" align="left">
-                        <template slot-scope="scope">
-                            <el-button @click.stop.native="deleteRelationItem(scope.row.id)" size="mini">{{ $t('dissociated') }}</el-button>
-                        </template>
-                    </el-table-column>
-                </el-table>
-                <!--子任务列表 -->
-                <el-table key="zi" :data="addForm.subTaskList" v-else
-                        :header-cell-style="{'font-weight':'normal'}"
-                        highlight-current-row v-loading="listLoading" style="width: 100%;margin-top:10px;" @row-click="taskLineClick">
-                            <el-table-column prop="taskStatus" :label="$t('wan-cheng')" width="50" >
+                                    </el-timeline-item>
+                                </el-timeline>
+                            </div>
+                        <!--  -->
+                    </div>
+                    <span slot="footer" class="dialog-footer foooot">
+                        <el-button type="primary" @click="innerVisibless = false">{{ $t('Shutdown') }}</el-button>
+                    </span>
+                    </el-dialog>
+                    </template>
+                    <!-- 子任务/关联任务 -->
+                    <p ><i class="iconfont firerock-icontree themeFontColor" style="margin-left:10px;">{{timelabel && !isRelationItem ? $t('guanlian') : $t('zirwu')}}</i>
+                        <el-link style="float:right;" @click="addRelation" v-if="timelabel && !isRelationItem">{{ $t('associatedTask') }}</el-link>
+                        <el-link style="float:right;" @click="addSubTask" v-else>{{ $t('addingsubtask') }}</el-link>
+                    </p>
+                    <!-- 关联任务列表 -->
+                    <el-table key="guanlian" :data="relationSubTaskList" v-if="timelabel && !isRelationItem"
+                    :header-cell-style="{'font-weight':'normal'}"
+                    highlight-current-row
+                    v-loading="listLoading"
+                    style="width: 100%;margin-top:10px;"
+                    @row-click="relationTaskClick">
+                        <el-table-column prop="taskStatus" :label="$t('wan-cheng')" width="50" >
                             <template slot-scope="scope">
-                            <el-checkbox :disabled="scope.row.taskStatus==2" :checked="scope.row.taskStatus==1?true:false" size="large" class="cb"  
-                                            @change="finishTask(scope.row)"
-                                            ></el-checkbox>
+                                <el-checkbox :disabled="scope.row.taskStatus==2" :checked="scope.row.taskStatus==1?true:false" size="large" class="cb" @change="relationFinishTask(scope.row)"></el-checkbox>
                             </template>
                         </el-table-column>
-                        <el-table-column prop="name" :label="$t('biao-ti')" >
+                        <el-table-column prop="taskName" :label="$t('biao-ti')" >
                             <template slot-scope="scope">
-                                <el-tooltip class="item" effect="dark" :content="scope.row.name" placement="top">
-                                <span style="overflow: hidden;text-overflow:ellipsis;white-space: nowrap;" > {{scope.row.name}}</span>
+                                <el-tooltip class="item themeFontColor" effect="dark" :content="scope.row.taskName" placement="top" style="cursor:pointer;">
+                                    <span style="overflow: hidden;text-overflow:ellipsis;white-space: nowrap;" > {{scope.row.taskName}}</span>
                                 </el-tooltip>
                             </template>
                         </el-table-column>
-                        <el-table-column prop="executorName" :label="$t('zhi-hang-ren')" width="100" >
+                        <el-table-column :label="$t('operation')" width="130" align="left">
                             <template slot-scope="scope">
-                                <span v-if="user.userNameNeedTranslate != 1">
-                                    {{scope.row.executorName == null?$t('dai-fen-pei'):scope.row.executorName}}
-                                </span>
-                                <span v-if="user.userNameNeedTranslate == 1">
-                                    <span v-if="scope.row.executorName == null">
-                                        {{$t('dai-fen-pei')}}
+                                <el-button @click.stop.native="deleteRelationItem(scope.row.id)" size="mini">{{ $t('dissociated') }}</el-button>
+                            </template>
+                        </el-table-column>
+                    </el-table>
+                    <!--子任务列表 -->
+                    <el-table key="zi" :data="addForm.subTaskList" v-else
+                            :header-cell-style="{'font-weight':'normal'}"
+                            highlight-current-row v-loading="listLoading" style="width: 100%;margin-top:10px;" @row-click="taskLineClick">
+                                <el-table-column prop="taskStatus" :label="$t('wan-cheng')" width="50" >
+                                <template slot-scope="scope">
+                                <el-checkbox :disabled="scope.row.taskStatus==2" :checked="scope.row.taskStatus==1?true:false" size="large" class="cb"  
+                                                @change="finishTask(scope.row)"
+                                                ></el-checkbox>
+                                </template>
+                            </el-table-column>
+                            <el-table-column prop="name" :label="$t('biao-ti')" >
+                                <template slot-scope="scope">
+                                    <el-tooltip class="item" effect="dark" :content="scope.row.name" placement="top">
+                                    <span style="overflow: hidden;text-overflow:ellipsis;white-space: nowrap;" > {{scope.row.name}}</span>
+                                    </el-tooltip>
+                                </template>
+                            </el-table-column>
+                            <el-table-column prop="executorName" :label="$t('zhi-hang-ren')" width="100" >
+                                <template slot-scope="scope">
+                                    <span v-if="user.userNameNeedTranslate != 1">
+                                        {{scope.row.executorName == null?$t('dai-fen-pei'):scope.row.executorName}}
                                     </span>
-                                    <span v-else>
-                                        <span v-for="item,index in scope.row.executorName" :key="index">
-                                            <TranslationOpenDataText type='userName' :openid='item'></TranslationOpenDataText>
-                                            <span v-if="index < scope.row.executorName.length - 1">,</span>
+                                    <span v-if="user.userNameNeedTranslate == 1">
+                                        <span v-if="scope.row.executorName == null">
+                                            {{$t('dai-fen-pei')}}
+                                        </span>
+                                        <span v-else>
+                                            <span v-for="item,index in scope.row.executorName" :key="index">
+                                                <TranslationOpenDataText type='userName' :openid='item'></TranslationOpenDataText>
+                                                <span v-if="index < scope.row.executorName.length - 1">,</span>
+                                            </span>
                                         </span>
                                     </span>
-                                </span>
-                            </template>
-                        </el-table-column>
-                        <el-table-column prop="endDate" :label="$t('deadline')" width="100" >
-                            <template slot-scope="scope">
-                                <p v-if="scope.row.endDate >= times">{{scope.row.endDate}}</p>
-                                <p v-else style="background: #e62412; color: #fff;text-align: center; border-radius: 3px;">{{scope.row.endDate}}</p>
-                            </template>
-                        </el-table-column>
-                </el-table>
-            </div>
+                                </template>
+                            </el-table-column>
+                            <el-table-column prop="endDate" :label="$t('deadline')" width="100" >
+                                <template slot-scope="scope">
+                                    <p v-if="scope.row.endDate >= times">{{scope.row.endDate}}</p>
+                                    <p v-else style="background: #e62412; color: #fff;text-align: center; border-radius: 3px;">{{scope.row.endDate}}</p>
+                                </template>
+                            </el-table-column>
+                    </el-table>
+                </div>
+            </template>
+            
         </el-form>
         <!-- 关联文件列表 -->
-        <template v-if="isEditFile">
+        <template v-if="isEditFile && addForm.taskPlanType != 3">
             <div style="width:100%;margin:1em 0;">
                 <i class="iconfont firerock-icontree themeFontColor" style="margin-left:10px;">{{ $t('jiafuchengguo') }}</i>
                 <el-link @click="relationFileClick()" style="float:right;margin-left:10px">{{ $t('associatedfiles') }}</el-link>
@@ -465,9 +491,20 @@
         </el-dialog>
     </div>
     <div slot="footer" class="dialog-footer foooot">
-        <el-button v-if="(user.id == addForm.createrId || currentProject.inchargerId == user.id || currentProject.creatorId == user.id || permissions.projectManagement) && canAddTask" @click.native="deleteTask()" style="float:left;">{{ $t('btn.delete') }}</el-button>
+        <template v-if="!showMmeiLaiDe">
+            <el-button v-if="(user.id == addForm.createrId || currentProject.inchargerId == user.id || currentProject.creatorId == user.id || permissions.projectManagement) && canAddTask" @click.native="deleteTask()" style="float:left;">{{ $t('btn.delete') }}</el-button>
+        </template>
+        <template v-if="showMmeiLaiDe">
+            <el-button v-if="[0, 1, 2, 3, 5, 6].includes(showMmeiLaiDeData.taskStatus)" @click.native="deleteTask()" style="float:left;">{{ $t('btn.delete') }}</el-button>
+        </template>
         <el-button type="primary" v-if="user.userNameNeedTranslate == 1 && !meetingId && !integrationTask.stage && addForm.executorListFront[0].executorId" @click="meetingCli()">{{ $t('faQiHuiYi') }}</el-button>
         <el-button @click.native="closeBounceds()">{{ $t('btn.cancel') }}</el-button>
+        <template v-if="showMmeiLaiDe && addForm.id && millerSReviewer.includes(user.id) && [3, 4].includes(showMmeiLaiDeData.taskStatus) && showMmeiLaiDeData.leaderOrManager == 2">
+            <template v-if="(showMmeiLaiDeData.taskStatus == 3 && user.id == showMmeiLaiDeData.checkFirstId) || (showMmeiLaiDeData.taskStatus == 4 && user.id == showMmeiLaiDeData.checkSecondId)">
+                <el-button type="danger" @click="planOperation(false)" :loading="addLoading">驳回</el-button>
+                <el-button type="success" @click="planOperation(true)" :loading="addLoading">通过</el-button>
+            </template>
+        </template>
         <el-button type="primary" @click="submitInsert" :loading="addLoading">{{ $t('btn.submit') }}</el-button>
     </div>
     
@@ -475,7 +512,7 @@
         <el-page-header  @back="backToParentTask" :title="timelabel ? $t('returnmilestone') : $t('parenttask')" :content="timelabel ? relationPar.name : addForm.parentTname"></el-page-header>
     </div> -->
     <!-- 评论 -->
-    <div class="remark" v-show="addForm.id != null">
+    <div class="remark" v-show="addForm.id != null && !showMmeiLaiDe">
         <span class="zh">
                 <div class="player">
                     <p>{{ $t('participantin') }}</p>
@@ -746,6 +783,15 @@ export default {
     showOrNot: {
         type: Boolean,
         default: false
+    },
+    // 是否属于美莱得定制化的工作计划
+    showMmeiLaiDe: {
+        type: Boolean,
+        default: false
+    },
+    showMmeiLaiDeData: {
+        type: Object,
+        default: {}
     }
   },
   components: {
@@ -755,6 +801,7 @@ export default {
   },
   data() {
     return { 
+        doYouWantToDisableAll: false,
         startNum: 0,
         endNum: 5,
         shownumber: 5,
@@ -854,6 +901,8 @@ export default {
             groupId: [{ required: true, message: this.$t('qingXuanZeSuoShuRenWuFenZu'), trigger: "blur" }],
             stagesId: [{ required: true, message: this.$t('qingXuanZeSuoShuRenWuLieBiao'), trigger: "blur" }],
             planCost: [{ required: true, message: this.$t('planCostHint'), trigger: "blur" }],
+            taskPlanType: [{ required: true, message: '请选择类型', trigger: "blur" }],
+            checkSecondId: [{ required: true, message: '请选择审核人', trigger: "blur" }]
         },
         formGrouping: {
             name: [{ required: true, message: this.$t('pleaseenteragroupname'), trigger: "blur" }],
@@ -972,7 +1021,9 @@ export default {
             startTime: '',
             endTime: '',
             taskId: ''
-        }
+        },
+        pmUserList: [],
+        millerSReviewer: [],
     };
   },
   computed: {
@@ -1009,8 +1060,20 @@ export default {
     this.getSapServiceList()
 
     this.timess();
+
+    if(this.showMmeiLaiDe) {
+        this.getPmUserList()
+        this.setDisabledPermission()
+    }
   },
   methods: {
+    setDisabledPermission() {
+        const { taskStatus } = this.showMmeiLaiDeData
+        this.doYouWantToDisableAll = taskStatus == 3 || taskStatus == 4
+        if(this.millerSReviewer.includes(this.user.id)) {
+            this.doYouWantToDisableAll = false
+        }
+    },
     viewOnline(row) {
         sessionStorage.setItem("fileName",row.documentName);
         sessionStorage.setItem("fileUrl",row.url);
@@ -1056,7 +1119,7 @@ export default {
         this.refreshData()
     },
     confirmMeeting() {
-        this.http.post('/task//operateMeeting',{...this.initiateAMeetingForm},
+        this.http.post('/task/operateMeeting',{...this.initiateAMeetingForm},
         res => {
             if (res.code == "ok") {
                 this.meetingVisable=false,
@@ -1080,6 +1143,35 @@ export default {
             });
         });
     },
+    planOperation(type) {
+        this.http.post('/task/taskPlanPassOrReject', {
+            taskId: this.addForm.id, type
+        },
+        res => {
+            if (res.code == "ok") {
+                this.$message({
+                    message: '操作成功',
+                    type: "success"
+                });
+                let obj = {
+                    submitInsert: true,
+                    showOrNot: this.showOrNot
+                }
+                this.$emit('closeBounced', obj)
+            } else {
+                this.$message({
+                    message: res.msg,
+                    type: "error"
+                });
+            }
+        },
+        error => {
+            this.$message({
+                message: error,
+                type: "error"
+            });
+        });
+    },
     // 触发外层的会议
     meetingCli() {
         // this.$parent.$parent.parentMeetingCli(this.integrationTask.id)
@@ -1095,17 +1187,38 @@ export default {
     triggerEvent(obj) {
         console.log(obj, '触发事件')
         this.curProjectId = obj.curProjectId
-        this.getProjectList()
+        if(!this.showMmeiLaiDe) {
+            this.getProjectList()
+        } else {
+            this.getProjectListTwo()
+        }
         if(!obj.taskVue) {
             this.getStageList(obj.integrationTaskNingwai)
         }
         if(obj.create) {
+            console.log(obj, '<=== 双击获取的')
             this.getUsers(); // 获取名单数据
             this.mileageCup = false
             this.addFormVisible = true;
             this.curProjectId = obj.stage.projectId;
-            this.addForm = {projectId: obj.stage.projectId, groupId: obj.stage.groupId, stagesId: obj.stage.id, taskLevel:0, planHours: 8, taskType: 0};
-            this.addForm.executorListFront = [{executorId:null, planHours:this.user.timeType.allday}];
+            this.addForm = {
+                projectId: obj.stage.projectId, 
+                groupId: obj.stage.groupId, 
+                stagesId: obj.stage.id, 
+                startDate: obj.addForm.startDate,
+                taskLevel:0, 
+                planHours: 8, 
+                taskType: 0
+            };
+            // this.addForm.executorListFront = [
+            //     {executorId:obj.executorListFront[0] && obj.executorListFront[0].executorId, planHours:this.user.timeType.allday}
+            // ];
+            this.addForm.executorListFront = (obj.executorListFront || []).map(em => {
+                return {
+                    executorId: em.executorId,
+                    planHours: this.user.timeType.allday
+                }
+            })
             this.gstimhour = [this.user.timeType.allday]
             this.gstimday = [1]
             this.addLoading = false;
@@ -1113,6 +1226,7 @@ export default {
             this.title=this.$t('createtask ');
             this.commentList = [];
             this.timelabel = false
+            console.log(this.addForm, '<====== this.addForm')
         } else {
             if(!obj.taskVue) {
                 this.isEditFile = true;
@@ -1125,6 +1239,10 @@ export default {
             this.getDailyList(obj.id) // 获取来自日报
             this.getRelationTaskList(obj.num, obj.id)
             this.getTaskFileList(obj.num,obj.id)
+            const { integrationTaskNingwai = {} } = obj
+            if(integrationTaskNingwai.groupId) {
+                this.getTaskGrouping(obj.curProjectId)
+            }
             setTimeout(() => {
                 this.getTaskDetail(obj.id);
             }, 200)
@@ -1138,11 +1256,60 @@ export default {
             this.addForm.stagesId = ''
             this.getTaskGrouping()
             this.getrelation();
+            if(this.showMmeiLaiDe) {
+                this.getProjectManager()
+            }
         } else if(num == 2) {
             this.addForm.stagesId = ''
             this.getTaskList()
         }
     },
+    getProjectManager() {
+        const { projectId } = this.addForm
+        this.http.post('/user/getChargeUserByProjectId', { projectId },
+        res => {
+            if (res.code == "ok") {
+                if(!res.data.id) {
+                    this.$message({
+                        message: '当前项目没有项目经理',
+                        type: "warning"
+                    });
+                    return
+                }
+                this.addForm.checkFirstId = res.data.id || '';
+            } else {
+                this.$message({
+                    message: res.msg,
+                    type: "error"
+                });
+            }
+        },
+        error => {
+            this.$message({
+                message: error,
+                type: "error"
+            });
+        });
+    },
+    getPmUserList() {
+        this.http.post('/user/getSecondCheckUser', {  },
+        res => {
+            if (res.code == "ok") {
+                this.pmUserList = res.data || [];
+            } else {
+                this.$message({
+                    message: res.msg,
+                    type: "error"
+                });
+            }
+        },
+        error => {
+            this.$message({
+                message: error,
+                type: "error"
+            });
+        });
+    },
     //获取项目列表
     getProjectList() {
         this.http.post(this.port.project.list, {},
@@ -1164,6 +1331,34 @@ export default {
             });
         });
     },
+    getProjectListTwo() {
+        let obj = {}
+        if(this.curProjectId) {
+            obj.projectId = this.curProjectId
+        }
+        this.http.post(`/project/getProjectByLeader`, {
+            ...obj
+        },
+        res => {
+            if (res.code == "ok") {
+                this.projectList = res.data;
+                this.integrationProjectList = [
+                    { label: '相关项目', peojectList: res.data }
+                ]
+            } else {
+                this.$message({
+                    message: res.msg,
+                    type: "error"
+                });
+            }
+        },
+        error => {
+            this.$message({
+                message: error,
+                type: "error"
+            });
+        });
+    },
     // 获取最近项目列表
     getRecentlyProject() {
         this.http.post('/project/nearProject',{},res => {
@@ -1192,8 +1387,8 @@ export default {
         })
     },
     // 获取任务分组
-    getTaskGrouping() {
-        this.http.post('/task-group/list', {projectId:this.addForm.projectId},
+    getTaskGrouping(projectId) {
+        this.http.post('/task-group/list', {projectId: projectId ? projectId : this.addForm.projectId},
         res => {
             if (res.code == "ok") {
                 this.groupList = res.data;
@@ -1301,6 +1496,10 @@ export default {
         this.http.post('/task/getTask',{id: id},
         res => {
             if (res.code == "ok") {
+                this.millerSReviewer = [res.data.checkFirstId, res.data.checkSecondId]
+                if(this.showMmeiLaiDe) {
+                    this.setDisabledPermission()
+                }
                 this.meetingId = res.data.meetingId
                 console.log(this.meetingId, '看看打印纸')
                 if(this.user.userNameNeedTranslate == 1) {
@@ -1708,6 +1907,14 @@ export default {
                 });
             }
         }
+
+        if(this.showMmeiLaiDe && !this.addForm.endDate) {
+            return this.$message({
+                    showClose: true,
+                    message: '请选择截止时间',
+                    type: 'warning'
+                });
+        }
         this.$refs.form1.validate(valid => {
             if (valid) {
                 delete this.addForm.subTaskList;
@@ -1720,9 +1927,20 @@ export default {
                     this.addForm.executorListFront.serviceId= this.addForm.executorListFront.serviceId;
                 }
                 this.addForm.executorListStr = JSON.stringify(this.addForm.executorListFront);
+                // this.addForm.executorList = this.addForm.aheadTidList;
                 this.addForm.aheadTid = JSON.stringify(this.addForm.aheadTidList);
+
+                let addFormData = { ...this.addForm }
+                if(this.addForm.taskPlanType == 3) {
+                    addFormData = {
+                        taskPlanType: 3,
+                        startDate: this.addForm.startDate,
+                        endDate: this.addForm.endDate,
+                        executorListStr: this.addForm.executorListStr
+                    }
+                }
                 this.addLoading = true;
-                this.http.post('/task/save',this.addForm,
+                this.http.post('/task/save',{ ...addFormData, isTaskPlan: this.showMmeiLaiDe ? 1 : 0},
                     res => {
                         this.addLoading = false;
                         if (res.code == "ok") {
@@ -1814,6 +2032,10 @@ export default {
             this.http.post('/task/delete',{id: this.addForm.id},
             res => {
                 if (res.code == "ok") {
+                    this.$message({
+                        message: '删除成功',
+                        type: 'success'
+                    });
                     this.$emit('closeBounced', {deleteTask: true})
                 } else {
                     this.$message({
@@ -2402,6 +2624,10 @@ export default {
 .themeFontColor {
     @include font_color("color");
 }
+.customizedReviewer {
+    display: flex;
+    align-items: center;
+}
 .editingTask {
     display: flex;
     flex-wrap: wrap;

+ 4 - 0
fhKeeper/formulahousekeeper/timesheet/src/permissions.js

@@ -103,6 +103,8 @@ const StringUtil = {
         reportResponsibleManhourCost: false, // 负责项目子项目工时成本 //
         reportFTEAll: false, // 全部部门FTE报表 //
         reportFTEPart: false, // 负责部门FTE报表 // 
+        reportFTEPlanAll: false, // 全部部门FTE计划报表 // 
+        reportFTEPlanPart: false, // 负责部门FTE计划报表 // 
         reportEfficent: false, // 有效工时率 // 
         reportSortScaleTable: false, // 项目分类工时占比表 // 
         reportSortDetailTable: false, // 分类全部工时明细表 // 
@@ -256,6 +258,8 @@ const StringUtil = {
         arr[i] == '负责项目分组阶段工时' ? obj.reportStageWorkingTime = true : ''
         arr[i] == '全部部门FTE报表' ? obj.reportFTEAll = true : ''
         arr[i] == '负责部门FTE报表' ? obj.reportFTEPart = true : ''
+        arr[i] == '全部部门FTE计划报表' ? obj.reportFTEPlanAll = true : ''
+        arr[i] == '负责部门FTE计划报表' ? obj.reportFTEPlanPart = true : ''
         arr[i] == '有效工时率表' ? obj.reportEfficent = true : ''
         arr[i] == '项目预估工时表' ? obj.reportProjectEstimated = true : ''
         arr[i] == '任务研发报表' ? obj.taskPlanCost = true : ''

+ 89 - 9
fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/list.vue

@@ -50,6 +50,7 @@
                   <el-menu-item index="1-28" v-if="permissions.reportProjectEstimated" @click="ssl(27)"><p>{{ $t('xiangMuYuGuGongShiBiao') }}</p></el-menu-item>
                   <el-menu-item index="1-29" v-if="permissions.takCompletedStatus" @click="ssl(28)"><p>{{ $t('yuanGongRenWuWanChengQingKuangBiao') }}</p></el-menu-item>
                   <el-menu-item index="1-30" v-if="permissions.taskPlanCost" @click="ssl(29)"><p>{{ $t('taskPlanCostReport') }}</p></el-menu-item>
+                  <el-menu-item index="1-31" v-if="permissions.reportFTEPlanAll || permissions.reportFTEPlanPart" @click="ssl(30)"><p>FTE计划报表</p></el-menu-item>
                 </el-submenu>
               </el-menu>
           </el-col>
@@ -204,7 +205,7 @@
           </el-select>
           
           <!-- 地区筛选 -->
-          <el-select v-if="ins == 19" v-model="areaName" :placeholder="customNameChoose" @change="selcts()" clearable filterable size="small" style="margin-left:2px;width:150px">
+          <el-select v-if="ins == 19 || ins == 30" v-model="areaName" :placeholder="customNameChoose" @change="selcts()" clearable filterable size="small" style="margin-left:2px;width:150px">
             <el-option :label="item" :value="item" v-for="item,index in areaList" :key="index"></el-option>
           </el-select>
 
@@ -1506,6 +1507,27 @@
               <el-table-column align="center" prop="noOnTimeNum" :label="$t('yanChiWanChengShuLiang')" min-width="150"></el-table-column>
               <el-table-column align="center" prop="onTimePercent" :label="$t('anShiWanChengShuai')" min-width="150"></el-table-column>
             </el-table>
+
+            <!-- FTE 计划报表 -->
+            <el-table v-if="ins == 30"  key="30" border :data="fTEPlanDataList" highlight-current-row v-loading="listLoading" :height="+tableHeight - 1" style="width: 100%;" @sort-change="tableSort">
+              <el-table-column align="center" prop="area" :label="customName" min-width="150"></el-table-column>
+              <el-table-column align="center" prop="projectCode" :label="user.companyId == '7030' ? '项目令号' : $t('Itemno')" min-width="250"></el-table-column>
+              <el-table-column align="center" prop="projectName" :label="$t('headerTop.projectName')" min-width="250"></el-table-column>
+              <el-table-column align="center" prop="userName" :label="$t('renMing')" min-width="150" sortable="custom">
+                <template slot-scope="scope">
+                  <div>
+                    <span v-if="user.userNameNeedTranslate == '1'">
+                      <TranslationOpenDataText type='userName' :openid='scope.row.userName'></TranslationOpenDataText>
+                    </span>
+                    <span v-if="user.userNameNeedTranslate != '1'">
+                      {{scope.row.userName}}
+                    </span>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column align="center" prop="planHours" label="计划工时" min-width="150"></el-table-column>
+              <el-table-column align="center" prop="FTE" :label="'计划FTE(计划工时/当月计划工时基数)'" min-width="250"></el-table-column>
+          </el-table>
         <!--工具条-->
         <el-col :span="24" class="toolbar" v-if="ins != 6 && ins != 20 && ins != 21 && tabPosition==0 && tabsType == 'all'">
           <el-pagination
@@ -1879,11 +1901,11 @@ export default {
     return {
       themeColor: getThemeColor(),
       screeningCondition: { // 筛选条件的判断
-        project: [4, 8, 9, 10, 11, 14, 15, 17, 19, 20, 21, 22,28], // 项目筛选条件 (不等于)
+        project: [4, 8, 9, 10, 11, 14, 15, 17, 19, 20, 21, 22, 28, 30], // 项目筛选条件 (不等于)
         months: [14, 15], // 月份筛选条件 (等于)
-        monthRange: [19], // 月份区间筛选条件 (等于)
-        staff: [6, 8, 9, 19, 11, 14, 18, 23, 25, 26,28], // 人员筛选条件 (等于)
-        departments: [14, 15, 23,21,26,28,19], // 部门筛选条件 (等于)
+        monthRange: [19, 30], // 月份区间筛选条件 (等于)
+        staff: [6, 8, 9, 19, 11, 14, 18, 23, 25, 26,28, 30], // 人员筛选条件 (等于)
+        departments: [14, 15, 23,21,26,28,19, 30], // 部门筛选条件 (等于)
         timePeriod: [5, 6, 8, 9, 10, 11, 12, 16, 17, 18, 20, 21, 22, 24, 25, 26,28], // 时间段筛选条件 (等于)
       },
       efficentList:[],
@@ -1943,14 +1965,14 @@ export default {
       this.$t('statisticsofovertimework'),this.$t('timecostearlywarningtable'),this.$t('personneltimeallocationtable'),
       this.$t('statisticsofstafffillingintimerate'),this.$t('dailyreporttobereviewedstatistics'),this.$t('statisticsofpersonnelhours'),this.$t('taskgrouptimesheet'),this.$t('projectcostbaselinetable'),
       this.$t('ren-yuan-yue-du-gong-shi-biao'), this.$t('bumenchanyuqingkuang'), this.$t('ge-fen-zu-yu-jie-duan-gong-shi-biao'), this.$t('ziXiangMuGongShiChengBenBiao'), this.$t('renWuZhongQiBiao'), this.$t('fteBaoBiao'), this.$t('youXiaoGongShiShuaiBiao'), this.$t('xiangMuFenLeiGongShiZhanBiBiao'), this.$t('fenLeiGongShiMingXiBiao'),
-      this.$t('yuanGongXiangMuJinDuBiao'), this.$t('fenZuHaoYongJinDuBiao'), this.$t('xiangMuHaoYongJinDuBiao'), this.$t('yuanGongRenWuJinDuBiao'), this.$t('xiangMuYuGuGongShiBiao'),this.$t('yuanGongRenWuWanChengQingKuangBiao')],
+      this.$t('yuanGongXiangMuJinDuBiao'), this.$t('fenZuHaoYongJinDuBiao'), this.$t('xiangMuHaoYongJinDuBiao'), this.$t('yuanGongRenWuJinDuBiao'), this.$t('xiangMuYuGuGongShiBiao'),this.$t('yuanGongRenWuWanChengQingKuangBiao'), this.$t('taskPlanCostReport'), 'FTE计划报表'],
 
       shuzArr: [this.$t('projectreport'),this.$t('projectTaskReport'),this.$t('projectcoststatement'),
       this.$t('projectbalancesheet'),this.$t('customerprojectincomestatement'),this.$t('projectphasetimesheet'),
       this.$t('statisticsofovertimework'),this.$t('timecostearlywarningtable'),this.$t('personneltimeallocationtable'),
       this.$t('employeereporttimelinessrate'),this.$t('dailyreporttobereviewedstatistics'),this.$t('statisticsofpersonnelhours'),this.$t('taskgrouptimesheet'),this.$t('projectcostbaselinetable'),
       this.$t('ren-yuan-yue-du-gong-shi-biao'), this.$t('bumenchanyuqingkuang'), this.$t('ge-fen-zu-yu-jie-duan-gong-shi-biao'), this.$t('ziXiangMuGongShiChengBenBiao'), this.$t('renWuZhongQiBiao'), this.$t('fteBaoBiao'),this.$t('youXiaoGongShiShuaiBiao'), this.$t('xiangMuFenLeiGongShiZhanBiBiao'), this.$t('fenLeiGongShiMingXiBiao'),
-      this.$t('yuanGongXiangMuJinDuBiao'), this.$t('fenZuHaoYongJinDuBiao'), this.$t('xiangMuHaoYongJinDuBiao'), this.$t('yuanGongRenWuJinDuBiao'), this.$t('xiangMuYuGuGongShiBiao'),this.$t('yuanGongRenWuWanChengQingKuangBiao')],
+      this.$t('yuanGongXiangMuJinDuBiao'), this.$t('fenZuHaoYongJinDuBiao'), this.$t('xiangMuHaoYongJinDuBiao'), this.$t('yuanGongRenWuJinDuBiao'), this.$t('xiangMuYuGuGongShiBiao'),this.$t('yuanGongRenWuWanChengQingKuangBiao'), this.$t('taskPlanCostReport'), 'FTE计划报表'],
 
       ins: 10000,
       user: JSON.parse(sessionStorage.user),
@@ -2026,6 +2048,7 @@ export default {
 
       taskRestartArr: [], // 任务重启表数据
       fTEDataList: [], // FTE数据
+      fTEPlanDataList: [], // FTE计划数据
 
       baobiaoList: [],
 
@@ -2596,7 +2619,7 @@ export default {
                 this.getGroupWorktimeAll()
             },
             getList(e) {
-              let noUserList = [16, 17, 18, 19, 20, 21, 22, 24, 25, 26,27,29]
+              let noUserList = [16, 17, 18, 19, 20, 21, 22, 24, 25, 26,27,29,30]
               if(this.ins == 24) {
                 if(this.tabsType == 'all') {
                   this.rangeDatas = []
@@ -2653,6 +2676,9 @@ export default {
                 } else if(this.ins == 19) {
                   this.getETF()
                   this.getArea()
+                } else if(this.ins == 30) {
+                  this.getETFPlan()
+                  this.getArea()
                 } else if (this.ins == 20) {
                   this.getEffectiveLaborHourRate();
                 }
@@ -2847,7 +2873,14 @@ export default {
           sl.monthEnd= this.monthRange[1]+"-01"
           sl.area = this.areaName || null
           sl.departmentId = this.departmentIdArray.length > 0 ? this.departmentIdArray[this.departmentIdArray.length - 1] : ''
-        }else if(this.ins == 20) {
+        } else if(this.ins == 30) {
+          fName = 'FTE计划报表' + '.xlsx'
+          url += "/exportTaskPlanFTEData"
+          sl.monthStart= this.monthRange[0]+"-01"
+          sl.monthEnd= this.monthRange[1]+"-01"
+          sl.area = this.areaName || null
+          sl.departmentId = this.departmentIdArray.length > 0 ? this.departmentIdArray[this.departmentIdArray.length - 1] : ''
+        } else if(this.ins == 20) {
           fName = this.$t('youXiaoGongShiShuaiBiao') + '.xlsx'
           url = "/project/exportEffectiveLaborHourRate"
           sl.startDate = this.rangeDatas[0]
@@ -3123,6 +3156,53 @@ export default {
           });
       });
     },
+    getETFPlan() {
+      this.getCustomName();
+      this.listLoading = true;
+      let parameter = {
+        monthStart: this.monthRange[0]+"-01",
+        monthEnd: this.monthRange[1]+"-01",
+        area: this.areaName || null,
+        userId:this.userId,
+        pageIndex: this.page,
+        pageSize: this.size
+      }
+      if(this.departmentIdArray.length != 0){
+        parameter.departmentId = this.departmentIdArray[this.departmentIdArray.length - 1]
+      }
+      if(this.sortOrder){
+          if(this.sortProp == 'userName'){
+              parameter.sortProp = "id"
+          }
+          if(this.sortOrder == 'descending'){
+              parameter.sortOrder = 0
+          }else if(this.sortOrder == 'ascending'){
+              parameter.sortOrder = 1
+          }
+      }
+      this.http.post('/project/getProjectTaskPlanFTEData', parameter,
+      res => {
+          if (res.code == "ok") {
+              for (var i in res.data.resultList) {
+                res.data.resultList[i].FTE = res.data.resultList[i].FTE.toFixed(2)
+              }
+              this.fTEPlanDataList = res.data.resultList;
+              this.total = res.data.total;
+              this.listLoading = false; 
+          } else {
+              this.$message({
+              message: res.msg,
+              type: "error"
+              });
+          }
+      },
+      error => {
+          this.$message({
+              message: error,
+              type: "error"
+          });
+      });
+    },
     getArea() {
       this.http.post('/user/areaData', {},
       res => {

+ 360 - 194
fhKeeper/formulahousekeeper/timesheet/src/views/project/gantt.vue

@@ -1,98 +1,179 @@
-{{ src/components/Gantt.vue }}
 <template>
-  <div ref="ganttContainer">
-  </div>
+  <div class="ganttContainerBox">
+    <div ref="ganttContainer" style="height: 100%;">
+    </div>
     <!-- 任务详情信息弹出框 -->
-    <!-- <el-dialog :class="addForm.id==null?'':'jm'" :title="title" v-if="taskFormVisible" :visible.sync="taskFormVisible" 
-      :close-on-click-modal="false" customClass="customWidth" width="840px" :top="'6vh'">
-          <taskComponent ref="thskComponents" :integrationTask="integrationTask" :showOrNot="showOrNot" @closeBounced="closeBounced"></taskComponent>
-          <div slot="title" v-if="addForm.parentTid != null">
-              <el-page-header  @back="backToParentTask" :title="$t('parenttask')" :content="addForm.parentTname"></el-page-header>
-          </div>
-      </el-dialog> -->
-  
+    <el-dialog :class="''" :title="title" v-if="addFormVisible" append-to-body
+      :visible.sync="addFormVisible" :close-on-click-modal="false" customClass="customWidth" width="840px" :top="'6vh'">
+      <taskComponent ref="thskComponents" :integrationTask="integrationTask" :showOrNot="showOrNot"
+        @closeBounced="closeBounced" :showMmeiLaiDe="true" :showMmeiLaiDeData="showMmeiLaiDeData"></taskComponent>
+      <div slot="title" v-if="addForm.parentTid != null">
+        <el-page-header @back="backToParentTask" :title="$t('parenttask')"
+          :content="addForm.parentTname"></el-page-header>
+      </div>
+    </el-dialog>
+  </div>
 </template>
 
 <script>
-
-   
-import {gantt} from 'dhtmlx-gantt';
+import { gantt } from 'dhtmlx-gantt';
 // import 'dhtmlx-gantt/codebase/dhtmlxgantt.css'
 // import 'dhtmlx-gantt/codebase/locale/locale_cn'  // 本地化
+import taskComponent from "@/components/taskComponent.vue"
 export default {
   name: 'gantt',
+  components: {
+    taskComponent
+  },
   props: {
     tasks: {
       type: Object,
-      default () {
-        return {data: [], links: []}
+      default() {
+        return { data: [], links: [] }
       }
     },
     stafforpro: '',
-    valueDate:[],
+    valueDate: [],
   },
   data() {
     return {
-      containerRect:null,
+      containerRect: null,
       taskFormVisible: false,
-      addForm:null,
+      addForm: {},
       addLoading: false,
-      title: this.$t('createtask '),
-      commentList:[],
+      title: '创建计划',
+      commentList: [],
+      dynamicTab: true,
       showOrNot: false,
-      integrationTask:null,
+      integrationTask: null,
       taskComponentFlg: false,
+      addFormVisible: false,
+      integrationTaskNingwai: {},
+      integrationTask: {},
+      user: JSON.parse(sessionStorage.getItem("user")),
+      showMmeiLaiDeData: {},
     };
   },
-  created:function(){
+  created: function () {
     // gantt.clearAll()
     // console.log("tasks",this.$props.tasks);
   },
- 
+
   methods: {
-    handleEmptyClick(event) {
-      const x = event.clientX - this.containerRect.left;
-      const y = event.clientY - this.containerRect.top;
+    getDistanceToParent(element, parent) {
+      let distance = 0;
+      while (element && element !== parent) {
+        distance += element.offsetTop;  // 获取当前元素相对于父元素顶部的距离
+        element = element.offsetParent; // 获取上一级父元素
+      }
+      return distance;
+    },
+    closeBounced(obj) {
+      console.log(obj, '<======== 点击事件')
+      if (!obj.backToParentTaskSub) {
+        this.addFormVisible = false
+        this.taskComponentFlg = false
 
-      // 获取点击位置对应的时间轴日期
-      const date = gantt.dateFromPos(x);
-      console.log(date);
+        if (obj.submitInsert) {
+          this.$emit('closeBounced', obj)
+        }
 
-      // this.addTask();
+        if(obj.deleteTask) {
+          this.$emit('closeBounced', obj)
+        }
+      }
+    },
+    backToParentTask() {
+      console.log('点击, <======== 点击了backToParentTask')
     },
-    addTask() {
-        this.taskFormVisible = true;
-        // this.addForm = {projectId: stage.projectId, groupId: stage.groupId, stagesId: stage.id, taskLevel:0, planHours: 8, taskType: 0};
-        this.addForm = {projectId: '', groupId: '', stagesId: '', taskLevel:0, planHours: 8, taskType: 0};
-        this.addLoading = false;
-        this.title=this.$t('createtask ');
-        this.commentList = [];
-        this.showOrNot = true
-
-        let obj = {
-            create: true,
-            addForm: this.addForm,
-            executorListFront: [{executorId:null, planHours:8}],
-            stage: this.addForm,
-            integrationTaskNingwai: this.integrationTaskNingwai,
-            taskVue: true,         
-            meetingId: this.addForm.meetingId
+    addTask(row) {
+      this.showOrNot = true
+      this.addForm = {
+        projectId: '', groupId: '', stagesId: '', taskLevel: 0, planHours: 8, taskType: 0, startDate: row.date
+      }
+      const userIdList = (row.userId && row.userId.split(',')) || []
+      const executorListFront = userIdList.map(item => {
+        return {
+          executorId: item,
+          planHours: 8
         }
-        this.integrationTask = obj
+      })
+      let obj = {
+        create: true,
+        addForm: this.addForm,
+        executorListFront,
+        stage: this.addForm,
+        integrationTaskNingwai: this.integrationTaskNingwai,
+        taskVue: true,
+        meetingId: this.addForm.meetingId
+      }
+      this.integrationTask = obj
+      this.addFormVisible = true
+    },
+    editTask(row) {
+      this.showOrNot = true
+      this.http.post('/task/getTask', { id: row.taskId },
+        res => {
+          if (res.code == "ok") {
+            const data = res.data
+            if(this.user.roleId != 2283 && !data.executorId) {
+              this.$message({
+                message: '这条数据只有区域经理才能分配',
+                type: 'warning'
+              });
+              return
+            }
+            this.addForm = {
+              id: data.id
+            }
+            this.integrationTask = {
+              id: data.id,
+              task: data,
+              num: 1,
+              curProjectId: data.projectId || '',
+              create: false,
+              integrationTaskNingwai: {
+                groupId: data.groupId,
+                isDesc: false,
+                order: "seq",
+                projectId: data.projectId || '',
+              },
+              taskVue: data.projectId ? false : true,
+              meetingId: this.addForm.meetingId
+            }
 
-        this.taskComponentFlg = true
+            this.addFormVisible = true
+          } else {
+            this.$message({ message: res.msg, type: "error" });
+          }
+        },
+        error => {
+          this.$message({ message: error, type: "error" });
+        });
+    },
+    handleEmptyClick(row) {
+      if (row.taskId) {
+        // 编辑任务
+        this.title = '编辑计划'
+        this.editTask(row)
+      } else {
+        // 新增任务
+        this.title = '创建计划'
+        this.addTask(row)
+      }
     },
   },
   mounted: function () {
+    const userInfo = JSON.parse(sessionStorage.getItem("user"));
     gantt.clearAll()
-    gantt.locale={
-    date: {
+    gantt.locale = {
+      date: {
         month_full: [this.$t('yiYue'), this.$t('erYue'), this.$t('sanYue'), this.$t('siYue'), this.$t('thisTWuyue'), this.$t('liuYue'), this.$t('qiYue'), this.$t('baYue'), this.$t('jiuYue'), this.$t('shiYue'), this.$t('shiYiYue'), this.$t('shiErYue')],
         month_short: [this.$t('1Yue'), this.$t('2Yue'), this.$t('3Yue'), this.$t('4Yue'), this.$t('5Yue'), this.$t('6Yue'), this.$t('7Yue'), this.$t('8Yue'), this.$t('9Yue'), this.$t('10Yue'), this.$t('11Yue'), this.$t('12Yue')],
         day_full: [this.$t('xingQiRi'), this.$t('xingQiYi'), this.$t('xingQiEr'), this.$t('xingQiSan'), this.$t('xingQiSi'), this.$t('xingQiWu'), this.$t('xingQiLiu')],
         day_short: [this.$t('ri'), "一", "二", "三", "四", "五", "六"]
-    },
-    labels: {
+      },
+      labels: {
         dhx_cal_today_button: this.$t('jinTian'),
         day_tab: this.$t('weekDay.day'),
         week_tab: this.$t('zhou'),
@@ -133,68 +214,27 @@ export default {
         weeks: this.$t('zhou'),
         months: this.$t('weekDay.month'),
         years: this.$t('nian')
-    }
-};
+      }
+    };
     // gantt.config.autosize = true;
     // gantt.config.duration_unit = "hour";
     gantt.config.fit_tasks = true;
     gantt.config.drag_move = false;
     gantt.config.xml_date = "%Y-%m-%d";
-    gantt.config.columns=[
-        {name:"text",label:(this.stafforpro == this.$t('anRenYuanChaKan') ? this.$t('lable.name') : this.$t('headerTop.projectName')), align: "left", tree:true},
-        // {name:"time",label:"计划工时(h)", align: "center" }
-        // {name:"start_date", label:"开始时间", width:'*' , align: "center" },
-        // {name:"duration",   label:"工时(天)", width:'*' ,   align: "center" }
+    gantt.config.columns = [
+      { name: "text", label: (this.stafforpro == this.$t('anRenYuanChaKan') ? this.$t('lable.name') : this.$t('headerTop.projectName')), align: "left", tree: true },
+      // {name:"time",label:"计划工时(h)", align: "center" }
+      // {name:"start_date", label:"开始时间", width:'*' , align: "center" },
+      // {name:"duration",   label:"工时(天)", width:'*' ,   align: "center" }
     ];
     gantt.config.scale_unit = "month";	//按月显示
-	  gantt.config.date_scale = "%F, %Y";		//设置时间刻度的格式(X轴) 多个尺度
+    gantt.config.date_scale = "%F, %Y";		//设置时间刻度的格式(X轴) 多个尺度
 
-	  gantt.config.scale_height = 50; //设置时间刻度的高度和网格的标题
+    gantt.config.scale_height = 50; //设置时间刻度的高度和网格的标题
     gantt.config.open_tree_initially = true;
-// gantt.config.layout = {
-//     css: "gantt_container",
-//     rows:[
-//         {
-//            cols: [
-//             {
-//               // the default grid view  
-//               view: "grid",  
-//               scrollX:"scrollHor", 
-//               scrollY:"scrollVer"
-//             },
-//             { resizer: true, width: 2 },
-//             {
-//               // the default timeline view
-//               view: "timeline", 
-//               scrollX:"scrollHor", 
-//               scrollY:"scrollVer"
-//             },
-//             {
-//               view: "scrollbar", 
-//               id:"scrollVer"
-//             }
-//         ]},
-//         {
-//             view: "scrollbar", 
-//             id:"scrollHor"
-//         }
-//     ]
-// }
-// gantt.templates.task_time = function(start,end,task){
-//   console.log('startend',start,end,task);
-//   let Jstart = JSON.parse(JSON.stringify(start))
-//   let Jend = JSON.parse(JSON.stringify(end))
-//   let estartmonth = Jstart.getMonth() + 1
-//   let estartday = Jstart.getDate()
-//   let estart = Jstart.getFullYear() + '-' + (estartmonth < 10 ? '0' + estartmonth : estartmonth) + '-' + (estartday < 10 ? '0' + estartday : estartday)
-//   let tend = new Date(Jend.setDate(end.getDate() - 1))
-//   let eendmonth = tend.getMonth() + 1
-//   let eendday = tend.getDate()
-//   let eend = tend.getFullYear() + '-' + (eendmonth < 10 ? '0' + eendmonth : eendmonth) + '-' + (eendday < 10 ? '0' + eendday : eendday)
-//   return estart + ' ' + eend
-// };
+
     gantt.config.subscales = [
-      {unit: "day", step: 1, date: "周%D,%d"}
+      { unit: "day", step: 1, date: "周%D,%d" }
     ];
     gantt.config.buttons_left = []
     gantt.config.buttons_right = ["gantt_cancel_btn"]
@@ -203,7 +243,7 @@ export default {
     gantt.config.drag_progress = false
     gantt.config.details_on_dblclick = false
     gantt.config.lightbox.sections = [
-      {name:"description", height:76, map_to:"text", type:"textarea",focus:true}
+      { name: "description", height: 76, map_to: "text", type: "textarea", focus: true }
     ];
 
     gantt.config.start_date = new Date(this.valueDate[0]);
@@ -211,126 +251,252 @@ export default {
 
     //设置任务条样式
     gantt.templates.task_class = function (start, end, item) {
-      return item.parent == 0 ? "person_line" : ""
+      return item.taskPlanType == 3 ? "error_line" : "person_line"
+    };
+
+    // 设置任务条内容显示
+    gantt.templates.task_text = function (start, end, task) {
+      const { leaderOrManager, taskPlan, taskStatus } = task
+      // 都审核通过
+      if(taskPlan == 1 && taskStatus == 0 && task.text == '请假') {
+        return `<div class="task_text">
+            <div style="background: '#ff5757'">${task.text}</div>
+          </div>`
+      }
+
+      if(taskPlan == 1 && taskStatus == 0) {
+        return `<div class="task_text">
+            <div class="exclamation-circle circle" style="color: ${task.taskPlanType == 3 ? '#f56c6c' : '#8ecaf8'}">V</div>
+            <div class="exclamation-circle circle" style="color: ${task.taskPlanType == 3 ? '#f56c6c' : '#8ecaf8'}">V</div>
+            <div>${task.text}</div>
+          </div>`
+      }
+
+      // 小组长
+      // if (userInfo.projectLeaderType == 1) {
+      if (leaderOrManager == 1) {
+        return `<div class="task_text">
+          ${task.taskStatus == 3 ? `<div class="circle" style="color: ${task.taskPlanType == 3 ? '#f56c6c' : '#8ecaf8'}">!</div> <div class="circle"></div>` : ''}
+          ${task.taskStatus == 4 ? `<div class="exclamation-circle circle" style="color: ${task.taskPlanType == 3 ? '#f56c6c' : '#8ecaf8'}">V</div> <div class="circle"></div>` : ''}
+          ${task.taskStatus == 5 ? `<div class="exclamation-circle circle" style="color: ${task.taskPlanType == 3 ? '#f56c6c' : '#8ecaf8'}">!</div> <div class="circle"></div>` : ''}
+          ${task.taskStatus == 6 ? `<div class="exclamation-circle circle" style="color: ${task.taskPlanType == 3 ? '#f56c6c' : '#8ecaf8'}">V</div> <div class="exclamation-circle circle" style="color: ${task.taskPlanType == 3 ? '#f56c6c' : '#8ecaf8'}">!</div>` : ''}
+          <div>${task.text}</div>
+        </div>`;
+      }
+
+      // 审核人
+      // if (userInfo.projectLeaderType == 2) {
+      if (leaderOrManager == 2) {
+        return `<div class="task_text statuss">
+            ${task.taskStatus == 3 || task.taskStatus == 4 ? `<div class="circle">
+              <div class="pendingReviewOfCornerMarkers">!</div>
+            </div>` : ''}
+            <div>${task.text}</div>
+          </div>`
+      }
+
+      // 正常人
+      return `<div class="task_text">
+          <div>${task.text}</div>
+        </div>`;
     };
     gantt.config.grid_width = 350;
-    gantt.plugins({tooltip: true});
+    gantt.plugins({ tooltip: true });
     gantt.templates.tooltip_text = function (start, end, task) {
       return
     };
-            
-    // gantt.ext.tooltips.tooltip.show = function(event){
-    //   // console.log('show', event);
-     
-    // }
-    // console.log('show',gantt.ext.tooltips.tooltip.show);
-    // gantt.ext.tooltips.tooltip = {
-    //   getNode: function (params) {
-    //     // console.log('getNode',params);
-    //   },
-    //   hide: function(){
-    //     // console.log('hide');
-    //   },
-    //   setContent: function(){
-    //     // console.log('setContent');
-    //   },
-    //   show: function(event){
-    //     console.log('show',event);
-    //   },
-
-    // }
-    // 给每行增加双击事件 ,亲测事件会重复注册,用这个方法拦截一下
-    if (this.onTaskDblClick) gantt.detachEvent(this.onTaskDblClick);
-    // 双击bar任务事件(单击会有问题,点击展开时也会触发)
-    this.onTaskDblClick = gantt.attachEvent("onTaskDblClick", (id, e) => {
-      console.log('=====在这里,开始显示任务弹窗编辑任务===id=='+id+", e="+e);
-        this.$emit('rowDbClick',id)
-        return true;
-    }, { id: 'onTaskDblClick' })
 
     gantt.ext.tooltips.attach({
       selector: '.gantt_grid [' + gantt.config.task_attribute + ']',
-      onmouseenter: (event,node) => {
-        if(node.textContent.length > 19){
+      onmouseenter: (event, node) => {
+        if (node.textContent.length > 19) {
           let sdom = document.createElement('span')
           sdom.innerText = node.innerText
           sdom.className = 'tooltiptext'
           node.appendChild(sdom)
         }
-        
+
       },
-      onmousemove: () => {},
-      onmouseleave: (event,node) => {
+      onmousemove: () => { },
+      onmouseleave: (event, node) => {
         let sdom = document.getElementsByClassName('tooltiptext')[0]
-        if(sdom){node.removeChild(sdom)}
-        
+        if (sdom) { node.removeChild(sdom) }
+
       },
-      // html: (event,node) => {
-      //   const targetTaskId = gantt.locate(event)
-      //   const task = gantt.getTask(targetTaskId)
-      //   return gantt.templates.tooltip_text(null,null,task)
-      // },
       global: true
     })
 
-    // 绑定空白点击事件
-    gantt.attachEvent("onEmptyClick", (event) => {
-      this.handleEmptyClick(event);
-      return true; // 阻止默认行为
+    // 双击事件
+    this.$refs.ganttContainer.addEventListener('dblclick', (event) => {
+      const taskIdStr = gantt.locate(event);
+      if(userInfo.projectLeaderType != 1 && userInfo.projectLeaderType != 2) {
+        return
+      }
+      this.showMmeiLaiDeData = {}
+      if (taskIdStr && gantt.isTaskExists(taskIdStr)) {
+        // 编辑任务
+        const rows = gantt.getTask(taskIdStr)
+        if (rows.id.indexOf('任务') != '-1') {
+          const value = taskIdStr.split('任务_')[1]
+          const taskId = value.split('_')[0]
+          this.showMmeiLaiDeData = rows
+          this.handleEmptyClick({ taskId })
+        }
+      } else {
+        if(userInfo.projectLeaderType != 1) {
+          return
+        }
+        // 获取 gantt_grid_data 容器
+        const ganttGrid = document.querySelector('.gantt_grid_data');
+        if (!ganttGrid) return;
+        // // 计算点击位置
+        const gridRect = ganttGrid.getBoundingClientRect();
+        // const clickY = event.clientY - gridRect.top; // 相对 gantt_grid_data 的 Y 轴偏移量
+
+        // // 获取任务行
+        // const rows = ganttGrid.querySelectorAll('.gantt_row');
+        // const rowHeight = rows.length > 0 ? rows[0].offsetHeight : 34; // 获取行高 (默认 40px)
+        // // 计算索引
+        // const rowIndex = Math.floor(clickY / rowHeight);
+        // if (rowIndex >= rows.length || rowIndex < 0) return;
+
+        // // 获取任务 ID
+        // const rowElement = rows[rowIndex];
+
+        // 新写的
+        const rows = ganttGrid.querySelectorAll('.gantt_row');
+        const clickedElement = event.toElement;  // 当前点击的元素
+        const parentElement = clickedElement.closest('.gantt_task_row');
+        const yzhozhi = this.getDistanceToParent(parentElement) - 219 // 219 固定值
+        const yCoordinate = +((yzhozhi / 35).toFixed(0)) * 35
+        let rowIndexs = 0
+        for(const em in rows) {
+          const str = (rows[em].style && rows[em].style.top) || '-1px'
+          const nums = str.split('px')[0]
+          if(nums == yCoordinate) {
+            rowIndexs = em
+          }
+        }
+        const rowElement = rows[rowIndexs]
+        console.log(yCoordinate, rowIndexs)
+        console.log(rowElement, '<,,,,,,,,,,=============== rowElement')
+
+        const taskIdFromRow = rowElement.getAttribute('task_id'); // 获取任务 ID
+        if (taskIdFromRow && gantt.isTaskExists(taskIdFromRow)) {
+          const taskData = gantt.getTask(taskIdFromRow);
+          console.log(taskData, '<=== taskData')
+          if (taskData.userId) {
+            // 新增任务
+            let rollingDistance = 0
+            const scrollElement = this.$refs.ganttContainer.querySelector('.gantt_hor_scroll');
+            if (scrollElement) {
+              rollingDistance = scrollElement.scrollLeft || 0
+            }
+            const userId = taskData.userId;
+            const gridX = event.clientX - gridRect.left; // 相对 gantt_grid_data 的 X 轴偏移量
+            const date = gantt.dateFromPos((gridX - 349) + rollingDistance);
+            console.log('点击的日期:', date, this.dayjs(date).format('YYYY-MM-DD'));
+            this.handleEmptyClick({ userId, date: this.dayjs(date).format('YYYY-MM-DD') })
+          }
+        }
+      }
     });
-    
-    
+
     gantt.init(this.$refs.ganttContainer);
-    console.log('===初始化Init gantt===');
-    console.log(this.$refs.ganttContainer)
     this.containerRect = this.$refs.ganttContainer.getBoundingClientRect();
-    // this.$props.tasks.data[31].render = "split"
     gantt.parse(this.$props.tasks);
-    
-    // gantt.groupBy({
-    //     relation_property: "owner",
-    //     groups: [{key:'seya', label: "seya"},{key:'tina', label: "tina"}],
-    //     group_id: "key",
-    //     group_text: "label"
-    // });
-    // console.log("props",gantt);
   }
 }
 
 </script>
- 
+
 <style>
-    @import "~dhtmlx-gantt/codebase/dhtmlxgantt.css";
-    .person_line {
-      background:#8ecaf8;
-      border: 1px solid;
-      @include border_color("border_color");
-    }
-    /* .gantt_tooltip{
+@import "~dhtmlx-gantt/codebase/dhtmlxgantt.css";
+
+.person_line {
+  background: #8ecaf8;
+  border: 1px solid;
+  @include border_color("border_color");
+}
+
+.error_line {
+  background: #ff5757;
+  border: 1px solid;
+  border: #ff5757;
+}
+
+.task_text {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  width: 100%;
+}
+
+.task_text>div {
+  flex: 0 0 auto;
+}
+
+.circle {
+  width: 10px;
+  height: 10px;
+  border-radius: 50%;
+  border: 2px solid #fff;
+  margin-left: 4px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.exclamation-circle {
+  background: #fff;
+  font-size: 12px;
+  font-weight: bold;
+}
+
+.pendingReviewOfCornerMarkers {
+  width: 100%;
+  height: 100%;
+  border-radius: 50%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  background: #fdba6e;
+  font-weight: bold;
+}
+
+.statuss .circle {
+  border-color: #fdba6e;
+}
+
+
+/* .gantt_tooltip{
       z-index: 10000;
       top: 10px !important;
       left: 10px !important;
     } */
-    .tooltiptext{
-      visibility: visible;
-      background-color: #fff;
-      color: #454545;
-      box-shadow: 3px 3px 3px rgba(0,0,0,.07);
-      border-left: 1px solid rgba(0,0,0,.07);
-      border-top: 1px solid rgba(0,0,0,.07);
-      font-size: 8pt;
-      line-height: 20px;
-      padding: 10px;
-      /* opacity: 0;
+.tooltiptext {
+  visibility: visible;
+  background-color: #fff;
+  color: #454545;
+  box-shadow: 3px 3px 3px rgba(0, 0, 0, .07);
+  border-left: 1px solid rgba(0, 0, 0, .07);
+  border-top: 1px solid rgba(0, 0, 0, .07);
+  font-size: 8pt;
+  line-height: 20px;
+  padding: 10px;
+  /* opacity: 0;
       transition: 0.5s; */
 
-      position: absolute;
-      z-index: 10000;
-      bottom: 120%;
-      left: 25px;
-      max-width: 300px;
-      /* word-wrap: break-word;
+  position: absolute;
+  z-index: 10000;
+  bottom: 120%;
+  left: 25px;
+  max-width: 300px;
+  /* word-wrap: break-word;
       word-break: break-all; */
-      white-space: pre-wrap;
-    }
+  white-space: pre-wrap;
+}
 </style>

+ 27 - 6
fhKeeper/formulahousekeeper/timesheet/src/views/project/list.vue

@@ -502,7 +502,7 @@
                         </el-select>
                     </el-form-item>
 
-                    <el-form-item :label="yonghuUser.customDegreeName" v-if="yonghuUser.customDegreeActive == 1">
+                    <el-form-item :label="yonghuUser.customDegreeName" v-if="yonghuUser.customDegreeActive == 1 && user.timeType.customDegreeWithPro != 0">
                         <el-select v-model="auseList" multiple :placeholder="$t('defaultText.pleaseChoose')" filterable="true" style="width: 100%" :disabled="canOnlyModParticipator">
                             <span v-for="(item, index) in ause" :key="index">
                             <el-option :label="item.name" :value="item.id"></el-option>
@@ -516,12 +516,12 @@
                     </el-form-item> -->
                     <el-form-item :label="$t('Allparticipants')" v-show="addForm.isPublic == 0" :class="title == $t('newproject') && user.companyId == 936 ? 'wpgCssClass' : ''">
                         <el-tooltip placement="top" effect="light" v-if="user.userNameNeedTranslate != 1">
-                            <div slot="content" style="width:780px">{{addForm.userNames}}</div>
+                            <div slot="content" style="width:580px">{{addForm.userNames}}</div>
                             <el-input  @focus="showChooseMembTree" v-model="addForm.userNames"></el-input>
                         </el-tooltip>
 
                         <el-tooltip placement="top" effect="light" v-if="user.userNameNeedTranslate == 1">
-                            <div slot="content" style="max-width: 780px;max-height: 400px;overflow-y: auto;">
+                            <div slot="content" style="max-width: 580px;max-height: 400px;overflow-y: auto;">
                                 <span v-for="(item, index) in addFormUserNames" :key="index">
                                     <TranslationOpenDataText type='userName' :openid='item'></TranslationOpenDataText>
                                     <span v-if="index < addFormUserNames.length - 1">,</span>
@@ -539,7 +539,7 @@
                         </el-tooltip>
                     </el-form-item>
                     <el-form-item :label="$t('projectmanager')" :class="title == $t('newproject') && user.companyId == 936 ? 'wpgCssClass' : ''" v-if="user.company.nonProjectSimple == 0 || (user.company.nonProjectSimple == 1 && addForm.isPublic == 0)">
-                       <el-select v-if="user.userNameNeedTranslate != 1" v-model="addForm.inchargerId" filterable :placeholder="$t('defaultText.pleaseChoose')" style="width:32%;" :disabled="canOnlyModParticipator || projectManagerEdit">
+                       <el-select v-if="user.userNameNeedTranslate != 1" v-model="addForm.inchargerId" filterable :placeholder="$t('defaultText.pleaseChoose')" style="width:32%;" :disabled="canOnlyModParticipator || projectManagerEdit" @change="changeInchargerId">
                             <el-option v-for="item in participator" :key="item.id" :label="item.name" :value="item.id">
                                 <span style="float: left">{{ item.name }}</span>
                                 <span style="float: right; color: #8492a6;" v-if="user.companyId == 936">{{ item.jobNumber }}</span>
@@ -558,6 +558,12 @@
                         <selectCat v-if="user.timeType.reportAuditType == 8 && user.userNameNeedTranslate == 1" :filterable="true" :size="'medium'" :subject="users" :subjectId="addForm.reviwerId" :distinction="'4'" @selectCal="selectCal" :disabled="canOnlyModParticipator || projectManagerEdit || isShowProjectName"></selectCat>
                     </el-form-item>
 
+                    <el-form-item label="LA" v-if="user.companyId == 876">
+                        <el-select v-model="addForm.leaderId" multiple placeholder="请选择LA" filterable style="width: 100%">
+                            <el-option v-for="item in (participator || []).filter(em => em.id != addForm.inchargerId)" :key="item.id" :label="item.name" :value="item.id"></el-option>
+                          </el-select>
+                    </el-form-item>
+
                     <span v-if="user.companyId != 469">
                         <el-form-item :label="$t('newspaperauditor')" v-show="user.timeType.reportAuditType == 0 || user.timeType.reportAuditType == 4 || user.timeType.reportAuditType == 6 || user.timeType.reportAuditType == 9" v-if="user.company.nonProjectSimple == 0 || (user.company.nonProjectSimple == 1 && addForm.isPublic == 0)">
                             <el-select v-if="user.userNameNeedTranslate != '1'" @change="$forceUpdate()" v-model="addForm.auditUserIds"  :disabled="!(permissions.projectManagement|| user.id == addForm.inchargerId || user.id == addForm.creatorId)" filterable :placeholder="$t('defaultistheprojectleader')" style="width:100%;" :multiple="user.timeType.reportAuditType != 6 && user.timeType.reportAuditType != 9" >
@@ -3933,7 +3939,12 @@ a {
                 var list = chosenList.filter(item=>item.isUser == 1);
                 this.chosenMembCount = list.length;
             },
-
+            changeInchargerId() {
+                if(this.user.companyId == 876) {
+                    const userList = this.addForm.leaderId || []
+                    this.addForm.leaderId = userList.filter(item => item != this.addForm.inchargerId)
+                }
+            },
             showChooseMembTree() {
                 this.deptMembData = JSON.parse(JSON.stringify(this.allMembData))
                 this.chosenMembCount = this.participator.length;
@@ -5076,6 +5087,7 @@ a {
                         this.$set(this.addForm, 'region', '')
                         this.$set(this.addForm, 'bu', '')
                     }
+                    
                     if(this.user.timeType.projectManDay){
                         this.$set(this.addForm, 'manDay',0)
                         this.$set(this.addForm, 'manDayStartDate','')
@@ -5227,7 +5239,12 @@ a {
                             this.$set(this.addForm, 'bu', '')
                         }
                     }
-                    console.log(111111)
+                    // 米莱的的LA
+                    if(this.user.companyId == 876) {
+                        const leaderListList = item.leaderList || []
+                        const leaderListListId = leaderListList.map(id => id.leaderId)
+                        this.$set(this.addForm, 'leaderId', leaderListListId)
+                    }
                     // 判断是否有供应商
                     if(this.user.company.packageProvider) {
                         if(item.providerIds) {
@@ -5614,6 +5631,10 @@ a {
                             formData.append('reviwerId', this.addForm.reviwerId);
                         }
 
+                        if((this.addForm.leaderId || []).length > 0) {
+                            formData.append('leaderIds', this.addForm.leaderId);
+                        }
+
                         const deptListNew = this.addForm.deptIds.filter(item => item)
                         formData.append('deptIds', deptListNew.join(','))
                         this.http.uploadFile(this.port.project.add,formData,

+ 6 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/project/project_gantt.vue

@@ -78,7 +78,7 @@
     <gantt v-if="isDataLoaded && user.userNameNeedTranslate != 1" ref="ganttTable1" class="left-container" :tasks="tasks" 
     :stafforpro="radio1"
     :valueDate="valueDate"
-    :key="updatakey1"></gantt>
+    :key="updatakey1" @closeBounced="closeBounced"></gantt>
     <vueGantt v-if="isDataLoaded && user.userNameNeedTranslate == 1" ref="ganttTable1" :stafforpro="radio1"
     :valueDate="valueDate"
     :key="updatakey1" :tasks="tasks"></vueGantt>
@@ -242,6 +242,11 @@ export default {
     this.isDataLoaded = true
   },
   methods: {
+    closeBounced(obj) {
+      if(obj.submitInsert) {
+        this.dateupdata()
+      }
+    },
     selectCal(obj) {
       if(obj.distinction == '1') {
           this.valuex = obj.id