Sfoglia il codice sorgente

Merge branch '165' of uskycloud/usky-web-mobile into master

gez 8 mesi fa
parent
commit
490b303658

+ 2 - 2
README.md

@@ -4,7 +4,7 @@
 ### 密码:FIRE_admin123
 
 
- ## node
- >18.1.0
+## node>18.1.0||16.17.1
+ 
 
 

+ 22 - 0
src/api/business/project.js

@@ -95,6 +95,28 @@ export function projectApi() {
                 url: '/service-iot/pmProject/joinProject?projectId=' + param,
                 method: 'GET',
             })
+        },
+        TimedReports() {
+            return request({
+                url: '/service-iot/pmWorkReport/timedReports',
+                method: 'GET',
+            })
+        },
+        usersProjectWorkTime(params) {
+            return request({
+                url: '/service-iot/pmProject/usersProjectWorkTime',
+                method: 'GET',
+                params
+            })
+        },
+        // 树结构查询部门--用户列表
+        deptUserTreeSelect(query) {
+            return request({
+                url: '/system/dept/deptUserTreeSelect',
+                method: 'get',
+                params: query
+            })
         }
+        
     }
 }

+ 1 - 1
src/config.js

@@ -5,7 +5,7 @@ export default {
   //#endif
 
   //#ifdef H5
-  baseUrl: import.meta.env.MODE === "production" ? `https://${window.location.host}/prod-api` : `http://172.16.120.165:13200/dev-api`,
+  baseUrl: import.meta.env.MODE === "production" ? `https://${window.location.host}/prod-api` : `http://172.16.120.165:801/dev-api`,
   //#endif
 
   websiteUrl: "https://qhome.usky.cn",

+ 2 - 12
src/manifest.json

@@ -5,13 +5,12 @@
     "versionName" : "2.1.9",
     "versionCode" : 19,
     "transformPx" : false,
-    /* 5+App特有相关 */
     "app-plus" : {
         "compatible" : {
-            "ignoreVersion" : true //true表示忽略版本检查提示框,HBuilderX1.9.0及以上版本支持
+            "ignoreVersion" : true
         },
         "kernel" : {
-            "ios" : "WKWebview" //或者 "WKWebview"
+            "ios" : "WKWebview"
         },
         "usingComponents" : true,
         "nvueStyleCompiler" : "uni-app",
@@ -28,7 +27,6 @@
             "landscape-primary",
             "landscape-secondary"
         ],
-        /* 模块配置 */
         "modules" : {
             "VideoPlayer" : {},
             "iBeacon" : {},
@@ -40,9 +38,7 @@
             "Camera" : {},
             "LivePusher" : {}
         },
-        /* 应用发布信息 */
         "distribute" : {
-            /* android打包配置 */
             "android" : {
                 "permissions" : [
                     "<uses-feature android:name=\"android.hardware.camera\"/>",
@@ -88,7 +84,6 @@
                 "abiFilters" : [ "armeabi-v7a", "arm64-v8a" ],
                 "targetSdkVersion" : 30
             },
-            /* ios打包配置 */
             "ios" : {
                 "dSYMs" : false,
                 "privacyDescription" : {
@@ -107,7 +102,6 @@
                 },
                 "UIBackgroundModes" : ""
             },
-            /* SDK配置 */
             "sdkConfigs" : {
                 "ad" : {},
                 "maps" : {
@@ -201,13 +195,10 @@
             }
         },
         "safearea" : {
-            //可选,JSON对象,安全区域配置
             "offset" : "none"
         }
     },
-    /* 快应用特有相关 */
     "quickapp" : {},
-    /* 小程序特有相关 */
     "mp-weixin" : {
         "appid" : "",
         "setting" : {
@@ -257,5 +248,4 @@
     "vueVersion" : "3",
     "locale" : "zh-Hans"
 }
-/* ios打包配置 *//* SDK配置 */
 

+ 25 - 1
src/pages.json

@@ -660,6 +660,30 @@
             }
           }
         },
+        {
+          "path": "projectMange/overview/index",
+          "style": {
+            "navigationBarTitleText": "项目概览",
+            "enablePullDownRefresh": false,
+            "navigationStyle": "custom",
+            "app-plus": {
+              "bounce": "none",
+              "titleNView": false
+            }
+          }
+        },
+        {
+          "path": "projectMange/record/timingLog",
+          "style": {
+            "navigationBarTitleText": "定时日志",
+            "enablePullDownRefresh": false,
+            "navigationStyle": "custom",
+            "app-plus": {
+              "bounce": "none",
+              "titleNView": false
+            }
+          }
+        },
         {
           "path": "projectMange/write/index",
           "style": {
@@ -675,7 +699,7 @@
         {
           "path": "projectMange/write/insert",
           "style": {
-            "navigationBarTitleText": "报告填写",
+            "navigationBarTitleText": "",
             "enablePullDownRefresh": false,
             "navigationStyle": "custom",
             "app-plus": {

+ 17 - 19
src/pages/business/common/projectMange/list/addEdit.vue

@@ -169,9 +169,9 @@ function insertUsers(key) {
   //将人员选中数据传入store中
   systemStore.mallList.activeUserList = state[key];
   if (key === "projectHeadList") {
-    proxy.$tab.navigateTo(`/pages/business/common/projectMange/mall/index?number=1`);
+    proxy.$tab.navigateTo(`/pages/business/common/projectMange/mall/index?number=1&type=1`);
   } else if (key === "projectMemberList") {
-    proxy.$tab.navigateTo(`/pages/business/common/projectMange/mall/index?number=50`);
+    proxy.$tab.navigateTo(`/pages/business/common/projectMange/mall/index?number=50&type=2`);
   }
 }
 
@@ -364,24 +364,22 @@ onUnload(() => {
 </script>
 
 <style lang="scss" scoped>
-:deep(.u-cell__body) {
-  color: #000000;
-  font-size: 12px;
-  padding: 10px 0px !important;
-}
-
-:deep(.u-collapse-item__content) {
-  overflow: auto;
-}
-
-:deep(.u-collapse-item__content__text) {
-  padding: 0;
-}
-
-:deep(.u-cell__left-icon-wrap) {
-  margin: 0;
+:deep() {
+  .u-cell__body {
+    color: #000000;
+    font-size: 12px;
+    padding: 10px 0px !important;
+  }
+  .u-collapse-item__content {
+    overflow: auto;
+  }
+  .u-collapse-item__content__text {
+    padding: 0;
+  }
+  .u-cell__left-icon-wrap {
+    margin: 0;
+  }
 }
-
 .content-area {
   &-title {
     text-align: right;

+ 125 - 8
src/pages/business/common/projectMange/list/index.vue

@@ -46,21 +46,38 @@
     :data-theme="'theme-' + proxy.$settingStore.themeColor.name"
   >
     <template #default>
+      <view class="projectSearchBox" >
+        <u-input v-model="projectTypeName" disabledColor="#fff" disabled clearable  @click="handleAction('项目类型',project_type)" placeholder="项目类型" suffixIcon="arrow-down" suffixIconStyle="color: #909399" />        
+        <u-input v-model="projectName" placeholder="请输入项目名称"  clearable prefixIcon="search" size="small" />
+        <!-- <u-button   type="primary" @click="selectListApi">搜索</u-button> -->
+        <u-picker
+          :show="actionShow"
+          :columns="projectTypeList"
+          title="请选择项目类型"
+          keyName="label"
+          visibleItemCount="6"
+          :closeOnClickOverlay="true"
+          @close="actionShow = false"
+          @cancel="actionShow = false"
+          @confirm="selectAction"
+        ></u-picker>
+
+      </view>      		
       <view class="menu-list m0">
         <view class="list-cell" style="color: #666666; line-height: 25px" v-for="(base, index) in dataList" :key="index">
           <view class="content-area-top menu-item">
-            <view class="content-area-top-name">{{ base.projectName }} </view>
+            <view class="content-area-top-name" style="color: #559AFF;" @click="toProjectMange(base.id)">{{ base.projectName }} </view>
             <u-icon class="content-area-top-icon" name="more-dot-fill" size="20" color="#000" @click="moreClick(base)"></u-icon>
           </view>
           <view class="content-area-row_wrap menu-item">
             <view class="content-area-row_wrap-view"> 负责人: {{ proxy.$common.mapping("nickName", "userId", base.projectHead, userDate) }} </view>
             <view class="content-area-row_wrap-view">
               状态:
-              <view class="content-area-row_wrap-view-status" v-if="base.projectStatus == 1" style="background-color: #909399"> 未开始 </view>
-              <view class="content-area-row_wrap-view-status" v-if="base.projectStatus == 2" style="background-color: #23dedc"> 进行中 </view>
-              <view class="content-area-row_wrap-view-status" v-if="base.projectStatus == 3" style="background-color: #16bf00"> 已完成 </view>
-              <view class="content-area-row_wrap-view-status" v-if="base.projectStatus == 4" style="background-color: #f9ae3d"> 已暂停 </view>
-              <view class="content-area-row_wrap-view-status" v-if="base.projectStatus == 5" style="background-color: #f56c6c"> 已作废 </view>
+              <uni-tag :text='proxy.$common.mapping("label", "value", base.projectStatus, project_status)' :type='proxy.$common.mapping("elTagType", "value", base.projectStatus, project_status)' />
+            </view>
+            <view class="content-area-row_wrap-view">
+              类型:
+              <uni-tag :text='proxy.$common.mapping("label", "value", base.projectStatus, project_type)' :type='proxy.$common.mapping("elTagType", "value", base.projectStatus, project_type)' />
             </view>
             <view class="content-area-row_wrap-view" style="display: block">
               成员:<span>{{ proxy.$common.mapping("nickName", "userId", base.projectMember, userDate) }} </span>
@@ -171,7 +188,7 @@
 <script setup>
 /*----------------------------------依赖引入-----------------------------------*/
 import { onLoad, onShow, onReady, onHide, onLaunch, onNavigationBarButtonTap, onPageScroll } from "@dcloudio/uni-app";
-import { ref, reactive, computed, getCurrentInstance, toRefs, inject } from "vue";
+import { ref, reactive, computed, getCurrentInstance, toRefs, inject,watchEffect} from "vue";
 /*----------------------------------接口引入-----------------------------------*/
 import { projectApi } from "@/api/business/project.js";
 import { dUserList } from "@/api/system/user.js";
@@ -181,7 +198,10 @@ import { useStores } from "@/store/modules/index";
 /*----------------------------------公共方法引入-----------------------------------*/
 /*----------------------------------公共变量-----------------------------------*/
 const { proxy } = getCurrentInstance();
+
 const useStore = useStores();
+const { project_type,project_status } = proxy.useDict("project_type","project_status");
+
 /*----------------------------------变量声明-----------------------------------*/
 const state = reactive({
   loading: false,
@@ -207,9 +227,35 @@ const state = reactive({
     content: "", //提示信息
   },
   eventList: {}, //数据存储
+  projectName:'',
+  projectTypeName: "", //项目类型名称
+  actionShow: false,
+  projectType: "", //项目类型
+  projectTypeList:[[]],    
 });
 
-const { tabsList, tabsCurrent, dataList, pageSize, current, total, userDate, popup, modal, eventList } = toRefs(state);
+const { tabsList, tabsCurrent, dataList, pageSize, current, total, userDate, popup, modal, eventList,array,index,projectTypeName,actionShow,projectType,projectTypeList,projectName} = toRefs(state);
+
+
+/**
+ * @action弹出框点击事件
+ */
+ function handleAction(value,event, index, ind) {
+  if (value == "项目类型") {
+    state.projectTypeList[0] = event
+  }
+
+  state.actionShow = true;
+}
+
+/**
+ * @action弹出框选择事件
+ */
+ function selectAction(e) {
+   state.projectType = e.value[0].value;
+   state.projectTypeName = e.value[0].label;
+   state.actionShow = false;
+}
 
 /**
  * @页面初始化
@@ -292,6 +338,8 @@ function selectListApi() {
       projectAscription: state.tabsList[state.tabsCurrent].value,
       pageNum: state.current,
       pageSize: state.pageSize,
+      projectType: state.projectType,
+      projectName: state.projectName,
     })
     .then((requset) => {
       state.dataList = requset.data.records;
@@ -324,8 +372,18 @@ function refresh() {
  */
 function tabsClick(e) {
   state.tabsCurrent = e.index;
+  state.projectName='';
+  state.projectType='';
+  state.projectTypeName=''
   init();
 }
+/**
+ * 跳转项目概览
+ * @param id 项目id
+ */
+function toProjectMange(id) {
+  proxy.$tab.navigateTo(`/pages/business/common/projectMange/overview/index?id=${id}`);
+}
 
 onReady(() => {});
 
@@ -335,6 +393,10 @@ onShow(() => {
   proxy.$settingStore.systemThemeColor([1]);
 });
 
+watchEffect(() => {
+  selectListApi();
+});
+
 onLoad((options) => {});
 </script>
 <style lang="scss" scoped>
@@ -344,6 +406,55 @@ onLoad((options) => {});
 }
 </style>
 <style lang="scss" scoped>
+.projectSearchBox {
+  margin:20px 4% ;width:92%;vertical-align:middle;
+  position:relative;
+  display:flex;
+  :deep(.u-input--radius, .u-input--square){
+      border-radius:0
+    }
+  
+  .u-input{
+   display:inline-block;background:#fff;height:34px;line-height:34px;padding:0 5px;
+    .uni-input-input{
+      font-size:12px!important;
+    }
+    :deep(.u-input__content__prefix-icon){
+      position:absolute;
+      right:8px;
+       .uicon-search{
+        font-size:16px
+      }
+    }
+  }
+  .u-input:first-child{
+    flex:2;
+    border-top-left-radius: 20px;
+    border-bottom-left-radius: 20px;
+    border-right:none;
+  }
+  .u-input:nth-child(2){
+    flex:4;
+    // width:70%;
+    border-top-right-radius: 20px;
+    border-bottom-right-radius: 20px;
+    // border-left:none
+  }
+  .u-popup{
+    flex:0;
+  }
+  .u-button{
+    width:50px;
+    position:absolute;
+    right:0px;
+    top:0;
+    height:32px;
+    line-height:32px;
+   
+
+  }
+  
+}
 .list-container {
   .content-area {
     &-top {
@@ -408,4 +519,10 @@ onLoad((options) => {});
     }
   }
 }
+:deep(.uni-tag){
+  padding:0px 2px;
+  height:20px;
+  line-height: 20px !important;
+  border-radius: 10px;
+}
 </style>

+ 12 - 2
src/pages/business/common/projectMange/mall/index.vue

@@ -1,6 +1,6 @@
 <template>
   <u-sticky class="shadow-default" bgColor="#fff" style="top: 0">
-    <u-navbar :titleStyle="{ color: '#000' }" :autoBack="true" title="选择人员" :placeholder="true" :safeAreaInsetTop="true" bgColor="#fff">
+    <u-navbar :titleStyle="{ color: '#000' }" :autoBack="true" :title="pageTitle" :placeholder="true" :safeAreaInsetTop="true" bgColor="#fff">
       <template #left>
         <view class="u-navbar__content__left__item">
           <u-icon name="arrow-left" size="20" color="#000"></u-icon>
@@ -64,8 +64,9 @@ const state = reactive({
   userList: [],
   activeUserList: [],
   activeUserNumber: undefined,
+  pageTitle: "",
 });
-const { defaultHeadList, userList, activeUserList, activeUserNumber } = toRefs(state);
+const { defaultHeadList, userList, activeUserList, activeUserNumber,pageTitle } = toRefs(state);
 
 function init() {
   deptUserTreeSelect({ pageNum: "1", pageSize: "10000" }).then((res) => {
@@ -90,6 +91,15 @@ onLoad((options) => {
     state.activeUserNumber = parseInt(options.number);
   }
   init();
+
+  if (options.type==1) {
+    state.pageTitle = "选择项目负责人";
+  } else if (options.type==2) {
+    state.pageTitle = "选择项目成员";
+  }else{
+    state.pageTitle = "选择抄送人"
+  }
+
 });
 
 onUnload(() => {});

+ 120 - 0
src/pages/business/common/projectMange/overview/components/echarts.vue

@@ -0,0 +1,120 @@
+<template>
+  <view style="height: 350upx;width:100%;">
+    <l-echart ref="detailedChart"></l-echart>
+  </view>
+</template>
+
+<script setup>
+import * as echarts from "echarts";
+import { onLoad, onShow, onHide, onLaunch, onResize } from "@dcloudio/uni-app";
+import { defineComponent, ref, onMounted, nextTick,watch } from "vue";
+
+const props = defineProps({
+  xAxisDataList: {
+    type: Object,
+    default: null,
+  },
+  seriesDataList: {
+    type: Object,
+    default: null,
+  },
+});
+
+let myChart;
+const detailedChart = ref(null);
+
+let option = {
+  tooltip: {
+    trigger: "axis",
+  },
+  legend: {
+    show: false,
+    // data: ["邮件营销"],
+  },
+  grid: {
+    top: "15%",
+    left: "3%",
+    right: "8%",
+    bottom: "3%",
+    containLabel: true,
+  },
+  xAxis: {
+    type: "category",
+    boundaryGap: true,
+    axisLabel: {
+      color: "rgba(0,0,0,0.4)",
+      fontSize:props.xAxisDataList.length>10?8:10, //标签字体大小
+      rotate: -30,  //文字过多时,倾斜角度
+    },
+    axisLine: {
+      show: true,
+      lineStyle: {
+        color: "rgba(0,0,0,0.4)",
+      },
+    },
+    axisTick: {
+      show: false,
+    },
+    data: props.xAxisDataList,
+  },
+  yAxis: {
+    type: "value",
+    name: '工时(小时)',
+    color: "rgba(0,0,0,0.4)",
+    axisLabel: {
+      color: "rgba(0,0,0,0.4)",
+    },
+    axisLine: {
+      show: true,
+      lineStyle: {
+        color: "rgba(0,0,0,0.4)",
+      },
+    },
+    splitLine: {
+      lineStyle: {
+        color: "rgba(0,0,0,0.1)",
+      },
+    },
+  },
+  series: [
+    {
+      name: "工时",
+      type: "bar",
+      stack: "总量",
+      smooth: true,
+      itemStyle: {
+        color: "rgba(73, 185, 245, 1)",
+      },
+      areaStyle: {
+        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+          {
+            offset: 0,
+            color: "rgba(73, 185, 245, 1)",
+          },
+          {
+            offset: 1,
+            color: "rgba(73, 185, 245, 0.4)",
+          },
+        ]),
+      },
+      data: props.seriesDataList,
+    },
+  ],
+};
+function initEcharts() {
+  myChart = detailedChart.value;
+  myChart.init(echarts, (myChart) => {
+    myChart.setOption(option);
+  });
+}
+
+onLoad(() => {
+  nextTick(() => {
+    initEcharts();
+  });
+});
+
+onResize(() => {
+  myChart.resize();
+});
+</script>

+ 261 - 0
src/pages/business/common/projectMange/overview/index.vue

@@ -0,0 +1,261 @@
+<template>
+  <u-sticky class="shadow-default projectOverview" bgColor="#fff" style="top: 0">
+    <u-navbar :titleStyle="{ color: '#000' }" :autoBack="true" title="项目概览" :placeholder="true" :safeAreaInsetTop="true" bgColor="#fff">
+      <template #left>
+        <view class="u-navbar__content__left__item">
+          <u-icon name="arrow-left" size="20" color="#000"></u-icon>
+        </view>
+      </template>
+    </u-navbar>
+  </u-sticky>
+  
+  <oa-scroll
+    customClass="invoicing-container scroll-height"
+    :customStyle="{}"
+    :isSticky="true"
+    :refresherLoad="false"
+    :refresherEnabled="false"
+    :refresherDefaultStyle="'none'"
+    :refresherThreshold="44"
+    :refresherBackground="'#f5f6f7'"
+    :scrollIntoView="scrollIntoView"
+    :data-theme="'theme-' + proxy.$settingStore.themeColor.name"
+    style="height: calc(100% - 44px);"
+  >
+  <view class="projectName">{{ project.projectName }}</view>
+    <view>
+      <view class="menu-list" style="font-size: 15px; line-height: 30px;padding:0;">
+        <view class="list-cell" style="color: #666666;padding:10px;">
+          <view class="menu-item">
+            <span style="color:#559AFF;font-weight:bold;font-size: 15px;">丨 项目概况</span>
+          </view>
+          <view class="tableType4" style="margin-top:10px;">
+            <u-row v-for="(item, index) in overviewData" :key="index">
+              <u-col span="4">
+                <view style="text-align: left; padding: 0px 5px 0px 5px" >{{ item.label }}</view>
+              </u-col>
+              <u-col span="8">
+                <view style="text-align: left; padding: 0px 5px 0px 5px;overflow-x:scroll !important;width:100%;white-space:none !important;" v-if="!item.color">{{ item.value ? item.value : '无' }}</view>
+                <view style="text-align: left; padding: 0px 5px 0px 5px;overflow-x:scroll !important;width:100%;white-space:none !important;" v-if="item.color"><uni-tag :text="item.value" :type="item.color" /></view>
+              </u-col>
+            </u-row>
+          </view>
+        </view>
+      </view>
+      <view class="menu-list" style="font-size: 15px; line-height: 30px;padding:0;">
+        <view class="list-cell" style="color: #666666;padding:10px;">
+          <view class="menu-item">
+            <span style="color:#559AFF;font-weight:bold;">丨 项目背景</span>
+          </view>
+          <view class="menu-item">
+            <span>{{ project.projectDescribe ? project.projectDescribe : "无" }}</span>
+          </view>
+        </view>
+      </view>
+      <view class="menu-list" style="font-size: 15px; line-height: 30px;padding:0;">
+        <view class="list-cell" style="color: #666666;padding:10px;">
+          <view class="menu-item">
+            <span style="color:#559AFF;font-weight:bold;">丨 项目参与人员</span>
+          </view>
+          <view class="menu-item">
+            <view class="example-body" style="width:100%">
+              <uni-datetime-picker v-model="range" type="daterange" @change="changeTime"  style="margin:10px 0;"/>
+              <lineEcharts :xAxisDataList="xAxisDataList" :seriesDataList="seriesDataList" style="width:100%;margin-top:10px;" v-if="xAxisDataList.length>0"></lineEcharts>
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+  </oa-scroll>
+</template>
+
+<script setup>
+/*----------------------------------依赖引入-----------------------------------*/
+import { onLoad, onShow, onReady, onHide, onLaunch, onNavigationBarButtonTap, onPageScroll } from "@dcloudio/uni-app";
+import { ref, reactive, computed, getCurrentInstance, toRefs, inject } from "vue";
+/*----------------------------------接口引入-----------------------------------*/
+import { crmInvoiceInfo, page } from "@/api/common/invoicing.js";
+import { projectApi } from "@/api/business/project.js";
+import { dUserList } from "@/api/system/user.js";
+import dayjs from 'dayjs/esm/index'
+/*----------------------------------组件引入-----------------------------------*/
+import lineEcharts from "./components/echarts.vue";
+/*----------------------------------store引入-----------------------------------*/
+/*----------------------------------公共方法引入-----------------------------------*/
+/*----------------------------------公共变量-----------------------------------*/
+const { proxy } = getCurrentInstance();
+const { project_type,project_status } = proxy.useDict("project_type","project_status");
+/*----------------------------------变量声明-----------------------------------*/
+const uForm = ref(null);
+const range = ref([dayjs().subtract(30, "day").format("YYYY-MM-DD"),dayjs().subtract(0, "day").format("YYYY-MM-DD")])
+const state = reactive({
+  projectId: "",//项目id
+  project:{},//项目信息
+  userDate:[],//人员列表
+  form: {
+    customId: "", //客户管理id
+    invoiceTitle: "", //发票抬头
+    dutyId: "", //税号
+    email: "", //电子邮箱
+    applicant: "", //申请人
+    phone: "", //手机号码
+    amount: "", //金额
+    invoiceType: "1", //发票类型;1:普票,2:专票
+    invoiceAttribute: "1", //发票性质;1:电子发票,2:纸质发票
+    sendAddress: "", //邮寄地址
+    paymentReceipt: "", //付款回执
+  },
+  overviewData:[
+    { label:"负责人", value:"",color:"" },
+    { label:"状态", value:"",color:"" },
+    { label:"类型", value:"",color:"" },
+    { label:"计划人天", value:"",color:"" },
+    { label:"成员", value:"",color:"" },
+    { label:"时间", value:"",color:"" },
+  ],
+  xAxisDataList:[],
+  seriesDataList:[],
+  scrollIntoView: "",
+  promptStatus: false,
+});
+
+const { scrollIntoView, promptStatus,project,userDate,overviewData,projectId,xAxisDataList,seriesDataList } = toRefs(state);
+
+/**
+ * @提交
+ */
+function handleSubmit(value) {
+  scrollIntoView.value = "";
+  uForm.value
+    .validate()
+    .then((res) => {
+      uni.$u.toast("校验通过");
+      proxy.$modal.loading("加载中");
+      page({
+        current: 1,
+        size: 10,
+        invoiceTitle: form.value.invoiceTitle,
+        startTime: proxy.$time.getYearLast(new Date()),
+        endTime: proxy.$time.getFormatterDate(new Date()),
+      }).then((requset) => {
+        if (requset.status === "SUCCESS") {
+          proxy.$modal.closeLoading();
+
+          if (requset.data.records.length > 0) {
+            promptStatus.value = true;
+            scrollIntoView.value = "noticeBar";
+          } else {
+            var param = {
+              customId: parseInt(form.value.customId), //客户管理id
+              invoiceTitle: form.value.invoiceTitle, //发票抬头
+              dutyId: form.value.dutyId, //税号
+              email: form.value.email, //电子邮箱
+              applicant: form.value.applicant, //申请人
+              phone: form.value.phone, //手机号码
+              amount: parseFloat(form.value.amount), //金额
+              invoiceType: parseInt(form.value.invoiceType), //发票类型;1:普票,2:专票
+              invoiceAttribute: parseInt(form.value.invoiceAttribute), //发票性质;1:电子发票,2:纸质发票
+              sendAddress: form.value.sendAddress, //邮寄地址
+              paymentReceipt: form.value.paymentReceipt, //付款回执
+            };
+            crmInvoiceInfo(param).then((requset) => {
+              if (requset.status === "SUCCESS") {
+                proxy.$tab.navigateTo("/pages/common/success/index?codeName=提交成功");
+              }
+            });
+          }
+        }
+      });
+    })
+    .catch((errors) => {
+      uni.$u.toast("校验失败");
+    });
+}
+function changeTime(e){
+  xAxisDataList.value=[]
+  getEchartsData()
+}
+
+/**
+ * @api接口查询
+ */
+function selectListApi(id) {
+  dUserList().then((res) => {
+    state.userDate = res.data;
+    projectApi()
+      .ProjectsList({
+        projectId: id,
+      })
+      .then((requset) => {
+        project.value = requset.data.records[0];
+        overviewData.value[0].value = proxy.$common.mapping("nickName", "userId", project.value.projectHead, userDate.value)
+        overviewData.value[1].value = proxy.$common.mapping("label", "value", project.value.projectStatus, project_status.value)
+        overviewData.value[1].color = proxy.$common.mapping("elTagType", "value", project.value.projectStatus, project_status.value)
+        overviewData.value[2].value = proxy.$common.mapping("label", "value", project.value.projectType, project_type.value)
+        overviewData.value[3].value = project.value.projectWorkload
+        overviewData.value[4].value = proxy.$common.mapping("nickName", "userId", project.value.projectMember, userDate.value)
+        overviewData.value[5].value = project.value.startTime || project.value.endTime ? 
+        (project.value.startTime ? project.value.startTime.slice(0, 10) : "") + 
+        " 至 " + (project.value.endTime ? project.value.endTime.slice(0, 10) : '') : ""
+      })
+    });
+
+}
+function getEchartsData(){
+  projectApi()
+  .usersProjectWorkTime(
+    {
+      projectId:projectId.value,
+      startDate:range.value[0],
+      endDate:range.value[1]
+    }
+  ).then((res) => {
+    xAxisDataList.value = res.data.users
+    seriesDataList.value = res.data.workTime
+  })
+}
+
+
+onLoad((options) => {
+  if(options.id){
+    projectId.value= options.id
+    selectListApi(options.id)
+    getEchartsData()
+  }
+});
+
+onReady(() => {});
+
+onShow((options) => {
+  //调用系统主题颜色
+  proxy.$settingStore.systemThemeColor([1]);
+});
+
+// 自定义导航事件
+onNavigationBarButtonTap((e) => {
+  if (e.float == "right") {
+  }
+});
+</script>
+
+<style lang="scss" scoped>
+:deep(.uni-page-head__title) {
+  opacity: 1 !important;
+}
+.projectName{
+  text-align: center;
+  font-size: 15px;
+  font-weight: bold;
+  margin:10px 0 0 ;
+}
+</style>
+<style>
+/* 时间样式 */
+  :deep(.uni-date-editor--x){
+    border-radius: 20px !important;
+    width:100% !important;
+  }
+  :deep(.uni-date-x){
+    background-color: transparent !important;
+  }
+</style>

+ 31 - 18
src/pages/business/common/projectMange/record/details.vue

@@ -1,5 +1,5 @@
 <template>
-  <u-navbar :titleStyle="{ color: '#000' }" :autoBack="true" :title="state.options.createBy + '的日报'" :placeholder="true" :safeAreaInsetTop="true" bgColor="#fff">
+  <u-navbar :titleStyle="{ color: '#000' }" :autoBack="true" :title="dataList[0]?.createBy + '的日报'" :placeholder="true" :safeAreaInsetTop="true" bgColor="#fff">
     <template #left>
       <view class="u-navbar__content__left__item">
         <u-icon name="arrow-left" size="20" color="#000"></u-icon>
@@ -26,7 +26,7 @@
     :data-theme="'theme-' + proxy.$settingStore.themeColor.name"
   >
     <template #default>
-      <view class="content-area radius bg-white" v-for="(item, ind) in state.dataList" :key="ind">
+      <view class="content-area radius bg-white" v-for="(item,index) in dataList" :key="index">
         <view class="content-area-header flex mb10">
           <u-avatar
             class="content-area-header-avatar mr10"
@@ -45,7 +45,7 @@
 
         <view class="content-area-center mb10" v-for="child in item.workContents" :key="child">
           <view class="content-area-center-top flex">
-            <view class="content-area-center-top-title mr10">{{ child.projectName ? child.projectName : " " }}</view>
+            <view class="content-area-center-top-title mr10" style="color: #559AFF;" @click="toProjectMange(child.projectId)">{{ child.projectName ? child.projectName : " " }}</view>
             <view class="content-area-center-top-time" :style="{ color: proxy.$settingStore.themeColor.color }">{{ child.workTime }}h</view>
           </view>
           <u-text :text="child.workContent" color="#000000" size="14"></u-text>
@@ -60,10 +60,14 @@
         </view>
         <view class="content-area-center mb10">
           <view class="content-area-center-top">抄送人 </view>
-          <u-text :text="item.ccTo" color="#000000" size="14"></u-text>
+          <u-text :text='item.ccTo ? proxy.$common.mapping("nickName", "userId", item.ccTo, userData) : "无"' color="#000000" size="14"></u-text>
         </view>
+
+
       </view>
     </template>
+
+    
   </oa-scroll>
 </template>
 
@@ -73,6 +77,7 @@ import { onLoad, onShow, onReady, onHide, onLaunch, onBackPress, onUnload, onNav
 import { ref, reactive, computed, getCurrentInstance, toRefs, inject } from "vue";
 /*----------------------------------接口引入-----------------------------------*/
 import { projectApi } from "@/api/business/project.js";
+import { dUserList } from "@/api/system/user.js";
 /*----------------------------------组件引入-----------------------------------*/
 /*----------------------------------store引入-----------------------------------*/
 /*----------------------------------公共方法引入-----------------------------------*/
@@ -81,39 +86,47 @@ const { proxy } = getCurrentInstance();
 /*----------------------------------变量声明-----------------------------------*/
 const state = reactive({
   loading: true,
-  dataList: [],
-  pageSize: 10,
-  current: 1,
-  total: 0,
-
-  options: {
+  dataList: [],//日报列表
+  options: {//日报详情参数
     reportId: "",
-    createBy: "",
   },
+  userData:[],//用户列表
 });
 
-const { dataList, pageSize, current, total } = toRefs(state);
+const { dataList, userData} = toRefs(state);
+
 
 /**
  * @初始化
  */
 function init() {
-  state.dataList = [];
+  dataList.value = [];
   state.loading = true;
-  projectApi()
-    .ReportRecordDetails({
+  dUserList().then(res=>{
+    userData.value = res.data;
+    projectApi()
+    .ReportRecord({
       reportId: state.options.reportId,
+      pageNum: 1,
+      pageSize: 1,
     })
     .then((requset) => {
-      state.options.createBy = requset.data[0].createBy;
-      state.dataList = requset.data;
+      dataList.value = requset.data.records;
       state.loading = false;
     })
     .catch((err) => {
       state.loading = false;
     });
-}
+  })
 
+}
+/**
+ * 跳转项目概览
+ * @param id 项目id
+ */
+function toProjectMange(id) {
+  proxy.$tab.navigateTo(`/pages/business/common/projectMange/overview/index?id=${id}`);
+}
 onReady(() => {});
 
 onShow(() => {

+ 188 - 9
src/pages/business/common/projectMange/record/index.vue

@@ -42,14 +42,26 @@
     :data-theme="'theme-' + proxy.$settingStore.themeColor.name"
   >
     <template #default>
+
+      <view v-if="timedList.length>0" class="list-cell list-cell-arrow"  style="margin:20px 0;color:rgb(20, 158, 255);background-color: rgba(20, 158, 255,.1)"  >
+          <view style="width: calc(100% - 51px); display: flex; ; padding-right: 10px">
+            <u-icon name="info-circle" color="#2979ff" size="18" style="margin-right: 5px"></u-icon>
+            <view v-if="timedList.length==1" @click="goTimingPage()">您有1条定时日志将于{{timedList[0].timingTime.slice(0,16)}}发布</view>
+
+            <view v-else  @click="goTimingPage()">您有{{timedList.length}}条定时日志将于指定时间发布</view>
+          </view>
+      </view>
+
+
       <u-loading-page :loading="state.loading" fontSize="16" style="z-index: 99"></u-loading-page>
       <view class="content-area" v-for="(group, date) in proxy.$common.groupedItems(state.dataList, 'submitDate')" :key="date">
         <view class="content-area-time font14">{{ proxy.$time.jktTimes(date, "否") }}</view>
         <view class="content-area-center bg-white" v-for="(el, ind) in group" :key="ind">
           <view class="content-area-top menu-item" style="float:right;padding:10px 0px">
             <view class="content-area-top-time"> </view>
+            <u-icon class="content-area-top-icon" name="more-dot-fill" size="20" color="#000" @click="moreClick(el)"></u-icon>
             <!-- <u-icon class="content-area-top-icon" name="edit-pen" size="20" color="rgb(20, 158, 255)" @click="handleSubmit('update',el)" v-if="state.tabsCurrent ==1" style="display:inline-block;margin-right:30px;"></u-icon> -->
-            <u-icon class="content-area-top-icon" name="trash" size="20" color="red" @click="tips('error',`确认删除时间为 '${el.submitDate}' 的日报吗?`,el,'delete')" v-if="state.tabsCurrent ==1" style="display:inline-block;"></u-icon>
+            <!-- <u-icon class="content-area-top-icon" name="trash" size="20" color="red" @click="tips('error',`确认删除时间为 '${el.submitDate}' 的日报吗?`,el,'delete')" v-if="state.tabsCurrent ==1" style="display:inline-block;"></u-icon> -->
           </view>
           <view class="flex mb10" @click="goContentDetails(el)">
             <u-avatar
@@ -80,10 +92,96 @@
   </oa-scroll>
 
   <oa-tabbar :tabbarValue="0" :tabbarList="proxy.$constData.projectTabbar" :isSwitchTab="false"></oa-tabbar>
+
+  <u-popup :show="popup.show" mode="bottom" bgColor="#fff" :round="10" @close="popup.show = false">
+    <view
+      :style="{
+        borderTopLeftRadius: '10px',
+        borderTopRightRadius: '10px',
+        overflow: 'hidden',
+      }"
+    >
+     
+      <u-button
+        v-if="state.tabsCurrent ==1"
+        class="custom-style"
+        type="info"
+        size="normal"
+        text="编辑"
+        :customStyle="{
+          height: '50px',
+          color: '#3c9cff',
+          borderWidth: 0,
+          borderRadius: 0,
+          borderBottomWidth: '1px',
+        }"
+        @click="handleSubmit('update', eventList)"
+      ></u-button>
+      <u-button
+        class="custom-style"
+        type="info"
+        size="normal"
+        text="一键复制"
+        :customStyle="{
+          height: '50px',
+          color: '#3c9cff',
+          borderWidth: 0,
+          borderRadius: 0,
+          borderBottomWidth: '1px',
+        }"
+        @click="handleSubmit('copy', eventList)"
+      ></u-button>
+      <u-button
+        v-if="state.tabsCurrent ==1"
+        class="custom-style"
+        type="info"
+        size="normal"
+        text="删除"
+        :customStyle="{
+          height: '50px',
+          color: '#f56c6c',
+          borderWidth: 0,
+          borderRadius: 0,
+          borderBottomWidth: '3px',
+        }"
+        @click="handleModal('delete', `确认删除“ ${eventList.createBy} ” 的“ ${eventList.reportDate} ” 的日报?`)"
+      ></u-button>
+      <u-button
+        class="custom-style"
+        type="info"
+        size="normal"
+        text="取消"
+        :customStyle="{
+          height: '50px',
+          color: '#3c9cff',
+          border: 'none',
+          borderRadius: 0,
+        }"
+        @click="popup.show = false"
+      ></u-button>
+    </view>
+  </u-popup>
+
+  
+
+
+
   <uni-popup ref="alertDialog" type="dialog">
     <uni-popup-dialog :type="state.tip.type" cancelText="取消" confirmText="确定" title="操作提醒" :content="state.tip.content" @confirm="dialogConfirm"
       @close="dialogClose"></uni-popup-dialog>
   </uni-popup>
+
+  <u-modal
+    :show="modal.show"
+    title="操作提醒"
+    :content="modal.content"
+    :showCancelButton="true"
+    :closeOnClickOverlay="true"
+    @confirm="handleSubmit(state.modal.type, eventList)"
+    @cancel="modal.show = false"
+    @close="modal.show = false"
+  ></u-modal>
+
 </template>
 
 <script setup>
@@ -116,16 +214,31 @@ const state = reactive({
   modalShow: false,
   modalType: "",
   modalEvent: {},
+
+  popup: {
+    show: false, //弹窗显示
+    content: "", //提示信息
+  },
+  modal: {
+    type: "", //操作类型
+    show: false, //弹窗显示
+    content: "", //提示信息
+  },
+  eventList: {}, //数据存储
+
+
   reportData:{},
   tip:{
     type:undefined,//弹框类型
     content:"",//提示信息
     data:{},//带入数据
     operation:undefined,//操作类型
-  }
+  },
+  timedList:[],
+  tree:[]
 });
 
-const { tabsList, tabsCurrent, dataList, pageSize, current, total} = toRefs(state);
+const { tabsList, tabsCurrent, dataList, pageSize, current, total,popup,eventList,modal,timedList,tree} = toRefs(state);
 /**
  * 操作弹框提醒
  * @param type  弹框类型
@@ -148,6 +261,9 @@ function dialogConfirm(){
   if(state.tip.operation=='exit'){
     handleSubmit('exit',state.tip.data)
   }
+  if(state.tip.operation=='copy'){
+    handleSubmit('copy',state.tip.data)
+  }
 }
 /**
  * @初始化
@@ -171,11 +287,22 @@ function init() {
       state.dataList = requset.data.records;
       state.total = requset.data.total;
       state.loading = false;
+
+      console.log(state.dataList )
     })
     .catch((err) => {
       state.loading = false;
     });
-}
+    projectApi()
+    .TimedReports({
+     }).then((requset) => {
+      state.timedList = requset.data;
+     })
+    .catch((err) => {
+
+    })
+
+  }
 
 /**
  * @跳转详情
@@ -207,23 +334,74 @@ function tabsClick(e) {
   state.tabsCurrent = e.index;
   init();
 }
+
+
+// 定时日志页面
+function goTimingPage(){
+  proxy.$tab.navigateTo(`/pages/business/common/projectMange/record/timingLog`);
+
+  // proxy.$tab.navigateTo(`/pages/business/common/projectMange/report/timingLog`);
+}
 /** 更多按钮点击事件 */
-function moreClick(type, event) {
-  state.modalShow = true;
-  state.modalType = type;
-  state.modalEvent = event;
-  state.reportData = event;
+function moreClick(event) {
+  state.popup.show = true;
+  state.eventList = event;
+}
 
+
+function handleModal(type, content) {
+  state.modal.show = true;
+  state.modal.type = type;
+  state.modal.content = content;
 }
+
 /** 编辑、删除日报*/
 function handleSubmit(type,item) {
   if (type === "update") {
     proxy.$tab.navigateTo(`/pages/business/common/projectMange/write/insert?templateId=1&id=${item.id}`);
+    state.modal.show = false;
+  }else if (type === "copy") {
+    var workLongString=''
+    item.workContents.forEach((item) => {
+      workLongString+=item.projectName+':'+item.workTime+ "h\n"+item.workContent+ "\n"
+    })
+    item.ccTo1 = item.ccTo.split(",").map(function (value, index) {
+      return Number(value);
+    });
+
+     /** 查询树结构用户列表  回显抄送人*/
+
+     item.tomorrowPlan=item.tomorrowPlan?item.tomorrowPlan:'-';
+     item.coordinateWork=item.coordinateWork?item.coordinateWork:'-'
+    // 触发方法
+      proxy.$common.uniCopy({
+      content: workLongString+ "\n" +
+              "明日计划:\n" + item.tomorrowPlan + "\n" +
+              "工作协调:\n" + item.coordinateWork,
+      success: (res) => {
+        uni.showToast({
+          title: res,
+          icon: "none",
+        });
+      },
+      error: (e) => {
+        uni.showToast({
+          title: e,
+          icon: "none",
+          duration: 3000,
+        });
+      },
+    });
+    state.popup.show = false;
+    
+
   } else if (type === "delete") {
     projectApi()
       .ReportDelete(item.id)
       .then(() => {
         proxy.$modal.msg("日报删除成功!");
+        state.modal.show = false;
+        state.popup.show = false;
         init();
       })
       .catch((errors) => {
@@ -236,6 +414,7 @@ function handleSubmit(type,item) {
 onReady(() => {});
 
 onShow(() => {
+  state.popup.show = false;
   //调用系统主题颜色
   proxy.$settingStore.systemThemeColor([1]);
 });

+ 346 - 0
src/pages/business/common/projectMange/record/timingLog.vue

@@ -0,0 +1,346 @@
+<template>
+  <u-sticky class="shadow-default" bgColor="#fff" style="top: 0">
+    <u-navbar :titleStyle="{ color: '#000' }" :autoBack="true" title="定时日志" :placeholder="true" :safeAreaInsetTop="true" bgColor="#fff">
+     
+    </u-navbar>
+   
+  </u-sticky>
+
+  <oa-scroll
+    customClass="record-container scroll-height"
+    :pageSize="pageSize"
+    :total="total"
+    :isSticky="true"
+    :customStyle="{
+      //#ifdef APP-PLUS || MP-WEIXIN
+      height: 'calc(100vh - 40px)',
+      //#endif
+      //#ifdef H5
+      height: 'calc(100vh - 40px)',
+      //#endif
+    }"
+    :refresherLoad="true"
+    :refresherEnabled="true"
+    :refresherDefaultStyle="'none'"
+    :refresherThreshold="44"
+    :lowerThreshold="44"
+    :refresherBackground="'#f5f6f7'"
+    @load="load"
+    @refresh="refresh"
+    :data-theme="'theme-' + proxy.$settingStore.themeColor.name"
+  >
+    <template #default>
+
+      <u-loading-page :loading="state.loading" fontSize="16" style="z-index: 99"></u-loading-page>
+      <view class="content-area" v-for="(group, date) in proxy.$common.groupedItems(state.timedList, 'submitDate')" :key="date">
+        <view class="content-area-time font14">{{ proxy.$time.jktTimes(date, "否") }}</view>
+        <view class="content-area-center bg-white" v-for="(el, ind) in group" :key="ind">
+          <view class="content-area-top menu-item" style="float:right;padding:10px 0px">
+            <view class="content-area-top-time"> </view>
+            <u-icon  class="content-area-top-icon" name="more-dot-fill" size="20" color="#000" @click="moreClick(el)"></u-icon>
+          </view>
+          <view class="flex mb10" @click="goContentDetails(el)">
+            <u-avatar
+              class="content-area-center-avatar mr10"
+              :text="el.createBy.length > 2 ? el.createBy.slice(1, 3) : el.createBy"
+              shape="square"
+              size="35"
+              fontSize="10"
+              color="#ffffff"
+              :bgColor="proxy.$settingStore.themeColor.color"
+            ></u-avatar>
+            <view>
+              <view class="content-area-center-title font14 mb5">{{ el.createBy }}的日报</view>
+              <view class="content-area-center-time font12">{{ proxy.$time.jktTimes(el.submitDate.replace("T", " ")) }}</view>
+            </view>
+          </view>
+          <view class="mb5" @click="goContentDetails(el)">
+            <u-text :text="el.contentText.length >= 100 ? el.contentText.slice(0, 100) + '···' : el.contentText" color="#666666" size="14"></u-text>
+          </view>
+          <view style="font-size:12px;lcolor:#a7a4a4">
+            <u-button size="mini" style="width:50px;float:left;margin-right:5px;line-height:18px;height:18px">定时日志</u-button>
+            将于 2021-10-10 19:20 发布
+          </view>
+        
+        </view>
+      </view>
+    </template>
+  </oa-scroll>
+
+
+  <u-popup :show="popup.show" mode="bottom" bgColor="#fff" :round="10" @close="popup.show = false">
+    <view
+      :style="{
+        borderTopLeftRadius: '10px',
+        borderTopRightRadius: '10px',
+        overflow: 'hidden',
+      }"
+    >
+     
+      <u-button
+        class="custom-style"
+        type="info"
+        size="normal"
+        text="编辑"
+        :customStyle="{
+          height: '50px',
+          color: '#3c9cff',
+          borderWidth: 0,
+          borderRadius: 0,
+          borderBottomWidth: '1px',
+        }"
+        @click="handleSubmit('update', eventList)"
+      ></u-button>
+      <u-button
+        class="custom-style"
+        type="info"
+        size="normal"
+        text="删除"
+        :customStyle="{
+          height: '50px',
+          color: '#f56c6c',
+          borderWidth: 0,
+          borderRadius: 0,
+          borderBottomWidth: '3px',
+        }"
+        @click="handleModal('delete', `确认删除“ ${eventList.createBy} ” 的“ ${eventList.reportDate} ” 的日报?`)"
+      ></u-button>
+      <u-button
+        class="custom-style"
+        type="info"
+        size="normal"
+        text="取消"
+        :customStyle="{
+          height: '50px',
+          color: '#3c9cff',
+          border: 'none',
+          borderRadius: 0,
+        }"
+        @click="popup.show = false"
+      ></u-button>
+    </view>
+  </u-popup>
+
+  
+
+
+
+  <uni-popup ref="alertDialog" type="dialog">
+    <uni-popup-dialog :type="state.tip.type" cancelText="取消" confirmText="确定" title="操作提醒" :content="state.tip.content" @confirm="dialogConfirm"
+      @close="dialogClose"></uni-popup-dialog>
+  </uni-popup>
+
+  <u-modal
+    :show="modal.show"
+    title="操作提醒"
+    :content="modal.content"
+    :showCancelButton="true"
+    :closeOnClickOverlay="true"
+    @confirm="handleSubmit(state.modal.type, eventList)"
+    @cancel="modal.show = false"
+    @close="modal.show = false"
+  ></u-modal>
+
+</template>
+
+<script setup>
+/*----------------------------------依赖引入-----------------------------------*/
+import { onLoad, onShow, onReady, onHide, onLaunch, onUnload, onNavigationBarButtonTap, onPageScroll } from "@dcloudio/uni-app";
+import { ref, reactive, computed, getCurrentInstance, toRefs, inject } from "vue";
+/*----------------------------------接口引入-----------------------------------*/
+import { projectApi } from "@/api/business/project.js";
+/*----------------------------------组件引入-----------------------------------*/
+/*----------------------------------store引入-----------------------------------*/
+import { useStores, commonStores } from "@/store/modules/index";
+/*----------------------------------公共方法引入-----------------------------------*/
+/*----------------------------------公共变量-----------------------------------*/
+const { proxy } = getCurrentInstance();
+const useStore = useStores();
+/*----------------------------------变量声明-----------------------------------*/
+const state = reactive({
+  loading: false,
+  pageSize: 20,
+  current: 1,
+  total: 0,
+
+  popup: {
+    show: false, //弹窗显示
+    content: "", //提示信息
+  },
+  modal: {
+    type: "", //操作类型
+    show: false, //弹窗显示
+    content: "", //提示信息
+  },
+  eventList: {}, //数据存储
+
+
+  tip:{
+    type:undefined,//弹框类型
+    content:"",//提示信息
+    data:{},//带入数据
+    operation:undefined,//操作类型
+  },
+  timedList:[]
+});
+
+const {pageSize, current, total,popup,eventList,modal,timedList} = toRefs(state);
+/**
+ * 操作弹框提醒
+ * @param type  弹框类型
+ * @param content 提示内容
+ * @param item 带入数据
+ * @param operation 操作类型
+ */
+ function tips(type,content,item,operation){
+  state.tip.type=type
+  state.tip.content=content
+  state.tip.data=item
+  state.tip.operation=operation
+  proxy.$refs.alertDialog.open()
+}
+/**弹框确定操作 */
+function dialogConfirm(){
+  if(state.tip.operation =='delete'){
+    handleSubmit('delete',state.tip.data)
+  }
+  if(state.tip.operation=='exit'){
+    handleSubmit('exit',state.tip.data)
+  }
+}
+/**
+ * @初始化
+ */
+function init() {
+  projectApi()
+    .TimedReports({
+     }).then((requset) => {
+      state.timedList = requset.data;
+      requset.data.forEach((el) => {
+        el.contentText = "";
+        el.workContents.forEach((cl) => {
+          el.contentText += `${cl.projectName} ${cl.workTime}h \n ${cl.workContent}`;
+        });
+      });
+      state.total = requset.data.length;
+      state.loading = false;
+     })
+    .catch((err) => {
+      state.loading = false;
+    })
+}
+
+/**
+ * @跳转详情
+ */
+function goContentDetails(e) {
+  proxy.$tab.navigateTo(`/pages/business/common/projectMange/record/details?reportId=${e.id}`);
+}
+
+/**
+ * @scrollView加载数据
+ */
+function load() {
+  init();
+}
+
+/**
+ * @scrollView刷新数据
+ */
+function refresh() {
+  init();
+}
+
+/** 更多按钮点击事件 */
+function moreClick(event) {
+  state.popup.show = true;
+  state.eventList = event;
+}
+
+/** 确认按钮点击事件 */
+function handleModal(type, content) {
+  state.modal.show = true;
+  state.modal.type = type;
+  state.modal.content = content;
+}
+
+/** 编辑、删除日报*/
+function handleSubmit(type,item) {
+  if (type === "update") {
+    proxy.$tab.navigateTo(`/pages/business/common/projectMange/write/insert?templateId=1&id=${item.id}`);
+    state.modal.show = false;
+  } else if (type === "delete") {
+    projectApi()
+      .ReportDelete(item.id)
+      .then(() => {
+        proxy.$modal.msg("日报删除成功!");
+        state.modal.show = false;
+        state.popup.show = false;
+        init();
+      })
+      .catch((errors) => {
+        proxy.$modal.msg(errors);
+      });
+  } 
+}
+
+onReady(() => {});
+
+onShow(() => {
+  state.popup.show = false;
+  //调用系统主题颜色
+  proxy.$settingStore.systemThemeColor([1]);
+});
+
+onLoad((options) => {
+  init();
+  uni.$on("projectMange_record", function (value) {
+    init();
+  });
+});
+
+onUnload(() => {
+  uni.$off("projectMange_record"); //将值删除监听器
+});
+</script>
+
+<style lang="scss" scoped>
+.content-area {
+  &-time {
+    padding: 10px;
+    text-align: left;
+    color: #000000;
+    font-weight: 600;
+  }
+
+  &-center {
+    margin: 0;
+    padding: 15px;
+    overflow: hidden;
+    border-bottom: 1px solid #eaeef1;
+
+    &:last-child {
+      border-bottom: 0px solid #eaeef1;
+    }
+
+    &-avatar {
+      margin: auto 0;
+    }
+
+    &-title {
+      margin: 0 0 15px 0;
+      font-weight: 600;
+      color: #000000;
+    }
+  }
+}
+
+.pp{
+  text-align: left;
+}
+</style>
+<style>
+.pp .u-modal__content{
+  justify-content: left !important
+}
+</style>

+ 158 - 51
src/pages/business/common/projectMange/write/components/template1.vue

@@ -1,6 +1,6 @@
 <template>
   <view class="content-area">
-    <view class="content-area-title font12 mtb5 plr10">实时保存,保存时间 {{ saveTime }}</view>
+    <view class="content-area-title font12 mtb5 plr10" v-if="!state.form.id">{{state.form.id}}实时保存,保存时间 {{ saveTime }}</view>
 
     <view class="content-area-item p10 bg-white">
       <view class="font14 weight mb10 required">工作内容</view>
@@ -65,10 +65,15 @@
         @change="realTimeSaving()"
       ></u-textarea>
     </view>
+    <!-- <view class="content-area-item mt10 p10 bg-white">
+      <view class="font14 weight mb10">图片上传</view>
+      <oa-upload :uploadCount="5" :uploadList="form.imageList" :uploadListSrc="'url'" @uploadSuccessChange="uploadSuccessChange" @uploadDeleteChange="uploadDeleteChange"></oa-upload>
+    </view> -->
+
     <view class="content-area-item mt10 p10 bg-white">
       <view class="font14 weight mb10">抄送到人</view>
       <avatarList :userList="userList" @deleteUsers="deleteUsers" />
-      <u-button class="mt20" type="primary" style="width: 100px; height: 25px" @click="insertUsers()" shape="circle" icon="plus" size="mini"> 选择人员 </u-button>
+      <u-button class="mt20" type="primary" style="width: 100px; height: 25px" @click="insertUsers()" shape="circle" icon="plus" size="mini" :disabled="form.reportStatus == 1"> 选择人员 </u-button>
     </view>
     <view class="content-area-item mt10 p10 bg-white">
       <view class="flex">
@@ -78,13 +83,14 @@
           :modelValue="form.sendDingTalk == 0 ? false : true"
           :ctiveColor="proxy.$settingStore.themeColor.color"
           size="20"
+          :disabled="form.reportStatus == 1"
           @change="(event) => switchChage(event, 'sendDingTalk')"
           asyncChange
         ></u-switch>
       </view>
       <view class="flex"> </view>
     </view>
-    <view class="content-area-item mt10 p10 bg-white">
+    <view class="content-area-item mt10 p10 bg-white" v-if="form.reportStatus != 1">
       <view class="flex">
         <view class="font14 weight">定时发送</view>
         <u-switch
@@ -124,7 +130,43 @@
 
   <u-modal :show="modalShow" title="" :confirmText="'确定'" :cancelText="'取消'" :zoom="false" :showCancelButton="true" @confirm="modalConfirm" @cancel="modalShow = false">
     <view class="slot-content" style="max-height: 80vh">
-      <u-checkbox-group v-model="projectsCheck" placement="row" :size="14" v-if="projectsList.length > 0" style="max-height: 100%; overflow: auto">
+     
+    <view v-if="projectsList.length > 0">
+    
+      <u-checkbox-group v-model="projectsCheck" placement="row" :size="14" style="max-height: 100%; overflow: auto">
+        <view class="checkbox-group-title">最近使用</view>
+        <block  v-for="(item, index) in projectsList">
+          <u-checkbox v-if="item.submissions>0"
+            :customStyle="{ marginBottom: '8px', width: '50%' }"
+            :label="item.projectName+' ('+item.submissions+'次)'"
+            :name="item.id"
+            :activeColor="proxy.$settingStore.themeColor.color"
+          >
+          </u-checkbox>
+        </block>
+				<u-line class="u-line"  color="info" style="margin:10px 0"></u-line>
+
+
+        <view  class="checkbox-group-title">其他</view>
+  
+        <block  v-for="(item, index) in projectsList">
+          <u-checkbox v-if="!item.submissions"
+            :customStyle="{ marginBottom: '8px', width: '50%' }"
+            :label="item.projectName"
+            :name="item.id"
+            :activeColor="proxy.$settingStore.themeColor.color"
+          >
+        </u-checkbox>
+       
+  
+           
+       
+        </block>
+
+       
+      </u-checkbox-group>
+ 
+      <!-- <u-checkbox-group v-else v-model="projectsCheck" placement="row" :size="14"  style="max-height: 100%; overflow: auto">
         <u-checkbox
           :customStyle="{ marginBottom: '8px', width: '50%' }"
           v-for="(item, index) in projectsList"
@@ -134,7 +176,9 @@
           :activeColor="proxy.$settingStore.themeColor.color"
         >
         </u-checkbox>
-      </u-checkbox-group>
+      </u-checkbox-group> -->
+    </view>
+      
       <view v-else>请联系项目管理人员给您分配项目后重试!</view>
     </view>
   </u-modal>
@@ -178,7 +222,8 @@ const state = reactive({
     sendDingTalk: 1,
     isRegularlySend: 0,
     timingTime: null,
-    reportStatus: null,
+    // reportStatus: null,
+    imageList: [],
   },
   projectsCheck: [],
   projectsList: [],
@@ -223,11 +268,16 @@ function switchChage(e, key) {
 function insertUsers() {
   //将人员选中数据传入store中
   systemStore.mallList.activeUserList = state.userList;
-  proxy.$tab.navigateTo(`/pages/business/common/projectMange/mall/index?number=200`);
+ 
+  proxy.$tab.navigateTo(`/pages/business/common/projectMange/mall/index?number=200&type=3`);
 }
 
 /** 删除人员按钮事件 */
 function deleteUsers(index) {
+  if (state.form.reportStatus == 1) {
+    console.log("已发送不可修改抄送人");
+    return;
+  }
   state.userList.splice(index, 1);
   realTimeSaving();
 }
@@ -235,12 +285,19 @@ function deleteUsers(index) {
 /** 添加项目按钮事件 */
 function insertProjects() {
   modal.modalShow = true;
+  projectApi()
+    .ProjectsSelect()
+    .then((requset) => {
+      state.projectsList = requset.data;
+    });
 }
 
 /** 实时保存填写数据 */
 function realTimeSaving() {
-  state.saveTime = proxy.$time.formatterDate(new Date(), "hh:mm");
-  storageSystem.set("project", state);
+  if(!state.form.id){
+    state.saveTime = proxy.$time.formatterDate(new Date(), "hh:mm");
+    storageSystem.set("project", state);
+  }
 }
 
 /** 弹窗确定 */
@@ -267,17 +324,38 @@ function modalConfirm() {
   });
 
   modal.modalShow = false;
-  realTimeSaving();
+  // realTimeSaving();
+}
+
+/**
+ * @图片上传成功回调
+ */
+ function uploadSuccessChange(e) {
+  
+  state.form.imageList.push({
+    name: e.name,
+    url: e.url,
+  })
+  realTimeSaving()
+}
+/**
+ * @图片删除回调
+ */
+ function uploadDeleteChange(e) {
+  state.form.imageList = e;
+  realTimeSaving()
 }
 
+
 /** 提交 */
 function handleSubmit() {
+  state.form.sendDingTalk == true ? 1 : 0;
+  state.form.id = state.form.id ? Number(state.form.id) : "";
   state.form.ccTo = state.userList.map((obj) => `${obj.id}`).join(",");
   state.form.reportDate = proxy.$time.formatterDate(new Date(), "yyyy-MM-dd");
   state.form.workContents.forEach((e) => {
     e.workTime = Number(e.workTime);
   });
-
   projectApi()
     .ReportInsert(state.form)
     .then((requset) => {
@@ -287,7 +365,7 @@ function handleSubmit() {
       state.form.coordinateWork = null;
       state.form.isRegularlySend = 0;
       state.form.timingTime = null;
-      storageSystem.set("project", state);
+      // storageSystem.set("project", state);
     });
 }
 
@@ -297,6 +375,7 @@ watch(
     state.userList = [];
     state.projectsCheck = [];
     state.projectsList = [];
+    state.form.imageList = [];
 
     Object.keys(props.projectList).forEach((key) => {
       state.form[key] = props.projectList[key];
@@ -305,55 +384,74 @@ watch(
     state.form.workContents.forEach((e) => {
       state.projectsCheck.push(e.projectId);
     });
-
     var ccTo = state.form.ccTo.length > 0 ? state.form.ccTo.split(",").map((num) => Number(num)) : [];
-    state.userDate.forEach((e) => {
-      if (ccTo.includes(e.userId)) {
-        state.userList.push({
-          address: e.address,
-          avatar: e.avatar,
-          deptId: e.deptId,
-          email: e.email,
-          id: e.userId,
-          label: e.nickName,
-          nickName: e.nickName,
-          phonenumber: e.phonenumber,
-          post: e.post,
-          sex: e.sex,
-          userId: e.userId,
-          userName: e.userName,
-        });
-      }
-    });
+    // setTimeout(function () {
+      state.userDate.forEach((e) => {
+        if (ccTo.includes(e.userId)) {
+          state.userList.push({
+            address: e.address,
+            avatar: e.avatar,
+            deptId: e.deptId,
+            email: e.email,
+            id: e.userId,
+            label: e.nickName,
+            nickName: e.nickName,
+            phonenumber: e.phonenumber,
+            post: e.post,
+            sex: e.sex,
+            userId: e.userId,
+            userName: e.userName,
+          });
+        }
+      });
+    // }, 300);
 
     projectApi()
       .ProjectsSelect()
       .then((requset) => {
         state.projectsList = requset.data;
       });
-
-    storageSystem.set("project", state);
+    if(!state.form.id){
+        storageSystem.set("project", state);
+      }
   }
 );
 
 onReady(() => {});
 
 onShow(() => {
+
+  init();
+
+
   //循环将缓存数据遍历
-  var storages = storageSystem.get("project");
-  Object.keys(storages).forEach((key) => {
-    state[key] = storages[key];
-  });
 
-  //监听组件返回数据
+  if(!state.form.id){
+    var storages = storageSystem.get("project");
+    Object.keys(storages).forEach((key) => {
+      state[key] = storages[key];
+    });
+  }
+  
+  
+
+  // 监听组件返回数据
   uni.$on("UserMall", function (value) {
     state.userList = value;
-    realTimeSaving();
+    if(!state.form.id){
+      realTimeSaving();
+    }
+   
   });
 });
 
 onLoad((options) => {
   init();
+  if (options.id) {
+    state.form.id = options.id;
+  } else {
+    state.form.id = "";
+  }
 });
 
 onUnload(() => {
@@ -362,22 +460,31 @@ onUnload(() => {
 </script>
 
 <style lang="scss" scoped>
-:deep(.u-cell__body) {
-  color: #000000;
-  font-size: 12px;
-  padding: 10px 0px !important;
+.checkbox-group-title{
+  display:block;width:100%;
+  font-size:16px;
+  font-weight:bold;
+  note-color: #909399;
+  margin-bottom:10px;
 }
+:deep() {
+  .u-cell__body {
+    color: #000000;
+    font-size: 12px;
+    padding: 10px 0px !important;
+  }
 
-:deep(.u-collapse-item__content) {
-  overflow: auto;
-}
+  .u-collapse-item__content {
+    overflow: auto;
+  }
 
-:deep(.u-collapse-item__content__text) {
-  padding: 0;
-}
+  .u-collapse-item__content__text {
+    padding: 0;
+  }
 
-:deep(.u-cell__left-icon-wrap) {
-  margin: 0;
+  .u-cell__left-icon-wrap {
+    margin: 0;
+  }
 }
 
 .content-area {

+ 34 - 3
src/pages/business/common/projectMange/write/insert.vue

@@ -1,6 +1,6 @@
 <template>
   <u-sticky class="shadow-default" bgColor="#fff" style="top: 0">
-    <u-navbar :titleStyle="{ color: '#000' }" :autoBack="true" title="报告填写" :placeholder="true" :safeAreaInsetTop="true" bgColor="#fff">
+    <u-navbar :titleStyle="{ color: '#000' }" :autoBack="true" :title="pageTitle" :placeholder="true" :safeAreaInsetTop="true" bgColor="#fff">
       <template #left>
         <view class="u-navbar__content__left__item">
           <u-icon name="arrow-left" size="20" color="#000"></u-icon>
@@ -65,13 +65,34 @@ var pages = getCurrentPages(); //获取当前页面栈的实例;
 const state = reactive({
   modalShow: false,
   newProjectList: {},
+  pageTitle: "",
 });
-const { modalShow, newProjectList } = toRefs(state);
+const { modalShow, newProjectList,pageTitle } = toRefs(state);
 
 function moreClick() {
   state.modalShow = true;
 }
 
+
+/**
+ * @列表查询
+ * @api接口查询
+ */
+ function selectListApi() {
+  projectApi()
+    .ProjectsWeekList({
+      id: parseInt(props.id),
+    })
+    .then((requset) => {
+      if (requset.data.length > 0) {
+        const data = requset.data[1].weekData[0];
+        state.newProjectList =data
+        console.log(state.newProjectList)
+      }
+    })
+    .catch((err) => {});
+}
+
 function handleSubmit(type, id) {
   if (type === "importPrevious") {
     projectApi()
@@ -88,6 +109,7 @@ function handleSubmit(type, id) {
           workContents: newData.workContents,
           sendDingTalk: newData.sendDingTalk,
           ccTo: newData.ccTo,
+          imgList: newData.imgList,
         };
 
         state.modalShow = false;
@@ -126,7 +148,16 @@ onShow(() => {
   proxy.$settingStore.systemThemeColor([1]);
 });
 
-onLoad((options) => {});
+onLoad((options) => {
+  if ("id" in options) {
+    state.pageTitle = "报告编辑";
+    selectListApi();
+  } else {
+    state.pageTitle = "报告填写";
+    state.newProjectList={}
+  }
+
+});
 
 onUnload(() => {});
 </script>

+ 7 - 6
src/pages/business/common/videoMonitor/videoDetail.vue

@@ -75,11 +75,12 @@ onLoad((options) => {
 </script>
 
 <style lang="scss" scoped>
-:deep(.u-input__content__field-wrapper__field) {
-  font-size: 13px !important;
-}
-
-:deep(.u-textarea__field) {
-  font-size: 13px;
+:deep() {
+  .u-input__content__field-wrapper__field {
+    font-size: 13px !important;
+  }
+  .u-textarea__field {
+    font-size: 13px;
+  }
 }
 </style>

+ 1 - 0
src/pages/business/mhxf/informationSelect/index.vue

@@ -112,6 +112,7 @@ function touchChange(e) {
 }
 
 function blur(e) {
+  console.log(1)
   if (state.dataInput) {
     goSearch();
   }

+ 31 - 28
src/pages/register.vue

@@ -178,36 +178,39 @@ onLoad((options) => {});
   }
 
   .bottom-area {
-    :deep(.u-input) {
-      height: 45px;
-      border-radius: 8px;
-      padding: 5px 12px !important;
-      border: 0 !important;
-      background-color: #f5f6fa !important;
-      margin-bottom: 15px;
-    }
-
-    :deep(.u-icon__icon) {
-      font-size: 24px !important;
-      line-height: 24px !important;
-      color: gray !important;
-    }
-
-    :deep(.iconfont) {
-      color: gray !important;
-    }
-
-    :deep(.input-placeholder) {
-      color: #c0c4cc !important;
-    }
-
-    :deep(.uni-input-wrapper) {
-      font-size: 16px;
+    :deep() {
+      .u-input {
+        height: 45px;
+        border-radius: 8px;
+        padding: 5px 12px !important;
+        border: 0 !important;
+        background-color: #f5f6fa !important;
+        margin-bottom: 15px;
+      }
+      .u-icon__icon {
+        font-size: 24px !important;
+        line-height: 24px !important;
+        color: gray !important;
+      }
+      .iconfont {
+        color: gray !important;
+      }
+      .input-placeholder {
+        color: #c0c4cc !important;
+      }
+      .uni-input-wrapper {
+        font-size: 16px;
+      }
+      .u-line {
+        display: none !important;
+      }
     }
+  }
+}
 
-    :deep(.u-line) {
-      display: none !important;
-    }
+@media (min-width: 1280px) {
+  #register-container {
+    padding-top: 10% !important;
   }
 }
 </style>

+ 18 - 19
src/pages/serveConfig.vue

@@ -196,25 +196,24 @@ onLoad((options) => {
   }
 
   .bottom-area {
-    :deep(.u-input) {
-      height: 45px;
-      border-radius: 8px;
-      padding: 5px 12px !important;
-      border: 0 !important;
-      background-color: #f5f6fa !important;
-      margin-bottom: 15px;
-    }
-
-    :deep(.input-placeholder) {
-      color: #c0c4cc !important;
-    }
-
-    :deep(.uni-input-wrapper) {
-      font-size: 16px;
-    }
-
-    :deep(.u-line) {
-      display: none !important;
+    :deep() {
+      .u-input {
+        height: 45px;
+        border-radius: 8px;
+        padding: 5px 12px !important;
+        border: 0 !important;
+        background-color: #f5f6fa !important;
+        margin-bottom: 15px;
+      }
+      .input-placeholder {
+        color: #c0c4cc !important;
+      }
+      .uni-input-wrapper {
+        font-size: 16px;
+      }
+      .u-line {
+        display: none !important;
+      }
     }
   }
 }

+ 25 - 0
src/plugins/common.plugins.js

@@ -71,6 +71,31 @@ export default {
       }
     });
   },
+
+
+    /**
+   * 树结构过滤
+   * @param {*} treeData 
+   * @param {*} ids 
+   * @returns 
+   */
+    findTreeNodes(treeData, ids) {
+      const result = [];
+      const findNodes_ = (nodes, idArray) => {
+        nodes.forEach(node => {
+          if (idArray.includes(node.id)) {
+            result.push(node);
+          }
+          if (node.children && node.children.length > 0) {
+            findNodes_(node.children, idArray);
+          }
+        });
+      };
+     
+      findNodes_(treeData, ids);
+      return result;
+    },
+  
   /**
    * @复制粘贴板
    * @param {传入值} content 

+ 23 - 0
src/static/scss/public.scss

@@ -212,7 +212,30 @@ uni-input {
     }
   }
 }
+.tableType4 {
+  .u-row {
+    align-items: initial !important;
+
+    border: 1px #e5e5e5 solid;
+    border-bottom: 0px;
+
+    >.u-col {
+      border-right: 1px #e5e5e5 solid;
+      white-space: normal;
+      word-break: break-all;
+    }
 
+    >.u-col:last-child {
+      border-right: 0px #e5e5e5 solid;
+    }
+  }
+
+  .u-row:last-child {
+    .u-col {
+      border-bottom: 1px #e5e5e5 solid;
+    }
+  }
+}
 
 //公共按钮样式
 .app-button {

+ 1 - 1
src/store/modules/setting.js

@@ -295,7 +295,7 @@ const settingStores = defineStore("storage-setting", {
             let data = {
                 _api_key: "fba7440cd37400b6ff46e303896af4df",
                 appKey: platform === "android" ? "cbd3508235d03365f4253f6aae6b68ab" : "4b858fce6367652f5c0959a0444a4bea",
-                buildVersion: "2.1.7",
+                buildVersion: config.appInfo.version,
             };
             modal.loading("加载中");
             checkUpdates(data).then((res) => {

+ 2 - 2
src/store/modules/user.js

@@ -285,9 +285,9 @@ const useStores = defineStore("useStores", {
     // 退出系统
     LogOut() {
       return new Promise((resolve, reject) => {
-        const openId = null;
+        var openId = null;
         // #ifdef H5
-        openId = localStorage.getItem("wxOpenId") ? localStorage.getItem("wxOpenId") : ""
+        openId = localStorage.getItem("wxOpenId") ? localStorage.getItem("wxOpenId") : "";
         // #endif
 
         logout({ openId: openId })