|
@@ -0,0 +1,387 @@
|
|
|
+<template>
|
|
|
+ <section>
|
|
|
+ <!--工具条-->
|
|
|
+ <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
|
|
|
+ <el-form :inline="true">
|
|
|
+ <el-form-item label="项目:">
|
|
|
+ <el-select v-model="search.projectId" placeholder="请选择" clearable @change="getList()" filterable="true">
|
|
|
+ <el-option v-for="item in projectList" :key="item.id" :label="item.projectName" :value="item.id"></el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="日期:" style="margin-left:20px;">
|
|
|
+ <el-date-picker v-model="search.date" :editable="false" format="yyyy-MM-dd" value-format="yyyy-MM-dd"
|
|
|
+ @change="getList()" :clearable="true" type="date" placeholder="选择工作日期"></el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item style="margin-left:20px;">
|
|
|
+ <el-button @click="batchApprove(true)" style="margin-left:10px;" :disabled="multipleSelection.length==0">批量通过</el-button>
|
|
|
+ <el-button @click="batchApprove(false)" :disabled="multipleSelection.length==0">批量驳回</el-button>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ </el-form>
|
|
|
+ </el-col>
|
|
|
+ <!--列表-->
|
|
|
+ <el-table :data="list" ref="multipleTable" highlight-current-row v-loading="listLoading" :height="tableHeight" style="width: 100%;"
|
|
|
+ @selection-change="handleSelectionChange">
|
|
|
+ <el-table-column type="selection" width="55"></el-table-column>
|
|
|
+ <el-table-column type="expand">
|
|
|
+ <template slot-scope="props">
|
|
|
+ <el-timeline>
|
|
|
+ <el-timeline-item v-for="(item,index) in props.row.data" :key="index">
|
|
|
+ <el-card shadow="never">
|
|
|
+ <p>项目:<b>{{item.project}}<span v-if="item.subProjectName != null"> / {{item.subProjectName}}</span></b></p>
|
|
|
+ <p v-if="user.timeType.customDegreeActive==1 && item.degree_id != null">{{user.timeType.customDegreeName}}:{{item.degreeName}}</p>
|
|
|
+ <p v-if="user.company.packageEngineering == 1">
|
|
|
+ 专业进度:
|
|
|
+ <span style="margin-right:10px;" v-for="progressItem in item.professionProgressList" :key="progressItem.id">
|
|
|
+ {{progressItem.professionName}}({{progressItem.progress}}%)
|
|
|
+ <el-tooltip v-if="progressItem.auditState == 0" content="待审核" effect="light" placement="top">
|
|
|
+ <i class="iconfont firerock-icondaibandengdaishenhe"></i>
|
|
|
+ </el-tooltip>
|
|
|
+ <el-tooltip v-if="progressItem.auditState == 1" content="已通过" effect="light" placement="top">
|
|
|
+ <i class="iconfont firerock-iconshenhetongguo"></i>
|
|
|
+ </el-tooltip>
|
|
|
+ <el-tooltip v-if="progressItem.auditState == 2" content="不通过" effect="light" placement="top">
|
|
|
+ <i class="iconfont firerock-iconshenhebohui"></i>
|
|
|
+ </el-tooltip>
|
|
|
+ </span>
|
|
|
+ </p>
|
|
|
+ <p v-if="item.taskId != null">任务:{{item.taskName}}</p>
|
|
|
+ <div v-if="item.multiWorktime==0">
|
|
|
+ <p>时长:{{item.time}}h <span class="propsbtn" v-if="item.isOvertime === 1">
|
|
|
+ <el-tag type="danger" size="mini" style="margin-left: 65px">加班</el-tag></span>
|
|
|
+ <!-- 阶段 -->
|
|
|
+ <span v-if="item.stage != null" style="margin-left:10px;"> 投入阶段:{{item.stage}}</span>
|
|
|
+ </p>
|
|
|
+ <p v-if="user.role == 1 || user.role == 2 || user.role == 6">成本:{{item.cost}}元</p>
|
|
|
+ <p>事项:<span v-html="item.content"></span></p>
|
|
|
+ </div>
|
|
|
+ <div v-if="item.multiWorktime==1" >
|
|
|
+ <div v-for="(timeItem, tIndex) in item.worktimeList" :key="tIndex"
|
|
|
+ style="border: 0.5px #ddd solid;margin:5px 0px;padding:5px; ">
|
|
|
+ <p style="line-height:20px;margin:5px 0px;">时长:
|
|
|
+ <span v-if="item.reportTimeType == 2" style="margin-right:10px;">{{timeItem.startTime+'-'+timeItem.endTime}}</span>
|
|
|
+ {{timeItem.time.toFixed(1)}}h
|
|
|
+ </p>
|
|
|
+ <p style="line-height:20px;margin:5px 0px;">事项:<span v-html="timeItem.content"></span></p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!--照片的显示 -->
|
|
|
+ <p v-if="item.pics != null && item.pics.length > 0">
|
|
|
+ <el-image v-for="(pic, index) in item.pics" :key="index"
|
|
|
+ style="width: 100px; height: 100px; margin-right:10px;"
|
|
|
+ :src="pic"
|
|
|
+ :preview-src-list="item.pics">
|
|
|
+ </el-image>
|
|
|
+ </p>
|
|
|
+ </el-card>
|
|
|
+ </el-timeline-item>
|
|
|
+ </el-timeline>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+
|
|
|
+ <el-table-column prop="name" label="姓名" sortable></el-table-column>
|
|
|
+ <el-table-column prop="dateStr" label="日期" sortable>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="reportTime" label="工作时长(h)" >
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="state" label="状态" sortable>
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span v-if="scope.row.state == -1" style="color:#DAA520;">待审核</span>
|
|
|
+ <span v-else-if="scope.row.state == 1" style="color:#32CD32;">已通过</span>
|
|
|
+ <span v-else-if="scope.row.state == 2" style="color:#FF0000;">已驳回</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作" width="220">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-button v-if="scope.row.state == -1" type="primary" :loading="logining" size="small" @click="approve(scope.row.id,scope.row.date, scope.row)">通过</el-button>
|
|
|
+ <el-button v-if="scope.row.state == -1" type="danger" :loading="logining" size="small" @click="showDenyDialog(scope.row.id,0,scope.row.dateStr, scope.row)">驳回</el-button>
|
|
|
+ <el-button v-if="scope.row.state == 1" type="danger" :loading="logining" size="small" @click="showDenyDialog(scope.row.id,1,scope.row.dateStr, scope.row)">撤销</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <!--驳回弹出框 -->
|
|
|
+ <el-dialog title="请输入原因" v-if="denyReasonDialog" :visible.sync="denyReasonDialog" :close-on-click-modal="false" customClass="customWidth" width="500px">
|
|
|
+ <div>
|
|
|
+ <el-input type="textarea" v-model="denyForm.reason" rows="2" :placeholder="'请输入您决定'+(denyForm.i==0?'驳回':'撤销')+'的原因'" />
|
|
|
+ </div>
|
|
|
+ <div slot="footer" class="dialog-footer">
|
|
|
+ <el-button @click="denyReasonDialog = false" >取消</el-button>
|
|
|
+ <el-button type="primary" @click="deny()" >确定</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+ <!--工具条-->
|
|
|
+ <!-- <el-col v-if="search.value != -1" :span="24" class="toolbar">
|
|
|
+ <el-pagination
|
|
|
+ @size-change="handleSizeChange"
|
|
|
+ @current-change="handleCurrentChange"
|
|
|
+ :page-sizes="[20 , 50 , 80 , 100]"
|
|
|
+ :page-size="20"
|
|
|
+ layout="total, sizes, prev, pager, next"
|
|
|
+ :total="total"
|
|
|
+ style="float:right;"
|
|
|
+ ></el-pagination>
|
|
|
+ </el-col> -->
|
|
|
+ </section>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ import util from "../../common/js/util";
|
|
|
+
|
|
|
+ export default {
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ denyForm:null,
|
|
|
+ denyReasonDialog:false,
|
|
|
+ isAllSelect:false,
|
|
|
+ user: JSON.parse(sessionStorage.getItem("user")),
|
|
|
+
|
|
|
+ search: {
|
|
|
+ projectId:null,
|
|
|
+ date: null,
|
|
|
+ },
|
|
|
+
|
|
|
+ users: [],
|
|
|
+ option:[],
|
|
|
+ tableHeight: 0,
|
|
|
+ listLoading: false,
|
|
|
+ total: 0,
|
|
|
+ page: 1,
|
|
|
+ size: 20,
|
|
|
+ list: [],
|
|
|
+ logining: false,
|
|
|
+ multipleSelection: [],
|
|
|
+ };
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+
|
|
|
+ // 获取部门列表
|
|
|
+ getDepartment() {
|
|
|
+ this.http.post( this.port.manage.depList, {},
|
|
|
+ res => {
|
|
|
+ if (res.code == "ok") {
|
|
|
+ var list1 = JSON.parse(JSON.stringify(res.data));
|
|
|
+
|
|
|
+ this.option = this.changeArr(list1);
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: res.msg,
|
|
|
+ type: "error"
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ error => {
|
|
|
+ this.$message({
|
|
|
+ message: error,
|
|
|
+ type: "error"
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ handleSelectionChange(val) {
|
|
|
+ this.multipleSelection = val;
|
|
|
+ },
|
|
|
+ batchApprove(isPass) {
|
|
|
+ var ids = '';
|
|
|
+ for (var i=0;i<this.multipleSelection.length; i++) {
|
|
|
+ var line = this.multipleSelection[i];
|
|
|
+ var array = line.data;
|
|
|
+ for (var m=0;m<array.length; m++) {
|
|
|
+ ids += array[m].id+',';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (ids.length > 0) {
|
|
|
+ ids = ids.substring(0, ids.length-1);
|
|
|
+ }
|
|
|
+ this.http.post(isPass?'/report/batchApproveReport':'/report/batchDenyReport', {ids: ids},
|
|
|
+ res => {
|
|
|
+ this.listLoading = false;
|
|
|
+ if (res.code == "ok") {
|
|
|
+ this.getList();
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: res.msg,
|
|
|
+ type: "error"
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ error => {
|
|
|
+ this.listLoading = false;
|
|
|
+ this.$message({
|
|
|
+ message: error,
|
|
|
+ type: "error"
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ //分页
|
|
|
+ handleCurrentChange(val) {
|
|
|
+ this.page = val;
|
|
|
+ this.getList();
|
|
|
+ },
|
|
|
+
|
|
|
+ handleSizeChange(val) {
|
|
|
+ this.size = val;
|
|
|
+ this.getList();
|
|
|
+ },
|
|
|
+
|
|
|
+ //获取待审核的数据列表
|
|
|
+ getList() {
|
|
|
+ this.listLoading = true;
|
|
|
+
|
|
|
+ this.http.post(this.port.report.importReportList, this.search,
|
|
|
+ res => {
|
|
|
+ this.listLoading = false;
|
|
|
+ if (res.code == "ok") {
|
|
|
+ this.list = res.data;
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: res.msg,
|
|
|
+ type: "error"
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ error => {
|
|
|
+ this.listLoading = false;
|
|
|
+ this.$message({
|
|
|
+ message: error,
|
|
|
+ type: "error"
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 通过日报
|
|
|
+ approve(id,date, item) {
|
|
|
+ console.log(item);
|
|
|
+ this.logining = true;
|
|
|
+
|
|
|
+ var ids = '';
|
|
|
+ var data = item.data;
|
|
|
+ data.forEach(element => {
|
|
|
+ ids +=(element.id+',');
|
|
|
+ });
|
|
|
+
|
|
|
+ this.http.post(this.port.report.approve, {id: id ,reportIds: ids},
|
|
|
+ res => {
|
|
|
+ this.logining = false;
|
|
|
+ if (res.code == "ok") {
|
|
|
+ this.$message({
|
|
|
+ message: "审核成功",
|
|
|
+ type: "success"
|
|
|
+ });
|
|
|
+ this.getList();
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: res.msg,
|
|
|
+ type: "error"
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ error => {
|
|
|
+ this.logining = false;
|
|
|
+ this.$message({
|
|
|
+ message: error,
|
|
|
+ type: "error"
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+// 修改数组
|
|
|
+ changeArr(arr) {
|
|
|
+ for (var i = 0; i < arr.length; i++) {
|
|
|
+ if(arr[i].id != -1 && arr[i].id != 0) {
|
|
|
+ if (arr[i].children != null && arr[i].children.length>0) {
|
|
|
+ arr[i].children = this.changeArr(arr[i].children);
|
|
|
+ }
|
|
|
+ arr[i].id && (arr[i].value = arr[i].id);
|
|
|
+ delete arr[i].id;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for(var i in arr) {
|
|
|
+ if(arr[i].id == -1 || arr[i].id == 0) {
|
|
|
+ arr.splice(i,1)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return arr;
|
|
|
+ },
|
|
|
+
|
|
|
+ //获取项目列表
|
|
|
+ getProjectList() {
|
|
|
+ this.http.post( this.port.project.list, {},
|
|
|
+ res => {
|
|
|
+ if (res.code == "ok") {
|
|
|
+ this.projectList = res.data;
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: res.msg,
|
|
|
+ type: "error"
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ error => {
|
|
|
+ this.$message({
|
|
|
+ message: error,
|
|
|
+ type: "error"
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ showDenyDialog(id,i, date, item) {
|
|
|
+ this.denyReasonDialog = true;
|
|
|
+ var ids = '';
|
|
|
+ var data = item.data;
|
|
|
+ data.forEach(element => {
|
|
|
+ ids +=(element.id+',');
|
|
|
+ });
|
|
|
+ this.denyForm = {id: id ,i:i, date: date, reportIds: ids, reason:null};
|
|
|
+ },
|
|
|
+
|
|
|
+ // 未通过日报
|
|
|
+ deny() {
|
|
|
+ this.logining = true;
|
|
|
+
|
|
|
+ this.http.post( this.port.report.deny, this.denyForm,
|
|
|
+ res => {
|
|
|
+ this.logining = false;
|
|
|
+ if (res.code == "ok") {
|
|
|
+ this.$message({
|
|
|
+ message: this.denyForm.i==0?"驳回成功":"撤销成功",
|
|
|
+ type: "success"
|
|
|
+ });
|
|
|
+ this.getList();
|
|
|
+ this.denyReasonDialog = false;
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: res.msg,
|
|
|
+ type: "error"
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ error => {
|
|
|
+ this.logining = false;
|
|
|
+ this.$message({
|
|
|
+ message: error,
|
|
|
+ type: "error"
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ let height = window.innerHeight;
|
|
|
+ this.tableHeight = height - 125;
|
|
|
+ const that = this;
|
|
|
+ window.onresize = function temp() {
|
|
|
+ that.tableHeight = window.innerHeight - 125;
|
|
|
+ };
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.getList();
|
|
|
+ this.getDepartment();
|
|
|
+ this.getProjectList();
|
|
|
+ }
|
|
|
+ };
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.propsbtn {
|
|
|
+ display: inline-block;
|
|
|
+ padding-left: 20px;
|
|
|
+}
|
|
|
+</style>
|