daily.vue 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578
  1. <template>
  2. <section>
  3. <!--工具条-->
  4. <!-- <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
  5. <el-form :inline="true">
  6. <el-form-item>
  7. <el-date-picker v-model="date" :editable="false" format="yyyy-MM" value-format="yyyy-MM" @change="changeMonthOut" :clearable="false" type="month" placeholder="选择月份"></el-date-picker>
  8. </el-form-item>
  9. </el-form>
  10. </el-col> -->
  11. <!--列表-->
  12. <div>
  13. <el-card class="box-card daily" shadow="never">
  14. <div slot="header" class="clearfix" id="clearfix" style="padding-left: 195px;">
  15. <div class="jjk" style="display:inline-block;position:fixed;top:70px;background:#fff;left:250px;">
  16. <el-date-picker size="small" v-model="date" :editable="false" format="yyyy-MM" value-format="yyyy-MM" style="width:190px;"
  17. @change="changeMonthOut" :clearable="false" type="month" placeholder="选择月份"></el-date-picker>
  18. </div>
  19. <span v-for="(item,index) in allDate" :id="'day'+index" :class="index==choseDay?'chooseDate date_item':'date_item'"
  20. @click="choseDate(index, item)" :key="index" >
  21. <div :style="'display:inline-block;'+(item.state == null?'padding:0px 6px;':'')" >
  22. <div><span>{{item.showDate}}</span>
  23. <span style="font-size:10px;text-align:center;color:#999;">{{item.weekDay}}</span>
  24. </div>
  25. </div>
  26. <i v-if="item.state != null" class="iconfont firerock-icondot" :class="statusStyle[item.state]"></i>
  27. </span>
  28. </div>
  29. <div style="display:flex;">
  30. <div v-if="user.role > 0 || user.manageDeptId != 0" >
  31. <div style="width:190px;">
  32. <el-select v-model="selectState" size="small" @change="stateChange" >
  33. <el-option value="-1" label="全部状态" >全部状态</el-option>
  34. <el-option value="-2" label="未填报">未填报</el-option>
  35. <el-option value="1" label="已通过">已通过</el-option>
  36. <el-option value="0" label="待审核">待审核</el-option>
  37. <el-option value="2" label="不通过">不通过</el-option>
  38. <el-option value="3" label="已撤回">已撤回</el-option>
  39. </el-select></div>
  40. <div>
  41. <el-tree :data="data" @node-click="handleNodeClick" >
  42. <span class="custom-tree-node" slot-scope="{ node, data}">
  43. <span>{{ node.label }}</span>
  44. <span v-if="data.membCount != null && data.isUser == null">({{data.membCount}})</span>
  45. <div style="width:0%;float:right;">
  46. <span v-if="data.isUser == 1 && data.state == null" style="color:red;">
  47. 未填报
  48. </span>
  49. <span v-if="data.isUser == 1 && data.state == 0" style="color:orange;">
  50. 待审核
  51. </span>
  52. <span v-if="data.isUser == 1 && data.state == 1" style="color:green;">
  53. 已通过
  54. </span>
  55. <span v-if="data.isUser == 1 && data.state == 2" style="color:red;">
  56. 未通过
  57. </span>
  58. <span v-if="data.isUser == 1 && data.state == 3" style="color:red;">
  59. 已撤回
  60. </span>
  61. </div>
  62. </span>
  63. </el-tree>
  64. </div>
  65. </div>
  66. <div :style="'height:'+tableHeight+'px;width:0.5px;background:#eee;margin-right:10px;margin-left:10px;'" ></div>
  67. <div class="allDaily" style="float:left;flex-grow:1">
  68. <!--系统管理员和部门负责人 -->
  69. <div class="report_title" v-if="user.role == 1 || user.role == 2 || user.manageDeptId > 0">
  70. <span>工作日报 | {{depData.label}}</span> - 已填写<span style="margin-left:5px;margin-right:5px;color:green;">{{reportList.length}}</span>人,
  71. 未填写<span style="margin-left:5px;margin-right:5px;color:red;">{{(depData == null?data[0].membCount:(depData.isUser == 1?1:depData.membCount))-reportList.length}}</span>人
  72. <span style="float:right;">
  73. <el-link type="primary" style="margin-right:10px;" :underline="false" @click="fillInReport(-1,0)">填写日报</el-link>
  74. <el-link type="primary" style="margin-right:10px;" :underline="false" @click="fillInReport(-1,1)">批量填报</el-link>
  75. <el-link type="primary" style="margin-right:10px;" :underline="false" @click="showExportDialog">导出日报</el-link>
  76. <el-link type="primary" style="margin-right:10px;" :underline="false" @click="batchApprove" >批量审核</el-link>
  77. </span>
  78. </div>
  79. <!--普通员工,含项目经理 -->
  80. <div class="report_title" v-if="(user.role==0||user.role==5) && user.manageDeptId == 0"><span>日报列表</span>
  81. <span style="float:right;" v-if="(user.role==0||user.role==5) && user.manageDeptId == 0">
  82. <el-link type="primary" style="margin-right:10px;" :underline="false" @click="fillInReport(-1,0)">填写日报</el-link>
  83. <el-link type="primary" style="margin-right:10px;" :underline="false" @click="fillInReport(-1,1)">批量填报</el-link>
  84. <el-link type="primary" v-if="user.leader" style="margin-right:10px;" :underline="false" @click="batchApprove">批量审核</el-link>
  85. </span>
  86. </div>
  87. <div :style="'height:'+(tableHeight-50)+'px;overflow:scroll;padding-top:10px;'">
  88. <div class="one_daily" v-for="(item1,index1) in reportList" :key="index1">
  89. <i class="fa fa-circle"></i>{{item1.name}}
  90. <span style="margin-left:30px;">
  91. <span style="margin-right:20px;">
  92. <!-- <i v-if="parseFloat(item1.reportTime)>parseFloat(item1.calculateTime)+0.5" style="color:red;margin-right:8px;" class="fa fa-exclamation-triangle"></i> -->
  93. 工作总时长:
  94. <!-- <span :style="parseFloat(item1.reportTime)>parseFloat(item1.calculateTime)+0.5?'color:red':''">{{item1.reportTime}}h</span> -->
  95. <span >{{item1.reportTime}}</span>h
  96. <span v-if="user.role >=1 && user.role <=3"><span style="margin-left:10px;">成本:</span>
  97. <span >{{item1.cost}}</span>元</span>
  98. </span>
  99. </span>
  100. <div class="checkbtn">
  101. <el-button v-if="(user.role == 1 || user.role == 2 || user.id == item1.data[0].inchargerId) && item1.state == 0" type="primary" :loading="logining" size="small" @click="approve(item1.id, item1)">通过</el-button>
  102. <el-button v-if="(user.role == 1 || user.role == 2 || user.id == item1.data[0].inchargerId) && item1.state == 0" type="danger" :loading="logining" size="small" @click="deny(item1.id,0, item1)">驳回</el-button>
  103. <!--自己可以撤回待审核状态的报告 -->
  104. <el-button v-if="(user.id == item1.id) && item1.state == 0" type="normal" :loading="logining" size="small" @click="cancel(item1)">撤回</el-button>
  105. <el-button v-if="(user.role == 1 || user.role == 2 || user.id == item1.data[0].inchargerId) && item1.state == 1" type="normal" :loading="logining" size="small" @click="deny(item1.id,1, item1)">撤销</el-button>
  106. <el-button v-if="item1.state >= 2 && user.id == item1.id" type="primary" size="small" @click="fillInReport(index1,0)">编辑日报</el-button>
  107. </div>
  108. <div class="one_daily_body">
  109. <el-timeline>
  110. <el-timeline-item v-for="(item2,index2) in item1.data" :key="index2">
  111. <el-card shadow="never">
  112. <p>项目:<b>{{item2.project}}</b><span v-if="item2.subProjectName != null"> / {{item2.subProjectName}}</span>
  113. <span style="margin-left:15px;color:#DAA520;" v-if="item2.state == 0">[ 待审核 ]</span>
  114. <span style="margin-left:15px;color:#32CD32;" v-else-if="item2.state == 1">[ 已通过 ]</span>
  115. <span style="margin-left:15px;color:#FF0000;" v-else-if="item2.state == 2">[ 已驳回 ]</span>
  116. <span style="margin-left:15px;color:#FF0000;" v-else-if="item2.state == 3">[ 已撤回 ]</span>
  117. </p>
  118. <p v-if="item2.taskId != null">任务:{{item2.taskName}}
  119. </p>
  120. <p style="display: inline-block;">时长:
  121. <span v-if="item2.reportTimeType == 0" style="margin-right:10px;">{{typeList[item2.timeType]}}</span>
  122. <span v-if="item2.reportTimeType == 2" style="margin-right:10px;">{{item2.startTime+'-'+item2.endTime}}</span>
  123. {{item2.time.toFixed(1)}}h
  124. <el-tag type="danger" size="mini" style="margin-left: 65px" v-if="item2.isOvertime === 1">加班</el-tag>
  125. </p>
  126. <p>事项:<span v-html="item2.content"></span></p>
  127. </el-card>
  128. </el-timeline-item>
  129. </el-timeline>
  130. </div>
  131. </div>
  132. <!-- 简陋的无报告提示 -->
  133. <div v-if="reportList.length==0" style="width:100%;font-size:17px;text-align:center;color:#aaa;">{{curDate}}暂无报告</div>
  134. </div>
  135. </div>
  136. </div>
  137. </el-card>
  138. </div>
  139. <!-- 填写日报的dialog -->
  140. <el-dialog :title="isBatch==0?'填写日报':'批量填报'" :visible.sync="dialogVisible" width="60%" :close-on-click-modal="false">
  141. <el-form ref="workForm" :model="workForm" :rules="workRules" label-width="100px">
  142. <el-form-item label="工作日期" prop="createDate">
  143. <el-date-picker v-model="workForm.createDate" :editable="false" format="yyyy-MM-dd" value-format="yyyy-MM-dd"
  144. :style="'width:'+(isBatch==0?'200':'280')+'px;'" :type="isBatch==0?'date':'daterange'"
  145. @change="changeMonth()" :clearable="false" placeholder="选择工作日期" :disabled="isDisable"></el-date-picker>
  146. <span v-if="reportTimeType.type == 3" style="margin-left:30px;">总时长:</span>
  147. <el-input-number :disabled="!canEdit" v-if="reportTimeType.type == 3" style="margin-left:10px;" @change="changeAllTime"
  148. v-model="reportTimeType.allday" :precision="1" :step="0.5" :max="12" :min="0.5"></el-input-number>
  149. <span v-if="reportTimeType.type == 3">小时</span>
  150. </el-form-item>
  151. <div v-for="(domain, index) in workForm.domains" :key="domain.id">
  152. <el-form-item v-if="reportTimeType.type != 3" label="工作时长" :prop="'domains.' + index + '.'+timeFields[reportTimeType.type]"
  153. :rules="{ required: true, message: '请选择工作时长', trigger: 'blur' }">
  154. <el-select v-model="domain.timeType" style="width:200px;"
  155. v-if="reportTimeType.type == 0"
  156. placeholder="请选择工作时长"
  157. :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)"
  158. @change="onTimeTypeChange(domain.timeType)">
  159. <el-option
  160. v-for="item in timeType"
  161. :key="item.value"
  162. :label="item.label"
  163. :value="item.value">
  164. </el-option>
  165. </el-select>
  166. <!-- 数字时长选择 -->
  167. <el-select v-model="domain.workingTime" style="width:200px;"
  168. v-if="reportTimeType.type == 1"
  169. :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)"
  170. placeholder="请选择工作时长" >
  171. <el-option v-for="item in timeRange" :key="item" :value="item.toFixed(1)">{{item.toFixed(1)}}</el-option>
  172. </el-select>
  173. <span v-if="reportTimeType.type == 1">小时</span>
  174. <span v-if="reportTimeType.type == 2">
  175. <!--时间范围选择 -->
  176. <el-time-picker
  177. :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)"
  178. v-model="domain.startTime"
  179. placeholder="起始时间"
  180. style="width:120px;"
  181. format="HH:mm"
  182. value-format="HH:mm"
  183. :picker-options="{
  184. start: '08:00',
  185. end: '23:30'
  186. }">
  187. </el-time-picker> - <el-time-picker
  188. :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)"
  189. v-model="domain.endTime"
  190. placeholder="结束时间"
  191. style="width:120px;"
  192. format="HH:mm"
  193. value-format="HH:mm"
  194. :picker-options="{
  195. start: '08:00',
  196. end: '23:30',
  197. minTime: domain.startTime
  198. }">
  199. </el-time-picker>
  200. </span>
  201. <div class="overtime"><el-checkbox :disabled="!canEdit" v-model="domain.isOvertime">加班</el-checkbox></div>
  202. </el-form-item>
  203. <el-form-item label="投入项目" :prop="'domains.' + index + '.projectId'"
  204. :rules="{ required: true, message: '请选择投入项目', trigger: ['change','blur'] }">
  205. <el-select v-model="domain.projectId" placeholder="请选择" style="width:200px;" clearable="true" @change="selectProject(domain, index)"
  206. :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)">
  207. <el-option v-for="item in projectList" :key="item.id" :label="item.projectName" :value="item.id"></el-option>
  208. </el-select>
  209. <!--子项目 -->
  210. <el-select v-model="domain.subProjectId" placeholder="请选择" style="width:200px;" clearable="true" v-if="domain.subProjectList != null && domain.subProjectList.length> 0"
  211. :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)">
  212. <el-option v-for="item in domain.subProjectList" :key="item.id" :label="item.name" :value="item.id"></el-option>
  213. </el-select>
  214. <el-link v-if="index >= 1" type="primary" :underline="false" @click="delDomain(index)" style="float:right;margin-right:10px;"
  215. :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)">
  216. <i class="fa fa-trash" style="color: red;;font-size:18px;"></i>
  217. </el-link>
  218. </el-form-item>
  219. <el-form-item v-if="reportTimeType.type == 3" label="用时占比" :prop="'domains.' + index + '.'+timeFields[reportTimeType.type]"
  220. :rules="{ required: true, message: '请选择工作时长', trigger: 'blur' }">
  221. <div style="width:300px;">
  222. <el-col span="14"><el-slider :disabled="!canEdit" v-model="domain.progress" :min="10" :show-tooltip="false" :step="10" style="width:180px;" @change="domain.workingTime = (reportTimeType.allday*domain.progress/100).toFixed(1)"></el-slider></el-col>
  223. <el-col span="10"><span style="margin-left:10px;float:right;"><span style="margin-right:10px;">{{domain.progress}}%</span>{{domain.workingTime}}小时</span></el-col>
  224. </div>
  225. <div class="overtime"><el-checkbox :disabled="!canEdit" v-model="domain.isOvertime">加班</el-checkbox></div>
  226. </el-form-item>
  227. <!--项目管理专业版模式下,项目下的近期执行的任务 -->
  228. <el-form-item label="相关任务" :prop="'domains.' + index + '.taskId'" v-if="user.company.packageProject==1">
  229. <el-select v-model="domain.taskId" placeholder="请选择" style="width:100%;"
  230. :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)">
  231. <el-option v-for="item in domain.taskList" :key="item.taskId" :label="item.taskName" :value="item.taskId"></el-option>
  232. </el-select>
  233. </el-form-item>
  234. <el-form-item label="工作事项" :prop="'domains.' + index + '.content'" >
  235. <el-input v-model="domain.content" type="textarea" :rows="4" placeholder="请填写工作事项" clearable
  236. :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)"></el-input>
  237. </el-form-item>
  238. <el-divider v-if="workForm.domains.length>1" style="margin-bottom:10px;"></el-divider>
  239. </div>
  240. <el-link v-if="showAddMore" :disabled="!canEdit" type="primary" :underline="false" @click="addDomain" style="margin-left:40px">添加更多</el-link>
  241. </el-form>
  242. <span slot="footer" class="dialog-footer">
  243. <el-button @click="deleteReport" v-if="workForm.domains[0].id != null">删除</el-button>
  244. <el-button @click="dialogVisible = false">取消</el-button>
  245. <el-button type="primary" @click="submitDepartment"
  246. :disabled="workForm.domains.length==0?true:(canEdit?false:true)" >提交</el-button>
  247. </span>
  248. </el-dialog>
  249. <!-- 批量日报审核 -->
  250. <el-dialog title="批量日报审核" :visible.sync="approveDialogVisible" width="500px" >
  251. <el-checkbox v-model="isAllSelect" label="全选" style="margin-left:24px;" @change="selectAll" v-if="reportNames.length > 0"></el-checkbox>
  252. <el-tree ref="approveTree" node-key="id" :data="reportNames" show-checkbox="true" @check-change="handleCheckChange" >
  253. </el-tree>
  254. <span slot="footer" class="dialog-footer">
  255. <el-button @click="approveDialogVisible = false">取消</el-button>
  256. <el-button type="primary" @click="submitBatchApprove" :disabled="batchShowData.length == 0">审核通过</el-button>
  257. </span>
  258. </el-dialog>
  259. <!--导出报表条件选择 -->
  260. <el-dialog title="日报导出" v-if="exportDialog" :visible.sync="exportDialog" customClass="customWidth" width="500px">
  261. <el-form ref="form3" :model="exportParam" >
  262. <el-form-item prop="projectId" label="选择项目">
  263. <el-select v-model="exportParam.projectId" placeholder="全部项目" clearable style="width:350px;">
  264. <el-option v-for="item in projectList" :key="item.id" :label="item.projectName" :value="item.id"></el-option>
  265. </el-select>
  266. </el-form-item>
  267. <el-form-item prop="projectId" label="日期范围">
  268. <el-date-picker
  269. v-model="exportParam.dateRange" :editable="false"
  270. format="yyyy-MM-dd" value-format="yyyy-MM-dd"
  271. :clearable="true"
  272. range-separator="至"
  273. type="daterange"
  274. start-placeholder="开始日期"
  275. end-placeholder="结束日期"
  276. ></el-date-picker>
  277. </el-form-item>
  278. </el-form>
  279. <div slot="footer" class="dialog-footer">
  280. <el-button type="primary" @click="exportReport" style="width:100%;" >导出</el-button>
  281. </div>
  282. </el-dialog>
  283. </section>
  284. </template>
  285. <script>
  286. import util from "../../common/js/util";
  287. export default {
  288. data() {
  289. return {
  290. isBatch:0,//是否是批量填报
  291. weekDay : ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],
  292. statusStyle:["waiting", "filledReportStyle", "RejectStyle", ""],
  293. fillStatusList: [],
  294. exportParam:{projectId: null, dateRange:[]},
  295. exportDialog:false,
  296. timeFields:['timeType', 'workingTime', 'startTime', 'progress'],
  297. subProjectList:[],
  298. canEdit: true,
  299. timeRange:[0.5,1.0,1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5,7.0,7.5,8.0,8.5,9.0,9.5,10.0,10.5,11.0,11.5,12.0,12.5,13.0,13.5,14.0,14.5,15.0],
  300. selectTime:null,
  301. reportTimeType:{},
  302. curDate:'',
  303. isAllSelect: false,
  304. approveDialogVisible:false,
  305. deptId:null,
  306. targetUid: null,
  307. membCount:0,
  308. selectState:"-1",
  309. user: JSON.parse(sessionStorage.getItem("user")),
  310. showAddMore:false,
  311. allDate: [],
  312. typeList:['全天','上午','下午'],
  313. date: sessionStorage.msg?sessionStorage.msg.split('-')[0]+"-"+sessionStorage.msg.split('-')[1]:util.formatDate.format(new Date(new Date()), "yyyy-MM"),
  314. choseDay: 0,
  315. tableHeight: 0,
  316. listLoading: false,
  317. projectList: [], //项目列表
  318. reportList: [], //日报列表
  319. reportNames:[], //批量审批列表
  320. dialogVisible: false, //项目弹窗
  321. report: '',
  322. workForm: {
  323. createDate: sessionStorage.msg?sessionStorage.msg:util.formatDate.format(new Date(new Date()), "yyyy-MM-dd"),
  324. domains: [{
  325. id: null,
  326. projectId: "",
  327. workingTime: "",
  328. timeType:0,
  329. content: "",
  330. state: 2,
  331. }],
  332. },
  333. workRules: {
  334. createDate: [{ required: true, message: "请选择工作日期", trigger: "change" }],
  335. },
  336. logining: false,
  337. isDisable: false,
  338. timeType:[],
  339. //部门人员树状结构
  340. data: [
  341. {
  342. id: -1,
  343. label: '全部人员',
  344. membCount:0
  345. },
  346. {
  347. id: 0,
  348. label: '未分配',
  349. }
  350. ],
  351. allData:{},
  352. batchShowData:{},
  353. option: [],
  354. depData: {
  355. id: -1,
  356. label: '全部人员',
  357. },
  358. defaultProps: {
  359. children: 'children',
  360. label: 'label'
  361. },
  362. isNew: false,
  363. selected: false,
  364. valuet: new Date(),
  365. domObj: null,
  366. };
  367. },
  368. methods: {
  369. //获取自己填写的日报状态
  370. getReportFillStatus() {
  371. this.http.post('/report/getReportFillStatus',{
  372. startDate: this.date+"-01", endDate: this.date+"-31", userId: this.user.id
  373. },
  374. res => {
  375. if (res.code == "ok") {
  376. this.fillStatusList = res.data;
  377. this.allDate.forEach(d=>{
  378. var fillInfo = null;
  379. d.state = null;
  380. this.fillStatusList.forEach(s=>{
  381. var d1 = s.createDate.split('-')[2];
  382. var d2 = d.date.split('月')[1].split('日')[0];
  383. if (d1.indexOf('0') == 0) {
  384. d1 = d1.substring(1,d1.length);
  385. }
  386. if (d1 == d2) {
  387. d.state = s.state;
  388. }
  389. })
  390. })
  391. this.$forceUpdate();
  392. }
  393. },
  394. error => {
  395. this.$message({
  396. message: error,
  397. type: "error"
  398. });
  399. }
  400. );
  401. },
  402. scrollFunction () {
  403. this.domObj = document.getElementById('clearfix') // 通过id获取要设置的div
  404. if (this.domObj.attachEvent) { // IE
  405. this.domObj.attachEvent('onmousewheel', this.mouseScroll)
  406. } else if (this.domObj.addEventListener) {
  407. this.domObj.addEventListener('DOMMouseScroll', this.mouseScroll, false)
  408. }
  409. this.domObj.onmousewheel = this.domObj.onmousewheel = this.mouseScroll
  410. },
  411. mouseScroll(event) { // google 浏览器下
  412. let detail = event.wheelDelta || event.detail
  413. let moveForwardStep = -1
  414. let moveBackStep = 1
  415. let step = 0
  416. step = detail > 0 ? moveForwardStep * 100 : moveBackStep * 100
  417. event.preventDefault() // 阻止浏览器默认事件
  418. this.domObj.scrollLeft = this.domObj.scrollLeft + step
  419. },
  420. // //左右滚动
  421. // wheel(e){
  422. // var a = document.getElementById("dateScroll");
  423. // var scroll_width = 80; //滚动一下的距离
  424. // var e = e || window.event, v;
  425. // e.wheelDelta ? v=e.wheelDelta : v=e.detail;
  426. // if(v>3||-v>3) v=-v;
  427. // v>0 ? a.scrollLeft+=scroll_width : a.scrollLeft-=scroll_width;
  428. // e.preventDefault(); //阻止浏览器的默认滚动
  429. // },
  430. showExportDialog() {
  431. this.exportDialog = true;
  432. },
  433. changeAllTime() {
  434. //总时长发生改变,自动按比例计算
  435. this.workForm.domains.forEach(d=>{
  436. d.workingTime = (d.progress*this.reportTimeType.allday/100).toFixed(1);
  437. });
  438. },
  439. // 是否加班的单机事件
  440. check() {
  441. this.selected = !this.selected
  442. this.isNew = this.selected
  443. },
  444. //项目选中了, 加载子项目
  445. selectProject(domain, index) {
  446. this.http.post('/sub-project/list',{
  447. projectId: domain.projectId
  448. },
  449. res => {
  450. if (res.code == "ok") {
  451. this.workForm.domains[index].subProjectList = res.data;
  452. this.$forceUpdate();
  453. }
  454. },
  455. error => {
  456. this.$message({
  457. message: error,
  458. type: "error"
  459. });
  460. }
  461. );
  462. //项目相关的近期任务
  463. if (this.user.company.packageProject == 1) {
  464. this.http.post('/task/getRecentTask',{
  465. projectId: domain.projectId
  466. },
  467. res => {
  468. if (res.code == "ok") {
  469. this.workForm.domains[index].taskList = res.data;
  470. this.$forceUpdate();
  471. }
  472. },
  473. error => {
  474. this.$message({
  475. message: error,
  476. type: "error"
  477. });
  478. }
  479. );
  480. }
  481. },
  482. //删除自己的日报
  483. deleteReport() {
  484. this.$confirm("确定要删除该日报吗?","提示", {
  485. confirmButtonText: "确定",
  486. cancelButtonText: "取消",
  487. type: "warning"
  488. })
  489. .then(() => {
  490. this.listLoading = true;
  491. this.http.post('/report/delete',{
  492. userId: this.user.id,
  493. date: this.workForm.createDate
  494. },
  495. res => {
  496. this.listLoading = false;
  497. if (res.code == "ok") {
  498. this.$message({
  499. message: "删除成功",
  500. type: "success"
  501. });
  502. this.getReportList();
  503. this.getDepartment();
  504. this.dialogVisible = false;
  505. } else {
  506. this.$message({
  507. message: res.msg,
  508. type: "error"
  509. });
  510. }
  511. },
  512. error => {
  513. this.listLoading = false;
  514. this.$message({
  515. message: error,
  516. type: "error"
  517. });
  518. }
  519. );
  520. })
  521. .catch(() => {});
  522. },
  523. //提交批量审核数据
  524. submitBatchApprove() {
  525. var data = this.$refs.approveTree.getCheckedNodes();
  526. var ids = '';
  527. if (data.length == 0) {
  528. this.$message({
  529. message: '请选择要审核的人员',
  530. type: "error"
  531. });
  532. return;
  533. }
  534. for (var i=0;i<data.length; i++) {
  535. ids += data[i].id;
  536. if (i < data.length-1) {
  537. ids += ',';
  538. }
  539. }
  540. let day = this.choseDay > 9 ? "-" + (this.choseDay + 1) : "-0" + (this.choseDay + 1);
  541. this.http.post("/report/batchApproveReport", {ids:ids, date:this.date + day},
  542. res => {
  543. if (res.code == "ok") {
  544. this.$message({
  545. message: '审核成功',
  546. type: "success"
  547. });
  548. this.getReportList();
  549. this.getDepartment();
  550. this.approveDialogVisible = false;
  551. } else {
  552. this.$message({
  553. message: res.msg,
  554. type: "error"
  555. });
  556. }
  557. },
  558. error => {
  559. this.$message({
  560. message: error,
  561. type: "error"
  562. });
  563. });
  564. },
  565. selectAll() {
  566. if (this.isAllSelect) {
  567. var keys = [];
  568. this.reportNames.forEach(b=>{
  569. keys.push(b.id);
  570. })
  571. this.$refs.approveTree.setCheckedKeys(keys);
  572. } else {
  573. this.$refs.approveTree.setCheckedKeys([]);
  574. }
  575. },
  576. //批量审核
  577. batchApprove() {
  578. this.approveDialogVisible = true;
  579. this.reportNames = [];
  580. for (var i=0;i<this.reportList.length; i++) {
  581. var report = this.reportList[i];
  582. var hasUnChecked =false;
  583. var id = '';
  584. for (var j=0;j<report.data.length; j++) {
  585. if (report.data[j].state == 0) {
  586. hasUnChecked = true;
  587. id += report.data[j].id+',';
  588. }
  589. }
  590. if (hasUnChecked) {
  591. this.reportNames.push({id:id, label: report.name});
  592. }
  593. }
  594. },
  595. removeEmptyNode(list) {
  596. for (var i=0;i<list.length;i++) {
  597. var cnt = 0;
  598. if (list[i].membCount == 0) {
  599. list.splice(i, 1);
  600. i--;
  601. } else if (list[i].children != null) {
  602. this.removeEmptyNode(list[i].children);
  603. }
  604. }
  605. },
  606. calculateMembCount(list) {
  607. for (var i in list) {
  608. var cnt = 0;
  609. if (list[i].children != null) {
  610. this.calculateMembCount(list[i].children);
  611. for (var m in list[i].children) {
  612. cnt += list[i].children[m].membCount;
  613. }
  614. }
  615. if (list[i].isUser == 1) {
  616. cnt++;
  617. this.membCount++;
  618. }
  619. list[i].membCount = cnt;
  620. }
  621. },
  622. stateChange() {
  623. this.membCount = 0;
  624. if (this.selectState == -1) {
  625. //全部状态
  626. this.data = this.allData;
  627. } else {
  628. //未填报
  629. var newData = JSON.parse(JSON.stringify(this.allData));
  630. this.filterState(this.selectState, newData);
  631. this.data = newData;
  632. }
  633. this.calculateMembCount(this.data);
  634. this.data[0].membCount = this.membCount;//总人数
  635. },
  636. //按状态过滤部门人员
  637. filterState(state, list) {
  638. for (var i =0;i<list.length; i++) {
  639. var obj = list[i];
  640. if (obj.isUser == 1) {
  641. var match = false;
  642. if (state == -2) {
  643. if (obj.state == null) {
  644. match = true;
  645. }
  646. } else {
  647. if (obj.state == state) {
  648. match = true;
  649. }
  650. }
  651. if (!match) {
  652. list.splice(i, 1);
  653. i--;
  654. } else {
  655. }
  656. } else {
  657. if (obj.children != null) {
  658. this.filterState(state, obj.children);
  659. }
  660. }
  661. }
  662. },
  663. // 部门列表点击
  664. handleNodeClick(data) {
  665. // if(this.depData == null || data.id != this.depData.id) {
  666. // this.depData = data;
  667. // //this.getUser();
  668. // }
  669. this.depData = data;
  670. if (data.id == -1) {
  671. this.deptId = null;
  672. this.targetUid = null;
  673. } else if (data.isUser == 1) {
  674. this.deptId = null;
  675. this.targetUid = data.id;
  676. } else {
  677. this.deptId = data.id;
  678. this.targetUid = null;
  679. }
  680. this.getReportList();
  681. },
  682. // 获取部门列表
  683. getDepartment() {
  684. let day = this.choseDay > 9 ? "-" + (this.choseDay + 1) : "-0" + (this.choseDay + 1);
  685. var param = {date:this.date + day};
  686. if (this.user.manageDeptId != 0) {
  687. param.manageDeptId = this.user.manageDeptId;
  688. }
  689. this.http.post("/report/getMembList", param,
  690. res => {
  691. if (res.code == "ok") {
  692. var list = res.data , list1 = JSON.parse(JSON.stringify(res.data));
  693. if (this.user.role > 0) {
  694. list.splice(0,0,{
  695. id: -1,
  696. label: '全部人员',
  697. })
  698. }
  699. this.membCount = 0;
  700. //设置员工到部门下面
  701. this.setUserToDept(list);
  702. this.data = list;
  703. this.allData = list;
  704. this.option = this.changeArr(list1);
  705. list[0].membCount = this.membCount;
  706. if (this.depData.id == -1) {
  707. this.depData.membCount = this.membCount;
  708. }
  709. } else {
  710. this.$message({
  711. message: res.msg,
  712. type: "error"
  713. });
  714. }
  715. },
  716. error => {
  717. this.$message({
  718. message: error,
  719. type: "error"
  720. });
  721. });
  722. this.getReportFillStatus();
  723. },
  724. setUserToDept(list) {
  725. for (var i in list) {
  726. var cnt = 0;
  727. if (list[i].children != null) {
  728. this.setUserToDept(list[i].children);
  729. for (var m in list[i].children) {
  730. cnt += list[i].children[m].membCount;
  731. }
  732. }
  733. if (list[i].userList != null) {
  734. if (list[i].children == null) {
  735. list[i].children = [];
  736. }
  737. list[i].userList.forEach(element => {
  738. var obj = {id: element.id, label:element.name, state:element.state, parentId:element.departmentId, isUser:1};
  739. list[i].children.push(obj);
  740. this.membCount++;
  741. cnt++;
  742. });
  743. }
  744. list[i].membCount = cnt;
  745. }
  746. },
  747. // 修改数组
  748. changeArr(arr) {
  749. for (var i = 0; i < arr.length; i++) {
  750. if(arr[i].id != -1 && arr[i].id != 0) {
  751. if (arr[i].children != null && arr[i].children.length>0) {
  752. arr[i].children = this.changeArr(arr[i].children);
  753. }
  754. arr[i].id && (arr[i].value = arr[i].id);
  755. delete arr[i].id;
  756. }
  757. }
  758. for(var i in arr) {
  759. if(arr[i].id == -1 || arr[i].id == 0) {
  760. arr.splice(i,1)
  761. }
  762. }
  763. return arr;
  764. },
  765. //时间段范围设置改动,监听
  766. onTimeTypeChange(timeType) {
  767. this.showAddMore = true;
  768. for(var i in this.workForm.domains) {
  769. if (this.workForm.domains[i].timeType == 0) {
  770. this.showAddMore = false;
  771. break;
  772. }
  773. }
  774. if (this.showAddMore) {
  775. //检测数量
  776. if (this.workForm.domains.length == 2) {
  777. this.showAddMore = false;
  778. } else {
  779. this.showAddMore = true;
  780. }
  781. }
  782. },
  783. getTimeType() {
  784. this.http.post('/time-type/getCompanyTimeSetting', { companyId: this.user.companyId},
  785. res => {
  786. if (res.code == "ok") {
  787. var t = res.data;
  788. this.reportTimeType = t;
  789. if (this.reportTimeType.type > 0) {
  790. this.showAddMore = true;
  791. }
  792. //转化时间格式
  793. if (t.allday != null) {
  794. this.timeType.push({value:0, label:'全天 - '+t.allday+'小时', hours:t.allday});
  795. }
  796. if (t.am != null) {
  797. this.timeType.push({value:1, label:'上午 - '+t.am+'小时', hours: t.am});
  798. }
  799. if (t.pm != null) {
  800. this.timeType.push({value:2, label:'下午 - '+t.pm+'小时', hours: t.pm});
  801. }
  802. } else {
  803. this.$message({
  804. message: res.msg,
  805. type: "error"
  806. });
  807. }
  808. },
  809. error => {
  810. this.listLoading = false;
  811. this.$message({
  812. message: error,
  813. type: "error"
  814. });
  815. });
  816. },
  817. // 改变月份
  818. changeMonthOut() {
  819. this.getAllDate();
  820. this.getReportList();
  821. this.getDepartment();
  822. },
  823. // 选择日期
  824. choseDate(i, item) {
  825. this.choseDay = i;
  826. let day = this.choseDay > 9 ? "-" + (this.choseDay + 1) : "-0" + (this.choseDay + 1);
  827. sessionStorage.msg = this.date + day,
  828. this.getReportList();
  829. this.getDepartment();
  830. this.curDate = item.date;
  831. },
  832. // 获取日期列表
  833. getAllDate() {
  834. var dayArry = [];
  835. var day = this.getCountDays();
  836. let curMonthDay = null;
  837. for (var k = 1; k <= day; k++) {
  838. var str = new Date(this.date.replace(/-/g, "/")+'/01').getMonth() + 1 + "月" + k+'日';
  839. var showStr = new Date(this.date.replace(/-/g, "/")+'/01').getMonth() + 1+'.'+k;
  840. if ( new Date(this.date.replace(/-/g, "/")+'/01').getFullYear() == new Date(new Date()).getFullYear() &&
  841. new Date(this.date.replace(/-/g, "/")+'/01').getMonth() == new Date(new Date()).getMonth()) {
  842. if(sessionStorage.msg) {
  843. if(parseInt(sessionStorage.msg.split("-")[2]) == k) {
  844. this.choseDay = k - 1;
  845. curMonthDay = str;
  846. }
  847. } else {
  848. if (new Date().getDate() == k) {
  849. this.choseDay = k - 1;
  850. }
  851. }
  852. } else {
  853. this.choseDay = 0;
  854. }
  855. var curDateStr = (this.date +'-'+ (k<10?('0'+k):k));
  856. var curDateTime = util.formatDate.parse(curDateStr, 'yyyy-MM-dd');
  857. dayArry.push({date:str, weekDay:this.weekDay[curDateTime.getDay()], showDate:showStr});
  858. }
  859. this.allDate = dayArry;
  860. //不能超过最大日期
  861. if (this.choseDay > day-1) {
  862. this.choseDay = day-1;
  863. }
  864. //从消息点击跳转过来的,直接加载指定日期
  865. if (sessionStorage.from == 1 && sessionStorage.msg) {
  866. this.curDate = sessionStorage.msg;
  867. sessionStorage.from = 0;
  868. } else {
  869. if (curMonthDay != null) {
  870. this.curDate = curMonthDay;
  871. } else {
  872. var d = new Date(this.date.replace(/-/g, "/")+'/01')
  873. this.curDate = (d.getMonth()+1)+'月'+d.getDate()+'日';
  874. }
  875. }
  876. this.getReportFillStatus();
  877. },
  878. getCountDays() {
  879. var newstr = this.date.replace(/-/g, "/");
  880. var curDate = new Date(newstr+'/01');
  881. var curMonth = curDate.getMonth();
  882. curDate.setMonth(curMonth + 1);
  883. curDate.setDate(0);
  884. return curDate.getDate();
  885. },
  886. //获取日报列表
  887. getReportList() {
  888. this.listLoading = true;
  889. let day = this.choseDay > 9 ? "-" + (this.choseDay + 1) : "-0" + (this.choseDay + 1);
  890. let param = {date: this.date + day};
  891. if (this.deptId != null) {
  892. param.deptId = this.deptId;
  893. }
  894. if (this.targetUid != null) {
  895. param.userId = this.targetUid;
  896. }
  897. this.http.post( this.port.report.list, param,
  898. res => {
  899. this.listLoading = false;
  900. if (res.code == "ok") {
  901. this.reportList = res.data;
  902. document.querySelector("#day"+this.choseDay).scrollIntoView(true);
  903. } else {
  904. this.$message({
  905. message: res.msg,
  906. type: "error"
  907. });
  908. }
  909. },
  910. error => {
  911. this.listLoading = false;
  912. this.$message({
  913. message: error,
  914. type: "error"
  915. });
  916. });
  917. },
  918. //导出日报
  919. exportReport() {
  920. this.listLoading = true;
  921. var param = {};
  922. if (this.exportParam.dateRange != null) {
  923. param = {startDate:this.exportParam.dateRange[0], endDate: this.exportParam.dateRange[1]};
  924. }
  925. if (this.exportParam.projectId != null) {
  926. param.projectId = this.exportParam.projectId;
  927. }
  928. this.http.post( this.port.report.export, param,
  929. res => {
  930. this.listLoading = false;
  931. if (res.code == "ok") {
  932. location.href = res.data;
  933. this.exportDialog = false;
  934. } else {
  935. this.$message({
  936. message: res.msg,
  937. type: "error"
  938. });
  939. }
  940. },
  941. error => {
  942. this.listLoading = false;
  943. this.$message({
  944. message: error,
  945. type: "error"
  946. });
  947. });
  948. },
  949. //获取项目列表
  950. getProjectList() {
  951. this.listLoading = true;
  952. this.http.post( this.port.project.list, {},
  953. res => {
  954. this.listLoading = false;
  955. if (res.code == "ok") {
  956. this.projectList = res.data;
  957. } else {
  958. this.$message({
  959. message: res.msg,
  960. type: "error"
  961. });
  962. }
  963. },
  964. error => {
  965. this.listLoading = false;
  966. this.$message({
  967. message: error,
  968. type: "error"
  969. });
  970. });
  971. },
  972. // 获取个人某天的日报
  973. getReport() {
  974. this.http.post( this.port.report.getPort, {
  975. date: this.workForm.createDate
  976. },
  977. res => {
  978. if (res.code == "ok") {
  979. var list = res.data;
  980. this.report = list;
  981. if(list.report.length != 0) {
  982. var arr = [];
  983. this.canEdit = false;
  984. for(var i in list.report) {
  985. var flg = null
  986. list.report[i].isOvertime == 1 ? flg = true : flg = false
  987. arr.push({
  988. id: list.report[i].id,
  989. projectId: list.report[i].projectId,
  990. workingTime: list.report[i].workingTime,
  991. content: list.report[i].content,
  992. state: list.report[i].state,
  993. timeType: list.report[i].timeType,
  994. subProjectList: list.report[i].subProjectList,
  995. taskList: list.report[i].taskList,
  996. subProjectId: list.report[i].subProjectId,
  997. taskId: list.report[i].taskId,
  998. // startTime: `Fri May 16 2021 ${list.report[i].startTime}:12 GMT+0800 (中国标准时间)`,
  999. startTime: list.report[i].startTime,
  1000. // endTime: `Fri May 16 2021 ${list.report[i].endTime}:12 GMT+0800 (中国标准时间)`,
  1001. endTime: list.report[i].endTime,
  1002. isOvertime: flg,
  1003. progress:list.report[i].progress,
  1004. })
  1005. if (list.report[i].state >= 2) {
  1006. this.canEdit = true;
  1007. }
  1008. }
  1009. this.workForm = {
  1010. createDate: this.workForm.createDate,
  1011. domains: arr,
  1012. }
  1013. } else {
  1014. this.workForm = {
  1015. createDate: this.workForm.createDate,
  1016. domains: [{
  1017. id: null,
  1018. projectId: "",
  1019. workingTime: this.reportTimeType.type==3?(this.reportTimeType.allday).toFixed(1):"",
  1020. content: "",
  1021. progress:100,
  1022. state: 2,
  1023. timeType:0,
  1024. }],
  1025. }
  1026. this.canEdit = true;
  1027. }
  1028. } else {
  1029. this.$message({
  1030. message: res.msg,
  1031. type: "error"
  1032. });
  1033. }
  1034. },
  1035. error => {
  1036. this.$message({
  1037. message: error,
  1038. type: "error"
  1039. });
  1040. });
  1041. },
  1042. // 打开日报填写
  1043. fillInReport(i, isBatch) {
  1044. if(i == -1) {
  1045. this.isDisable = false;
  1046. } else {
  1047. this.isDisable = true;
  1048. }
  1049. let day = this.choseDay > 9 ? "-" + (this.choseDay + 1) : "-0" + (this.choseDay + 1);
  1050. this.isBatch = isBatch;
  1051. if (this.isBatch == 0) {
  1052. this.workForm.createDate = this.date + day; // 获取个人某天的日报
  1053. this.getReport(i);
  1054. } else {
  1055. this.workForm = {
  1056. createDate: null,//批量填报没有日期
  1057. domains: [{
  1058. id: null,
  1059. projectId: "",
  1060. workingTime: this.reportTimeType.type==3?(this.reportTimeType.allday).toFixed(1):"",
  1061. content: "",
  1062. progress:100,
  1063. state: 2,
  1064. timeType:0,
  1065. }],
  1066. }
  1067. this.canEdit = true;
  1068. }
  1069. this.dialogVisible = true;
  1070. },
  1071. // 添加模块
  1072. addDomain() {
  1073. var leftProgress = 10;
  1074. if (this.reportTimeType.type == 3) {
  1075. //计算已经待分配工时比例
  1076. let array = this.workForm.domains;
  1077. let totalProgress = 0;
  1078. for (var i=0;i<array.length; i++) {
  1079. totalProgress += array[i].progress;
  1080. }
  1081. if (totalProgress < 100) {
  1082. leftProgress = 100 - totalProgress;
  1083. }
  1084. }
  1085. this.workForm.domains.push({
  1086. projectId: "",
  1087. workingTime: this.reportTimeType.type == 3?(leftProgress*this.reportTimeType.allday/100).toFixed(1):"",
  1088. content: "",
  1089. progress:leftProgress,
  1090. state:2,//2-表示待提交
  1091. });
  1092. if (this.reportTimeType.type == 0) {
  1093. //全天上下午模式下,检测时间段数量,达到2个,不能再加了
  1094. var length = this.workForm.domains.length;
  1095. if (length == 2) {
  1096. this.showAddMore = false;
  1097. }
  1098. }
  1099. },
  1100. // 移除模块
  1101. delDomain(i) {
  1102. this.workForm.domains.splice(i,1)
  1103. //检测当前剩下的一个,时间类型是否是全天
  1104. if (this.reportTimeType.type == 0) {
  1105. if (this.workForm.domains[0].timeType == 0) {
  1106. this.showAddMore = false;
  1107. } else {
  1108. this.showAddMore = true;
  1109. }
  1110. }
  1111. },
  1112. // 改变月份
  1113. changeMonth() {
  1114. if (this.isBatch == 0) {
  1115. //只有按天填报才能获取当天的日报
  1116. this.getReport()
  1117. }
  1118. },
  1119. // 保存日报
  1120. submitDepartment() {
  1121. this.$refs.workForm.validate(valid => {
  1122. if (valid) {
  1123. //检查时间,全天和上下午不能同时存在
  1124. if (this.reportTimeType.type == 0) {
  1125. var alldayNum = 0;
  1126. var amNum = 0;
  1127. var pmNum = 0;
  1128. for(var i in this.workForm.domains) {
  1129. if (this.workForm.domains[i].timeType == 0) {
  1130. alldayNum ++;
  1131. } else if (this.workForm.domains[i].timeType == 1) {
  1132. amNum++;
  1133. } else if (this.workForm.domains[i].timeType == 2) {
  1134. pmNum++;
  1135. }
  1136. }
  1137. if (alldayNum > 1) {
  1138. this.$message({
  1139. message: "工作时间-全天,只能选择一次",
  1140. type: "error"
  1141. });
  1142. return;
  1143. }
  1144. if (amNum > 1) {
  1145. this.$message({
  1146. message: "工作时间-上午,只能选择一次",
  1147. type: "error"
  1148. });
  1149. return;
  1150. }
  1151. if (pmNum > 1) {
  1152. this.$message({
  1153. message: "工作时间-下午,只能选择一次",
  1154. type: "error"
  1155. });
  1156. return;
  1157. }
  1158. if (alldayNum == 1 && (amNum > 0 || pmNum > 0)) {
  1159. this.$message({
  1160. message: "工作时间-全天,不能和上下午同时存在",
  1161. type: "error"
  1162. });
  1163. return;
  1164. }
  1165. } else if (this.reportTimeType.type == 3) {
  1166. //总百分比不能超过100%
  1167. let total = 0;
  1168. this.workForm.domains.forEach(w=>{total += w.progress});
  1169. if (total > 100) {
  1170. this.$message({
  1171. message: "用时比例之和不能超过100%",
  1172. type: "error"
  1173. });
  1174. return;
  1175. } else if (total < 100) {
  1176. this.$message({
  1177. message: "工时尚未完全分配,无法提交",
  1178. type: "error"
  1179. });
  1180. return;
  1181. }
  1182. }
  1183. this.listLoading = true;
  1184. let formData = new FormData();
  1185. for(var i in this.workForm.domains) {
  1186. if (this.workForm.domains[i].id != null) {
  1187. formData.append("id", this.workForm.domains[i].id);
  1188. } else {
  1189. formData.append("id", -1);
  1190. }
  1191. formData.append("projectId", this.workForm.domains[i].projectId);
  1192. if (this.workForm.domains[i].subProjectId != null) {
  1193. formData.append("subProjectId", this.workForm.domains[i].subProjectId);
  1194. } else {
  1195. formData.append("subProjectId", 0);
  1196. }
  1197. if (this.workForm.domains[i].taskId != null) {
  1198. formData.append("taskId", this.workForm.domains[i].taskId);
  1199. } else {
  1200. formData.append("taskId", 0);
  1201. }
  1202. formData.append("reportTimeType", this.reportTimeType.type);
  1203. if (this.reportTimeType.type == 0) {
  1204. formData.append("timeType", this.workForm.domains[i].timeType);
  1205. var workingTime = this.timeType.filter(t=>t.value == this.workForm.domains[i].timeType)[0].hours;
  1206. formData.append("workingTime", workingTime);
  1207. } else if (this.reportTimeType.type == 1){
  1208. formData.append("workingTime", this.workForm.domains[i].workingTime);
  1209. } else if (this.reportTimeType.type == 2) {
  1210. formData.append("endTime", this.workForm.domains[i].endTime);
  1211. formData.append("startTime", this.workForm.domains[i].startTime);
  1212. } else if (this.reportTimeType.type == 3) {
  1213. //按比例分配
  1214. formData.append("progress", this.workForm.domains[i].progress);
  1215. formData.append("workingTime", this.workForm.domains[i].workingTime);
  1216. }
  1217. if (this.workForm.domains[i].content == null || this.workForm.domains[i].content == '') {
  1218. formData.append("content", '-');
  1219. } else {
  1220. formData.append("content", this.workForm.domains[i].content);
  1221. }
  1222. if (this.isBatch == 0) {
  1223. formData.append("createDate", this.workForm.createDate);
  1224. } else {
  1225. //批量填报,时间范围
  1226. formData.append("createDate", this.workForm.createDate[0]+'@'+this.workForm.createDate[1]);
  1227. }
  1228. if(this.workForm.domains[i].isOvertime == undefined ) {
  1229. this.workForm.domains[i].isOvertime = '0'
  1230. formData.append("isOvertime", this.workForm.domains[i].isOvertime);
  1231. } else if (this.workForm.domains[i].isOvertime == false){
  1232. this.workForm.domains[i].isOvertime = '0'
  1233. formData.append("isOvertime", this.workForm.domains[i].isOvertime);
  1234. } else {
  1235. this.workForm.domains[i].isOvertime = '1'
  1236. formData.append("isOvertime", this.workForm.domains[i].isOvertime);
  1237. }
  1238. }
  1239. this.http.uploadFile( this.port.report.editPort, formData,
  1240. res => {
  1241. this.listLoading = false;
  1242. if (res.code == "ok") {
  1243. this.$message({
  1244. message: "填报成功",
  1245. type: "success"
  1246. });
  1247. this.dialogVisible = false;
  1248. this.getReportList();
  1249. this.getDepartment();
  1250. } else {
  1251. this.$message({
  1252. message: res.msg,
  1253. type: "error"
  1254. });
  1255. }
  1256. },
  1257. error => {
  1258. this.listLoading = false;
  1259. this.$message({
  1260. message: error,
  1261. type: "error"
  1262. });
  1263. });
  1264. }
  1265. });
  1266. },
  1267. cli() {
  1268. },
  1269. // 跳转
  1270. junpToDeskTop(id) {
  1271. let day = this.choseDay > 9 ? "-" + (this.choseDay + 1) : "-0" + (this.choseDay + 1);
  1272. this.$router.push("/desktop/" + id + "/" + this.date +day);
  1273. },
  1274. // 通过日报
  1275. approve(id, item) {
  1276. this.logining = true;
  1277. let day = this.choseDay > 9 ? "-" + (this.choseDay + 1) : "-0" + (this.choseDay + 1);
  1278. var ids = '';
  1279. var data = item.data;
  1280. data.forEach(element => {
  1281. ids +=(element.id+',');
  1282. });
  1283. this.http.post( this.port.report.approve, {id: id , date: this.date +day, reportIds: ids},
  1284. res => {
  1285. this.logining = false;
  1286. if (res.code == "ok") {
  1287. this.$message({
  1288. message: "审核成功",
  1289. type: "success"
  1290. });
  1291. this.getReportList();
  1292. this.getDepartment();
  1293. } else {
  1294. this.$message({
  1295. message: res.msg,
  1296. type: "error"
  1297. });
  1298. }
  1299. },
  1300. error => {
  1301. this.logining = false;
  1302. this.$message({
  1303. message: error,
  1304. type: "error"
  1305. });
  1306. });
  1307. },
  1308. //撤回日报
  1309. cancel(item) {
  1310. this.logining = true;
  1311. var ids = '';
  1312. var data = item.data;
  1313. data.forEach(element => {
  1314. ids +=(element.id+',');
  1315. });
  1316. this.http.post(this.port.report.cancelReport, {userId: this.user.id, reportIds: ids},
  1317. res => {
  1318. this.logining = false;
  1319. if (res.code == "ok") {
  1320. this.$message({
  1321. message:"撤回成功",
  1322. type: "success"
  1323. });
  1324. this.getReportList();
  1325. this.getDepartment();
  1326. } else {
  1327. this.$message({
  1328. message: res.msg,
  1329. type: "error"
  1330. });
  1331. }
  1332. },
  1333. error => {
  1334. this.logining = false;
  1335. this.$message({
  1336. message: error,
  1337. type: "error"
  1338. });
  1339. });
  1340. },
  1341. // 未通过日报
  1342. deny(id,i, item) {
  1343. this.logining = true;
  1344. let day = this.choseDay > 9 ? "-" + (this.choseDay + 1) : "-0" + (this.choseDay + 1);
  1345. var ids = '';
  1346. var data = item.data;
  1347. data.forEach(element => {
  1348. ids +=(element.id+',');
  1349. });
  1350. this.http.post( this.port.report.deny, {id: id , date: this.date +day, reportIds: ids},
  1351. res => {
  1352. this.logining = false;
  1353. if (res.code == "ok") {
  1354. this.$message({
  1355. message: i==0?"驳回成功":"撤销成功",
  1356. type: "success"
  1357. });
  1358. this.getReportList();
  1359. this.getDepartment();
  1360. } else {
  1361. this.$message({
  1362. message: res.msg,
  1363. type: "error"
  1364. });
  1365. }
  1366. },
  1367. error => {
  1368. this.logining = false;
  1369. this.$message({
  1370. message: error,
  1371. type: "error"
  1372. });
  1373. });
  1374. }
  1375. },
  1376. created() {
  1377. let height = window.innerHeight;
  1378. this.tableHeight = height - 178;
  1379. const that = this;
  1380. window.onresize = function temp() {
  1381. that.tableHeight = window.innerHeight - 178;
  1382. };
  1383. },
  1384. mounted() {
  1385. var now = new Date();
  1386. var t = util.formatDate.format(now, 'yyyy-MM-dd');
  1387. var startStr = util.formatDate.format(new Date(), 'yyyy-MM') + "-01";
  1388. this.exportParam.dateRange = [startStr,t];
  1389. this.getAllDate();
  1390. this.getReportList();
  1391. this.getProjectList();
  1392. this.getTimeType();
  1393. this.getDepartment();
  1394. this.scrollFunction()
  1395. }
  1396. };
  1397. </script>
  1398. <style lang="scss" scoped>
  1399. .waiting {
  1400. color:orange;
  1401. }
  1402. .filledReportStyle {
  1403. color:#32CD32;
  1404. }
  1405. .RejectStyle {
  1406. color:red;
  1407. }
  1408. .allDaily {
  1409. width:82%;
  1410. }
  1411. .report_title {
  1412. padding:10px 0;
  1413. color:#666;
  1414. }
  1415. .clearfix {
  1416. overflow-x: auto;
  1417. white-space: nowrap;
  1418. padding: 15px 0;
  1419. // overflow-y: hidden;
  1420. .date_item {
  1421. padding: 0 3px;
  1422. cursor: pointer;
  1423. }
  1424. .chooseDate {
  1425. color: #20a0ff;
  1426. }
  1427. }
  1428. .one_daily {
  1429. i {
  1430. color: #9ed0ff;
  1431. margin-right: 5px;
  1432. }
  1433. .one_daily_body {
  1434. padding: 15px 0px;
  1435. p {
  1436. margin: 0;
  1437. line-height: 30px;
  1438. }
  1439. }
  1440. ul {
  1441. padding: 0;
  1442. }
  1443. }
  1444. .checkbtn {
  1445. float: right;
  1446. margin-top: -10px;
  1447. }
  1448. </style>
  1449. <style lang="scss">
  1450. .daily {
  1451. .el-card__body {
  1452. height: 80%;
  1453. overflow-y: auto;
  1454. }
  1455. .el-card__header {
  1456. padding: 0 20px;
  1457. }
  1458. }
  1459. </style>
  1460. <style scoped>
  1461. /* 项目标签的样式 */
  1462. .el-tag + .el-tag {
  1463. margin-left: 10px;
  1464. }
  1465. .button-new-tag {
  1466. margin-left: 10px;
  1467. height: 32px;
  1468. line-height: 30px;
  1469. padding-top: 0;
  1470. padding-bottom: 0;
  1471. }
  1472. .input-new-tag {
  1473. width: 90px;
  1474. margin-left: 10px;
  1475. vertical-align: bottom;
  1476. }
  1477. </style>
  1478. <style lang="scss" scoped>
  1479. // 加班样式
  1480. .overtime {
  1481. display: inline-block;
  1482. margin-left: 20px;
  1483. input {
  1484. display: inline-block;
  1485. margin-top: 5px;
  1486. }
  1487. }
  1488. .plus {
  1489. display: inline-block;
  1490. }
  1491. // .tages {
  1492. // float: right;
  1493. // }
  1494. .overtime {
  1495. display: inline-block;
  1496. margin-left: 30px;
  1497. }
  1498. </style>