|
@@ -0,0 +1,420 @@
|
|
|
+<template>
|
|
|
+ <div class='weeklyCustomization'>
|
|
|
+ <div class="title">
|
|
|
+ <el-button @click="getCurrentWeek(-7)" size="small"><<</el-button>
|
|
|
+ <el-button @click="getCurrentWeek(0)" size="small">本周</el-button>
|
|
|
+ <el-button @click="getCurrentWeek(7)" size="small">>></el-button>
|
|
|
+ </div>
|
|
|
+ <div class="weekcen flexColumn" v-loading="submitLoading">
|
|
|
+ <div class="flexColumnAuto flex1">
|
|
|
+ <el-table :data="weekTableData" border style="width: 100%;" height="0" :span-method="arraySpanMethod">
|
|
|
+ <el-table-column prop="dateTime" label="日期" width="180">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span>{{ scope.row.dateTime }}</span>
|
|
|
+ (<span>{{ scope.row.weekDayTxt }}</span>)
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="项目" width="220">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-select v-model="scope.row.projectId" size="small" placeholder="请选择项目" clearable
|
|
|
+ @change="changeProject(scope.row.projectId, scope.$index)" :disabled="scope.row.state == 1">
|
|
|
+ <el-option v-for="item in projectList" :key="item.id" :label="item.projectName"
|
|
|
+ :value="item.id">
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="分类" width="180">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-select v-model="scope.row.groupId" size="small" placeholder="请选择分类"
|
|
|
+ @change="changeGroup(scope.row.groupId, scope.row.taskGroups, scope.$index)"
|
|
|
+ :disabled="scope.row.state == 1">
|
|
|
+ <el-option v-for="item in scope.row.taskGroups" :key="item.id" :label="item.name"
|
|
|
+ :value="item.id">
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="content" label="工作内容" width="300">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-input size="small" type="textarea" :rows="1" v-model="scope.row.content"
|
|
|
+ :disabled="scope.row.state == 1"></el-input>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="workingTime" label="时间(小时)" width="160">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-input-number size="small" v-model="scope.row.workingTime" :min="0" :max="12" :step="0.5"
|
|
|
+ :disabled="scope.row.state == 1"></el-input-number>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="projectAuditorId" label="审批人" width="160">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <!-- <span v-if="user.userNameNeedTranslate != '1'">{{ scope.row.projectAuditorName }}</span>
|
|
|
+ <span v-if="user.userNameNeedTranslate == '1'"><ww-open-data type='userName'
|
|
|
+ :openid='scope.row.projectAuditorName'></ww-open-data></span> -->
|
|
|
+ <span v-if="user.userNameNeedTranslate != '1'">{{ auditorNameFun(scope.row) }}</span>
|
|
|
+ <span v-if="user.userNameNeedTranslate == '1'"><ww-open-data type='userName'
|
|
|
+ :openid='scope.row.projectAuditorName'></ww-open-data></span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="state" label="状态" width="140" fixed="right">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <div class="controls">
|
|
|
+ <el-tag v-if="scope.row.state == 0" type="warning">待审</el-tag>
|
|
|
+ <el-tag v-if="scope.row.state == 1" type="success">通过</el-tag>
|
|
|
+ <el-tag v-if="scope.row.state == 2" type="danger">拒绝</el-tag>
|
|
|
+ <span v-if="scope.row.state != 1">
|
|
|
+ <el-link type="primary" :underline="false" class="el-icon-circle-plus-outline"
|
|
|
+ @click="insertRow(scope.$index)"></el-link>
|
|
|
+ <el-link type="primary" :underline="false" class="el-icon-delete"
|
|
|
+ @click="deleteRow(scope.$index)"></el-link>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ <div class="weeklyCustomization_btn">
|
|
|
+ <el-button @click="handleClose()">取消</el-button>
|
|
|
+ <el-button @click="submitWeekData(1)">暂存</el-button>
|
|
|
+ <el-button type="primary" @click="submitWeekData(0)">确定</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import cloneDeep from 'lodash/cloneDeep'; // 深拷贝
|
|
|
+export default {
|
|
|
+ name: '',
|
|
|
+ components: {},
|
|
|
+ props: {
|
|
|
+ weekParentData: {
|
|
|
+ type: Object,
|
|
|
+ default: () => {
|
|
|
+ return {}
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ weekTableData: [],
|
|
|
+ projectList: [],
|
|
|
+ nowTime: this.dayjs().format('YYYY-MM-DD'),
|
|
|
+ submitLoading: false,
|
|
|
+ permissions: JSON.parse(sessionStorage.getItem("permissions")),
|
|
|
+ user: JSON.parse(sessionStorage.getItem("user")),
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {},
|
|
|
+ watch: {},
|
|
|
+ created() { },
|
|
|
+ mounted() {
|
|
|
+ this.$set(this, 'weekTableData', [])
|
|
|
+ this.getCurrentWeek(0)
|
|
|
+ this.getProjectList()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // 提交与暂存
|
|
|
+ submitWeekData(draft) { // draft 暂存(1)提交(0)
|
|
|
+ const newWeekData = cloneDeep(this.weekTableData)
|
|
|
+
|
|
|
+ let strArr = this.judgmentData(newWeekData)
|
|
|
+ console.log(strArr, '<===== strArr')
|
|
|
+ if (strArr.length > 0) {
|
|
|
+ this.$message({
|
|
|
+ message: `【${strArr.join('、')}】日期填写工作时长小于系统设置的每日工作时长`,
|
|
|
+ type: "error"
|
|
|
+ });
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ let formData = new FormData();
|
|
|
+ formData.append("draft", draft);
|
|
|
+ let fixation = {
|
|
|
+ id: -1,
|
|
|
+ projectId: '',
|
|
|
+ subProjectId: 0,
|
|
|
+ taskId: 0,
|
|
|
+ reportTimeType: 1,
|
|
|
+ workingTime: 0,
|
|
|
+ multiWorktime: 0,
|
|
|
+ content: '',
|
|
|
+ isOvertime: 0,
|
|
|
+ // professionProgress: [],
|
|
|
+ groupId: '',
|
|
|
+ stage: '',
|
|
|
+ createDate: '',
|
|
|
+ projectAuditorId: '',
|
|
|
+ basecostId: 0,
|
|
|
+ degreeId: -1,
|
|
|
+ customData: 0,
|
|
|
+ customText: '-',
|
|
|
+ }
|
|
|
+
|
|
|
+ const arr = newWeekData
|
|
|
+ .filter(data => data.projectId)
|
|
|
+ .map(data => ({
|
|
|
+ ...fixation,
|
|
|
+ projectId: data.projectId,
|
|
|
+ createDate: data.dateTime,
|
|
|
+ content: data.content,
|
|
|
+ projectAuditorId: data.projectAuditorId,
|
|
|
+ workingTime: data.workingTime,
|
|
|
+ groupId: data.groupId,
|
|
|
+ id: data.id || -1,
|
|
|
+ }));
|
|
|
+
|
|
|
+ arr.forEach(item => {
|
|
|
+ Object.entries(item).forEach(([key, value]) => {
|
|
|
+ formData.append(key, value);
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ this.submitLoading = true
|
|
|
+ this.http.uploadFile(this.port.report.editPort, formData,
|
|
|
+ res => {
|
|
|
+ this.submitLoading = false
|
|
|
+ if (res.code == "ok") {
|
|
|
+ this.$message({
|
|
|
+ message: `${draft ? '暂存成功:' : '提交成功:'}`,
|
|
|
+ type: "success"
|
|
|
+ });
|
|
|
+ this.$emit('weekClose')
|
|
|
+ this.$emit('weekSubmit')
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: `${draft ? '暂存失败:' : '提交失败:'}` + res.msg,
|
|
|
+ type: "error"
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ error => {
|
|
|
+ this.submitLoading = false
|
|
|
+ this.$message({
|
|
|
+ message: error,
|
|
|
+ type: "error"
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 判断是否小于系统设置的每日工作时间
|
|
|
+ judgmentData(data) {
|
|
|
+ const { allday } = this.user.timeType // 系统设置的每日工作时间
|
|
|
+ const result = [];
|
|
|
+ data.forEach((item) => {
|
|
|
+ const date = item.dateTime;
|
|
|
+ const index = result.findIndex((arr) => arr[0].dateTime === date);
|
|
|
+
|
|
|
+ if (index === -1) {
|
|
|
+ result.push([item]);
|
|
|
+ } else {
|
|
|
+ result[index].push(item);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ const strArr = result
|
|
|
+ .filter((arr) => arr[0].projectId)
|
|
|
+ .filter(
|
|
|
+ (arr) => arr.reduce((sum, item) => sum + (+item.workingTime || 0), 0) < allday
|
|
|
+ )
|
|
|
+ .map((arr) => arr[0].dateTime);
|
|
|
+
|
|
|
+ return strArr
|
|
|
+ },
|
|
|
+ // 项目切换事件
|
|
|
+ changeProject(projectId, index) {
|
|
|
+ this.$set(this.weekTableData[index], 'projectAuditorId', '')
|
|
|
+ this.$set(this.weekTableData[index], 'projectAuditorName', '')
|
|
|
+ this.$set(this.weekTableData[index], 'groupId', '')
|
|
|
+ if (projectId) {
|
|
|
+ this.getProjectGroup(projectId, index)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 分组切换事件
|
|
|
+ changeGroup(groupId, groupList, index) {
|
|
|
+ let newArr = groupList.filter(item => item.id == groupId)
|
|
|
+ if (!newArr[0].inchargerId) {
|
|
|
+ this.$message({
|
|
|
+ message: `【${newArr[0].name}】分类未设置审批人,请联系该项目管理人员`,
|
|
|
+ type: "error"
|
|
|
+ });
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.$set(this.weekTableData[index], 'projectAuditorId', newArr[0].inchargerId)
|
|
|
+ this.$set(this.weekTableData[index], 'projectAuditorName', newArr[0].inchargerName)
|
|
|
+ },
|
|
|
+ // 获取周数据
|
|
|
+ async getCurrentWeek(time) {
|
|
|
+ if (!time) {
|
|
|
+ this.nowTime = this.dayjs().format('YYYY-MM-DD')
|
|
|
+ } else {
|
|
|
+ this.nowTime = this.dayjs(this.nowTime).add(time, 'day').format('YYYY-MM-DD')
|
|
|
+ }
|
|
|
+ let { data } = await this.getData('/report/getWeeklyFillReportData', { targetDate: this.nowTime })
|
|
|
+ const { dateList, projectList, sumTimeList, cardTimeList } = data;
|
|
|
+ const weekTableData = dateList.flatMap(date => {
|
|
|
+ const { weekDayTxt, date: dateTime, reportList } = date;
|
|
|
+ const reports = reportList.map(report => ({ ...report, weekDayTxt, dateTime }));
|
|
|
+ return reports.length > 0 ? reports : [{ weekDayTxt, dateTime }];
|
|
|
+ });
|
|
|
+
|
|
|
+ this.weekTableData = weekTableData;
|
|
|
+ },
|
|
|
+ // 获取项目列表
|
|
|
+ async getProjectList() {
|
|
|
+ let { data } = await this.getData('/project/getProjectList')
|
|
|
+ this.projectList = data
|
|
|
+ },
|
|
|
+ // 获取项目下的分组
|
|
|
+ async getProjectGroup(projectId, index) {
|
|
|
+ const { isSubstitude } = this.weekParentData;
|
|
|
+ let { data } = await this.getData('/task-group/listProjectGroupAndAuditor', { projectId, isSubstitude: isSubstitude ? 1 : 0 })
|
|
|
+ if (data.length == 0) {
|
|
|
+ this.$message({
|
|
|
+ message: '分类未设置,请联系该项目管理人员',
|
|
|
+ type: "error"
|
|
|
+ });
|
|
|
+ } else if (data.length == 1) {
|
|
|
+ this.$set(this.weekTableData[index], 'groupId', data[0].id)
|
|
|
+ this.$set(this.weekTableData[index], 'projectAuditorId', data[0].inchargerId)
|
|
|
+ this.$set(this.weekTableData[index], 'projectAuditorName', data[0].inchargerName)
|
|
|
+ if (!data[0].inchargerId) {
|
|
|
+ this.$message({
|
|
|
+ message: `【${newArr[0].name}】分类未设置审批人,请联系该项目管理人员`,
|
|
|
+ type: "error"
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.$set(this.weekTableData[index], 'taskGroups', data)
|
|
|
+ },
|
|
|
+ // 插入一行
|
|
|
+ insertRow(index) {
|
|
|
+ this.weekTableData.splice(index + 1, 0, {
|
|
|
+ dateTime: this.weekTableData[index].dateTime,
|
|
|
+ weekDayTxt: this.weekTableData[index].weekDayTxt,
|
|
|
+ content: '',
|
|
|
+ workingTime: 0,
|
|
|
+ projectId: '',
|
|
|
+ projectAuditorId: '',
|
|
|
+ projectAuditorName: '',
|
|
|
+ groupId: '',
|
|
|
+ groupList: [],
|
|
|
+ approverList: [],
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 删除一行
|
|
|
+ deleteRow(index) {
|
|
|
+ this.weekTableData.splice(index, 1)
|
|
|
+ },
|
|
|
+ // 合并单元格
|
|
|
+ arraySpanMethod({ row, column, rowIndex, columnIndex }) {
|
|
|
+ let spanOneArr = [], concatOne = 0;
|
|
|
+ this.weekTableData.map((item, index) => {
|
|
|
+ if (index === 0) {
|
|
|
+ spanOneArr.push(1);
|
|
|
+ } else {
|
|
|
+ if (item.dateTime === this.weekTableData[index - 1].dateTime) {
|
|
|
+ spanOneArr[concatOne] += 1;
|
|
|
+ spanOneArr.push(0);
|
|
|
+ } else {
|
|
|
+ spanOneArr.push(1);
|
|
|
+ concatOne = index;
|
|
|
+ };
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ if (columnIndex === 0) {
|
|
|
+ const _row = spanOneArr[rowIndex];
|
|
|
+ const _col = _row > 0 ? 1 : 0;
|
|
|
+ return {
|
|
|
+ rowspan: _row,
|
|
|
+ colspan: _col
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 回显审批人名字
|
|
|
+ auditorNameFun(item) {
|
|
|
+ const { groupId, taskGroups } = item;
|
|
|
+
|
|
|
+ if (groupId) {
|
|
|
+ const newArr = taskGroups.filter(v => v.id === groupId);
|
|
|
+ return newArr.length > 0 ? newArr[0].inchargerName : '';
|
|
|
+ }
|
|
|
+
|
|
|
+ return '';
|
|
|
+ },
|
|
|
+ // post 方法请求二次封装
|
|
|
+ async getData(url, param) {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ this.http.post(url, param,
|
|
|
+ res => {
|
|
|
+ resolve(res)
|
|
|
+ },
|
|
|
+ error => {
|
|
|
+ this.$message({
|
|
|
+ message: error,
|
|
|
+ type: "error"
|
|
|
+ });
|
|
|
+ reject(error)
|
|
|
+ }
|
|
|
+ )
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 关闭弹窗
|
|
|
+ handleClose() {
|
|
|
+ this.$emit('weekClose')
|
|
|
+ },
|
|
|
+ },
|
|
|
+}
|
|
|
+</script>
|
|
|
+<style scoped lang='scss'>
|
|
|
+.flexColumn {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+}
|
|
|
+
|
|
|
+.flexColumnAuto {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ overflow: auto;
|
|
|
+}
|
|
|
+
|
|
|
+.flex1 {
|
|
|
+ flex: 1;
|
|
|
+ overflow-y: auto;
|
|
|
+}
|
|
|
+
|
|
|
+.weeklyCustomization {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ position: absolute;
|
|
|
+ top: 16px;
|
|
|
+ left: 140px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .weekcen {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .weeklyCustomization_btn {
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+ padding-top: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .controls {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ width: 100%;
|
|
|
+
|
|
|
+ .el-link {
|
|
|
+ font-size: 18px;
|
|
|
+ margin-right: 5px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|