Explorar el Código

Merge remote-tracking branch 'origin/master'

yurk hace 2 años
padre
commit
1731514311

+ 10 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectController.java

@@ -1185,5 +1185,15 @@ public class ProjectController {
     public HttpRespMsg timeCostAndExpenseByProject(HttpServletRequest request,String startDate,String endDate,Integer projectId){
         return projectService.timeCostAndExpenseByProject(request,startDate,endDate,projectId);
     }
+
+    /**
+     * 获取最近填写的三个项目
+     * @param request
+     * @return
+     */
+    @RequestMapping("/nearProject")
+    public HttpRespMsg nearProject(HttpServletRequest request){
+        return projectService.nearProject(request);
+    }
 }
 

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Report.java

@@ -52,7 +52,7 @@ public class Report extends Model<Report> {
     private Integer projectId;
 
     /**
-     * 日期
+     * 工作日期
      */
     @TableField("create_date")
     @DateTimeFormat(pattern = "yyyy-MM-dd")

+ 2 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ProjectMapper.java

@@ -151,4 +151,6 @@ public interface ProjectMapper extends BaseMapper<Project> {
     List<Map<String, Object>> getExportDegreeCost(Integer companyId, String startDate, String endDate,Integer projectId, List<Integer> deptIds, List<Integer> filterDeptIds, List<Integer> deptRelatedProjectIds);
 
     List<Map<String, Object>> getDegreeDetailCost(Integer companyId, String startDate, String endDate, Integer projectId,int curProjectId, List<Integer> finalDeptIds, List<Integer> filterDeptIds, List<Integer> deptIds);
+
+    List<Project> selectNearProject(String userId);
 }

+ 2 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectService.java

@@ -225,4 +225,6 @@ public interface ProjectService extends IService<Project> {
     HttpRespMsg exportDegreeCost(String startDate, String endDate, Integer projectId,Integer deptId, HttpServletRequest request);
 
     HttpRespMsg timeCostAndExpenseByProject(HttpServletRequest request, String startDate, String endDate, Integer projectId);
+
+    HttpRespMsg nearProject(HttpServletRequest request);
 }

+ 14 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java

@@ -9345,4 +9345,18 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
         httpRespMsg.data = map;
         return httpRespMsg;
     }
+
+    /**
+     * 获取最新填写的三个项目
+     * @param request
+     * @return
+     */
+    @Override
+    public HttpRespMsg nearProject(HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        User user = userMapper.selectById(request.getHeader("token"));
+        List<Project> projects = projectMapper.selectNearProject(user.getId());
+        httpRespMsg.data = projects;
+        return httpRespMsg;
+    }
 }

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectMapper.xml

@@ -1570,4 +1570,25 @@
         GROUP BY a.project_id,b.id,a.degree_id
         ORDER BY b.id,a.degree_id ASC
     </select>
+
+    <select id="selectNearProject" resultType="com.management.platform.entity.Project">
+        select * from project
+        where id in (
+            SELECT project_id
+            from (
+                SELECT project_id
+                FROM (
+                        SELECT DISTINCT *
+                        FROM report
+                        WHERE creator_id = #{userId}
+                        order by create_time
+                        DESC
+                    ) p1
+                    GROUP BY project_id
+                    order by create_time
+                    DESC
+                    LIMIT 3
+            ) p2
+        )
+    </select>
 </mapper>

+ 40 - 3
fhKeeper/formulahousekeeper/timesheet/src/components/taskComponent.vue

@@ -4,10 +4,18 @@
         <el-form ref="form1" :model="addForm" :rules="taskRules" label-width="120px">
             <el-form-item label="所属项目" 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 v-for="item in projectList" :key="item.id" :label="item.projectName + item.projectCode" :value="item.id">
+
+                    <!-- <el-option v-for="item in projectList" :key="item.id" :label="item.projectName + item.projectCode" :value="item.id">
                         <span style="float: left;color: #8492a6;">{{ item.projectCode }}</span>
                         <span style="float: right;font-size: 13px;">{{ item.projectName }}</span>
-                    </el-option>
+                    </el-option> -->
+                    <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="所属任务分组" v-if="showOrNot" prop="groupId">
@@ -817,7 +825,8 @@ export default {
         taskListTotal: 0,
         dynamicTab: true,
         dailyList: [],
-        meetingId: ''
+        meetingId: '',
+        integrationProjectList: []
     };
   },
   computed: {},
@@ -887,6 +896,7 @@ export default {
         res => {
             if (res.code == "ok") {
                 this.projectList = res.data;
+                this.getRecentlyProject()
             } else {
                 this.$message({
                     message: res.msg,
@@ -901,6 +911,33 @@ export default {
             });
         });
     },
+    // 获取最近项目列表
+    getRecentlyProject() {
+        this.http.post('/project/nearProject',{},res => {
+            if(res.code == 'ok'){
+                let topObj = {
+                    label: '最近选择项目',
+                    peojectList: res.data 
+                }
+                let botomObj = {
+                    label: '全部项目',
+                    peojectList: this.projectList
+                }
+                this.integrationProjectList = [topObj, botomObj]
+                console.log(this.integrationProjectList, '整合')
+            }else {
+                this.$message({
+                    message: res.msg,
+                    type: 'error'
+                })
+            }
+        },err => {
+            this.$message({
+                message: err,
+                type: 'error'
+            })
+        })
+    },
     // 获取任务分组
     getTaskGrouping() {
         this.http.post('/task-group/list', {projectId:this.addForm.projectId},

+ 16 - 9
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

@@ -430,17 +430,17 @@
                             @change="selectProject(domain, index)"
                             :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)" popper-class="projectSelectPopperClass">
                             
-                                <el-option v-for="item in fillProjectList" :disabled="item.status!=1 && item.status!=4" :key="item.id" :label="item.projectName + '\u3000' + item.projectCode" :value="item.id">
+                                <!-- <el-option v-for="item in fillProjectList" :disabled="item.status!=1 && item.status!=4" :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> -->
 
-                                <!-- <el-option-group v-for="group in integrationProjectList" :key="group.label" :label="group.label">
+                                <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" :disabled="item.status!=1 && item.status!=4">
                                         <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-option-group>
 
                             </el-select>
                             <template v-if="user.timeType.mainProjectState != 1">
@@ -593,17 +593,17 @@
                                 <el-select v-model="domain.projectId" :placeholder="$t('defaultText.pleaseSelectSnItem')" style="width:200px;" clearable="true"  filterable="true" value-key="id"
                                 @change="selectProject(domain, index)"
                                 :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)" popper-class="projectSelectPopperClass">
-                                    <el-option v-for="item in fillProjectList" :disabled="item.status!=1 && item.status!=4" :key="item.id" :label="item.projectName + '\u3000' + item.projectCode" :value="item.id">
+                                    <!-- <el-option v-for="item in fillProjectList" :disabled="item.status!=1 && item.status!=4" :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> -->
 
-                                    <!-- <el-option-group v-for="group in integrationProjectList" :key="group.label" :label="group.label">
+                                    <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" :disabled="item.status!=1 && item.status!=4">
                                             <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-option-group>
 
                                 </el-select>
                                 <template v-if="user.timeType.mainProjectState != 1">
@@ -1994,6 +1994,7 @@
                 for(let i in domains){
                     if(domains[i].projectId){
                         if(this.reportTimeType.multiWorktime == 1){
+                            console.log('进一')
                             for(let m in domains[i].worktimeList){
                                 if(domains[i].worktimeList[m].startTime && domains[i].worktimeList[m].endTime){
                                     hours += this.getHour(domains[i].worktimeList[m].startTime, domains[i].worktimeList[m].endTime)
@@ -2001,6 +2002,7 @@
                             }
                         }else{
                             if(this.user.timeType.type == 2){
+                            console.log('进2')
                                 if(domains[i].startTime && domains[i].endTime){
                                     // let selectionTime = this.getHourMinutes(domains[i].startTime, domains[i].endTime)
                                     let selectionTime = this.getHour(domains[i].startTime, domains[i].endTime)
@@ -2016,11 +2018,13 @@
                                     // hours += this.getHour(domains[i].startTime, domains[i].endTime)
                                 }
                             }else{
+                            console.log('进3')
                                 hours += domains[i].workingTime ? parseFloat(domains[i].workingTime) : 0
                             }
                         }
                     }
                 }
+                console.log(hours, '需要返回的数据')
                 return hours.toFixed(2)
             },
         },
@@ -2056,7 +2060,6 @@
                     that.dataLoading = that.$store.state.dataLoading
                 }, 1000)
             }
-            // this.getRecentlyProject() // 近期选择的项目
         },
         methods: {
             ...mapMutations(['upDataLoading']),
@@ -4472,6 +4475,7 @@
                             }
                         }
                         this.projectList = res.data;
+                        
                         // console.log("项目列表",this.projectList);
                     } else {
                         this.$message({
@@ -4500,6 +4504,7 @@
                             }
                         }
                         this.fillProjectList = res.data;
+                        this.getRecentlyProject() 
                     } else {
                         this.$message({
                             message: res.msg,
@@ -5730,6 +5735,7 @@
                                 // 关闭弹窗 并 清空
                                 this.selProjectList = []
                                 this.selCon = []
+                                this.getRecentlyProject()
                             } else {
                                 this.$message({
                                     message: res.msg,
@@ -6358,6 +6364,7 @@
                                 this.jsTime = 0
                                 this.getReportList();
                                 this.getDepartment();
+                                this.getRecentlyProject()
                             } else {
                                 this.$message({
                                     message: (this.isDraft==0?this.$t('message.SubmissionFailed') + ':':this.$t('message.Stagingfailed') + ':')+res.msg,

+ 92 - 0
fhKeeper/formulahousekeeper/timesheet/static/css/index.css

@@ -0,0 +1,92 @@
+* {
+    margin: 0;
+    padding: 0;
+}
+
+body {
+    background-color: #ebf1fd;
+}
+
+.header {
+    display: flex;
+    flex-direction: column;
+    background-color: white;
+}
+
+.header .time-message {
+    display: flex;
+    height: 44px;
+    align-items: center;
+    padding: 0 33.5px;
+    justify-content: space-between;
+}
+
+.header .title {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    height: 44px;
+}
+
+.header .title span {
+    font-weight: 500;
+    font-size: 17px;
+}
+
+.img {
+    width: 120px;
+    height: 239px;
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+    display: flex;
+    align-items: center;
+    flex-direction: column;
+}
+
+.img_div {
+    border-radius: 50%;
+    overflow: hidden;
+    width: 88px;
+    height: 88px;
+    border: 3px white solid;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+}
+
+.hello_text {
+    font-size: 26px;
+    font-weight: 600;
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+}
+
+.hello_text_name {
+    font-size: 20px;
+    color: #3370ff;
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, 50%);
+    text-align: center;
+}
+
+.hello_text_welcome {
+    position: absolute;
+    bottom: 0;
+    size: 20px;
+    font-weight: 500;
+    text-align: center;
+    white-space: nowrap;
+}
+
+.icon {
+    position: absolute;
+    bottom: 44px;
+    left: 50%;
+    transform: translate(-50%, 0);
+}

+ 61 - 0
fhKeeper/formulahousekeeper/timesheet/static/js/index.js

@@ -0,0 +1,61 @@
+let lang = window.navigator.language;
+console.log(lang);
+
+
+function apiAuth() {
+    if (!window.h5sdk) {
+        console.log('invalid h5sdk')
+        // alert('please open in feishu')
+        return
+    }
+
+    // 通过服务端的Route: get_appid获取app_id
+    // 服务端Route: get_appid的具体内容请参阅服务端模块server.py的get_appid()函数
+    // 为了安全,app_id不应对外泄露,尤其不应在前端明文书写,因此此处从服务端获取
+    fetch(`/get_appid`).then(response1 => response1.json().then(res1 => {
+        console.log("get appid succeed: ", res1.appid);
+        // 通过error接口处理API验证失败后的回调
+        window.h5sdk.error(err => {
+            throw('h5sdk error:', JSON.stringify(err));
+        });
+        // 通过ready接口确认环境准备就绪后才能调用API
+        window.h5sdk.ready(() => {
+            console.log("window.h5sdk.ready");
+            console.log("url:", window.location.href);
+            // 调用JSAPI tt.requestAuthCode 获取 authorization code
+            tt.requestAuthCode({
+                appId: res1.appid,
+                // 获取成功后的回调
+                success(res) {
+                    console.log("getAuthCode succeed");
+                    //authorization code 存储在 res.code
+                    // 此处通过fetch把code传递给接入方服务端Route: callback,并获得user_info
+                    // 服务端Route: callback的具体内容请参阅服务端模块server.py的callback()函数
+                    fetch(`/callback?code=${res.code}`).then(response2 => response2.json().then(res2 => {
+                        console.log("getUserInfo succeed");
+                        // 示例Demo中单独定义的函数showUser,用于将用户信息展示在前端页面上
+                        showUser(res2);}
+                        )
+                    ).catch(function (e) {console.error(e)})
+                },
+                // 获取失败后的回调
+                fail(err) {
+                    console.log(`getAuthCode failed, err:`, JSON.stringify(err));
+                }
+            })
+        }
+        )
+    })).catch(function (e) { // 从服务端获取app_id失败后的处理
+        console.error(e)
+        })
+}
+
+function showUser(res) {
+    // 展示用户信息
+    // 头像
+    $('#img_div').html(`<img src="${res.avatar_url}" width="100%" height=""100%/>`);
+    // 名称
+    $('#hello_text_name').text(lang === "zh_CN" || lang === "zh-CN" ? `${res.name}` : `${res.en_name}`);
+    // 欢迎语
+    $('#hello_text_welcome').text(lang === "zh_CN" || lang === "zh-CN" ? "欢迎使用飞书" : "welcome to Feishu");
+}

+ 17 - 0
fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue

@@ -384,6 +384,13 @@
             <!-- <van-search v-model="userName" placeholder="输入项目名称搜索" @clear="sea()" @blur="sea()" @search="sea()"></van-search> -->
             <van-search v-model="userName" placeholder="请输入项目名称/编号" @clear="sea()" @blur="sea()" @search="sea()" @input="sea()"/>
             <div style="minHeight:300px;">
+                <div class="ryuan" style="color: rgb(185 185 185);">近期选择项目</div>
+                <div v-for="(item, index) in integrationProjectList" :key="index" class="ryuan" @click="fZr(item, index)">
+                    <p>{{item.projectName}}</p>
+                    <p style="margin-top: 5px;color: #9697B2;">{{item.projectCode}}</p> 
+                </div>
+
+                <div class="ryuan" style="color: rgb(185 185 185);">全部项目</div>
                 <div v-for="(item, index) in projectss" :key="item.id" class="ryuan" @click="fZr(item, index)">
                     <p>{{item.projectName}}</p>
                     <p style="margin-top: 5px;color: #9697B2;">{{item.projectCode}}</p> 
@@ -398,6 +405,7 @@ import timetoolVue from '../timetool/timetool.vue';
     export default {
         data() {
             return {
+                integrationProjectList: [],
                 cardRefLoading: false,
                 today: '',
 
@@ -532,6 +540,14 @@ import timetoolVue from '../timetool/timetool.vue';
         },
 
         methods: {
+            getRecentlyProject() {
+                this.$axios.post('/project/nearProject',{})
+                .then(res => {
+                    if(res.code == 'ok'){
+                        this.integrationProjectList = res.data
+                    }
+                }).catch(err => {this.$toast.clear();this.cardRefLoading = false;})
+            },
             // 判断两个时间段是否重叠
             timeOverlap(idx, dateAr) {
                 let zhi = 0
@@ -675,6 +691,7 @@ import timetoolVue from '../timetool/timetool.vue';
                         this.project = res.data;
                         this.projectss = this.projectss.filter(p=>p.status == 1 || p.status == 4);
                         this.proads = res.data
+                        this.getRecentlyProject()
                     } else {
                         this.$toast.fail('获取失败:'+res.msg);
                     }

+ 26 - 3
fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/weekEdit.vue

@@ -347,9 +347,21 @@
         <van-popup v-model="showPickerUserddp" position="bottom" style="height: 80%">
             <van-search v-model="userName" placeholder="请输入项目名称/编号" @clear="sea()" @blur="sea()" @search="sea()" @input="sea()"/>
             <div style="minHeight:300px;">
-                <div v-for="(item, index) in projectss" :key="item.id" class="ryuan" @click="fZr(item, index)">
+                <!-- <div v-for="(item, index) in projectss" :key="item.id" class="ryuan" @click="fZr(item, index)">
                     <p>{{item.projectName}}</p> 
                     <p style="margin-top: 5px;color: #9697B2;">{{item.projectCode}}</p> 
+                </div> -->
+
+                <div class="ryuan" style="color: rgb(185 185 185);">近期选择项目</div>
+                <div v-for="(item, index) in integrationProjectList" :key="index" class="ryuan" @click="fZr(item, index)">
+                    <p>{{item.projectName}}</p>
+                    <p style="margin-top: 5px;color: #9697B2;">{{item.projectCode}}</p> 
+                </div>
+
+                <div class="ryuan" style="color: rgb(185 185 185);">全部项目</div>
+                <div v-for="(item, index) in projectss" :key="item.id" class="ryuan" @click="fZr(item, index)">
+                    <p>{{item.projectName}}</p>
+                    <p style="margin-top: 5px;color: #9697B2;">{{item.projectCode}}</p> 
                 </div>
             </div>
         </van-popup> 
@@ -448,11 +460,20 @@
                     searchText: '',
                     item: {},
                     list: [],
-                    searchList: []
-                }
+                    searchList: [],
+                },
+                integrationProjectList: []
             };
         },
         methods: {
+            getRecentlyProject() {
+                this.$axios.post('/project/nearProject',{})
+                .then(res => {
+                    if(res.code == 'ok'){
+                        this.integrationProjectList = res.data
+                    }
+                }).catch(err => {this.$toast.clear();this.cardRefLoading = false;})
+            },
             auditorClick(domainIndex,auditorIndex){
                 this.auditor.index = domainIndex
                 this.auditor.auditorIndex = auditorIndex
@@ -747,6 +768,8 @@
                         this.projectss = res.data;
                         this.projectss = this.projectss.filter(p=>p.status == 1);
                         this.proads = res.data
+
+                        this.getRecentlyProject()
                     } else {
                         this.$toast.fail('获取失败:'+res.msg);
                     }

+ 23 - 1
fhKeeper/formulahousekeeper/timesheet_h5/src/views/task/editask.vue

@@ -9,6 +9,13 @@
                         <van-search v-model.trim="select_project_show_searchText" placeholder="输入项目名称搜索" @input="onSearchProject"></van-search>
                         <div style="minHeight:300px;">
                             <van-radio-group v-model="taskform.projectId">
+                                <div class="ewProjectlist">近期选择项目</div>
+                                <van-radio v-for="(uitem, index) in integrationProjectList" :key="index" :name="uitem" style="padding:10px">
+                                    <span>{{uitem.projectName}}</span>
+                                </van-radio>
+                            </van-radio-group>
+                            <van-radio-group v-model="taskform.projectId">
+                                <div class="ewProjectlist">全部项目</div>
                                 <van-radio v-for="uitem in select_project_array" :key="uitem.id" :name="uitem" style="padding:10px">
                                     <span>{{uitem.projectName}}</span>
                                 </van-radio>
@@ -209,8 +216,9 @@ export default {
             select_project_array_tow: [], 
             select_grouping_array: [],
             select_list_array: [],
-            select_project_show_searchText: ''
+            select_project_show_searchText: '',
 
+            integrationProjectList: []
         }
     },
     mounted() {
@@ -293,11 +301,20 @@ export default {
                 if(res.code == "ok") {
                     this.select_project_array = res.data
                     this.select_project_array_tow = res.data
+                    this.getRecentlyProject()
                 } else {
                     this.$toast.fail('失败');
                 }
             }).catch(err=> {this.$toast.clear();console.log(err)});
         },
+        getRecentlyProject() {
+            this.$axios.post('/project/nearProject',{})
+            .then(res => {
+                if(res.code == 'ok'){
+                    this.integrationProjectList = res.data
+                }
+            }).catch(err => {this.$toast.clear();this.cardRefLoading = false;})
+        },
         getTaskGrouping() {
             this.$axios.post("/task-group/list", {projectId:this.taskform.projectId})
             .then(res => {
@@ -568,6 +585,11 @@ export default {
     display: inline-block;
     float: right;
 }
+.ewProjectlist {
+    padding: 10px 10px 10px 20px;
+    border-bottom: 1px solid #666;
+    color: #a5a5a5;
+}
 </style>
 <style>
     .editaskBox .van-radio__label {