Explorar o código

自定义基线成本项,客户管理,删除基线记录

seyason %!s(int64=3) %!d(string=hai) anos
pai
achega
6c03215ead
Modificáronse 21 ficheiros con 1710 adicións e 345 borrados
  1. 9 9
      fhKeeper/formulahousekeeper/timesheet/package-lock.json
  2. 1 1
      fhKeeper/formulahousekeeper/timesheet/package.json
  3. 118 3
      fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/demo_index.html
  4. 23 3
      fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.css
  5. 1 1
      fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.js
  6. 35 0
      fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.json
  7. BIN=BIN
      fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.ttf
  8. BIN=BIN
      fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.woff
  9. BIN=BIN
      fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.woff2
  10. 6 2
      fhKeeper/formulahousekeeper/timesheet/src/main.js
  11. 26 2
      fhKeeper/formulahousekeeper/timesheet/src/routes.js
  12. 199 28
      fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/list.vue
  13. 461 0
      fhKeeper/formulahousekeeper/timesheet/src/views/customer/list.vue
  14. 98 210
      fhKeeper/formulahousekeeper/timesheet/src/views/project/earning.vue
  15. 7 5
      fhKeeper/formulahousekeeper/timesheet/src/views/project/fileCenter.vue
  16. 51 16
      fhKeeper/formulahousekeeper/timesheet/src/views/project/info.vue
  17. 246 57
      fhKeeper/formulahousekeeper/timesheet/src/views/project/list.vue
  18. 5 1
      fhKeeper/formulahousekeeper/timesheet/src/views/project/projectInside.vue
  19. 168 7
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue
  20. 234 0
      fhKeeper/formulahousekeeper/timesheet/src/views/workflow/report.vue
  21. 22 0
      fhKeeper/formulahousekeeper/timesheet_h5/public/index.html

+ 9 - 9
fhKeeper/formulahousekeeper/timesheet/package-lock.json

@@ -565,7 +565,7 @@
     },
     "async-validator": {
       "version": "1.8.5",
-      "resolved": "https://registry.npm.taobao.org/async-validator/download/async-validator-1.8.5.tgz?cache=0&sync_timestamp=1575620599372&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fasync-validator%2Fdownload%2Fasync-validator-1.8.5.tgz",
+      "resolved": "https://registry.nlark.com/async-validator/download/async-validator-1.8.5.tgz",
       "integrity": "sha1-3D4I7B/Q3dtn5ghC8CwM0c7G1/A=",
       "requires": {
         "babel-runtime": "6.x"
@@ -832,7 +832,7 @@
     },
     "babel-helper-vue-jsx-merge-props": {
       "version": "2.0.3",
-      "resolved": "https://registry.npm.taobao.org/babel-helper-vue-jsx-merge-props/download/babel-helper-vue-jsx-merge-props-2.0.3.tgz",
+      "resolved": "https://registry.nlark.com/babel-helper-vue-jsx-merge-props/download/babel-helper-vue-jsx-merge-props-2.0.3.tgz",
       "integrity": "sha1-Iq69OzOQIyjlEyk6jkmSs4T58bY="
     },
     "babel-helpers": {
@@ -2822,7 +2822,7 @@
     },
     "deepmerge": {
       "version": "1.5.2",
-      "resolved": "https://registry.npm.taobao.org/deepmerge/download/deepmerge-1.5.2.tgz",
+      "resolved": "https://registry.npm.taobao.org/deepmerge/download/deepmerge-1.5.2.tgz?cache=0&sync_timestamp=1612354180346&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdeepmerge%2Fdownload%2Fdeepmerge-1.5.2.tgz",
       "integrity": "sha1-EEmdhohEza1P7ghC34x/bwyVp1M="
     },
     "define-property": {
@@ -3085,9 +3085,9 @@
       "dev": true
     },
     "element-ui": {
-      "version": "2.13.0",
-      "resolved": "https://registry.npm.taobao.org/element-ui/download/element-ui-2.13.0.tgz",
-      "integrity": "sha1-9rsE5bCnbqX2JGYES3dEB7pOvS0=",
+      "version": "2.15.3",
+      "resolved": "https://registry.nlark.com/element-ui/download/element-ui-2.15.3.tgz?cache=0&sync_timestamp=1624954448804&other_urls=https%3A%2F%2Fregistry.nlark.com%2Felement-ui%2Fdownload%2Felement-ui-2.15.3.tgz",
+      "integrity": "sha1-VRCKuCo7zGRuewVwhxxIupYwBlI=",
       "requires": {
         "async-validator": "~1.8.1",
         "babel-helper-vue-jsx-merge-props": "^2.0.0",
@@ -5891,7 +5891,7 @@
     },
     "normalize-wheel": {
       "version": "1.0.1",
-      "resolved": "https://registry.npm.taobao.org/normalize-wheel/download/normalize-wheel-1.0.1.tgz",
+      "resolved": "https://registry.nlark.com/normalize-wheel/download/normalize-wheel-1.0.1.tgz",
       "integrity": "sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU="
     },
     "npmlog": {
@@ -7886,7 +7886,7 @@
     },
     "resize-observer-polyfill": {
       "version": "1.5.1",
-      "resolved": "https://registry.npm.taobao.org/resize-observer-polyfill/download/resize-observer-polyfill-1.5.1.tgz",
+      "resolved": "https://registry.nlark.com/resize-observer-polyfill/download/resize-observer-polyfill-1.5.1.tgz",
       "integrity": "sha1-DpAg3T0hAkRY1OvSfiPkAmmBBGQ="
     },
     "resolve": {
@@ -8658,7 +8658,7 @@
     },
     "throttle-debounce": {
       "version": "1.1.0",
-      "resolved": "https://registry.npm.taobao.org/throttle-debounce/download/throttle-debounce-1.1.0.tgz",
+      "resolved": "https://registry.nlark.com/throttle-debounce/download/throttle-debounce-1.1.0.tgz",
       "integrity": "sha1-UYU9o3vmihVctugns1FKPEIuic0="
     },
     "through2": {

+ 1 - 1
fhKeeper/formulahousekeeper/timesheet/package.json

@@ -15,7 +15,7 @@
     "dayjs": "^1.10.4",
     "dingtalk-jsapi": "^2.13.42",
     "echarts": "^3.8.5",
-    "element-ui": "^2.13.0",
+    "element-ui": "^2.15.3",
     "font-awesome": "^4.7.0",
     "jquery": "^3.4.1",
     "nprogress": "^0.2.0",

+ 118 - 3
fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/demo_index.html

@@ -54,6 +54,36 @@
       <div class="content unicode" style="display: block;">
           <ul class="icon_lists dib-box">
           
+            <li class="dib">
+              <span class="icon iconfont">&#xe634;</span>
+                <div class="name">流程</div>
+                <div class="code-name">&amp;#xe634;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe60e;</span>
+                <div class="name">长箭头</div>
+                <div class="code-name">&amp;#xe60e;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6e3;</span>
+                <div class="name">App_New_Line</div>
+                <div class="code-name">&amp;#xe6e3;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe609;</span>
+                <div class="name">line</div>
+                <div class="code-name">&amp;#xe609;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe61d;</span>
+                <div class="name">Insert Line</div>
+                <div class="code-name">&amp;#xe61d;</div>
+              </li>
+          
             <li class="dib">
               <span class="icon iconfont">&#xe611;</span>
                 <div class="name">密 码</div>
@@ -342,9 +372,9 @@
 <pre><code class="language-css"
 >@font-face {
   font-family: 'iconfont';
-  src: url('iconfont.woff2?t=1624604148407') format('woff2'),
-       url('iconfont.woff?t=1624604148407') format('woff'),
-       url('iconfont.ttf?t=1624604148407') format('truetype');
+  src: url('iconfont.woff2?t=1627295057848') format('woff2'),
+       url('iconfont.woff?t=1627295057848') format('woff'),
+       url('iconfont.ttf?t=1627295057848') format('truetype');
 }
 </code></pre>
           <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@@ -370,6 +400,51 @@
       <div class="content font-class">
         <ul class="icon_lists dib-box">
           
+          <li class="dib">
+            <span class="icon iconfont firerock-iconliucheng"></span>
+            <div class="name">
+              流程
+            </div>
+            <div class="code-name">.firerock-iconliucheng
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont firerock-iconright"></span>
+            <div class="name">
+              长箭头
+            </div>
+            <div class="code-name">.firerock-iconright
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont firerock-iconApp_New_Line"></span>
+            <div class="name">
+              App_New_Line
+            </div>
+            <div class="code-name">.firerock-iconApp_New_Line
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont firerock-icon0"></span>
+            <div class="name">
+              line
+            </div>
+            <div class="code-name">.firerock-icon0
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont firerock-iconInsertLine"></span>
+            <div class="name">
+              Insert Line
+            </div>
+            <div class="code-name">.firerock-iconInsertLine
+            </div>
+          </li>
+          
           <li class="dib">
             <span class="icon iconfont firerock-iconmima"></span>
             <div class="name">
@@ -802,6 +877,46 @@
       <div class="content symbol">
           <ul class="icon_lists dib-box">
           
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#firerock-iconliucheng"></use>
+                </svg>
+                <div class="name">流程</div>
+                <div class="code-name">#firerock-iconliucheng</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#firerock-iconright"></use>
+                </svg>
+                <div class="name">长箭头</div>
+                <div class="code-name">#firerock-iconright</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#firerock-iconApp_New_Line"></use>
+                </svg>
+                <div class="name">App_New_Line</div>
+                <div class="code-name">#firerock-iconApp_New_Line</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#firerock-icon0"></use>
+                </svg>
+                <div class="name">line</div>
+                <div class="code-name">#firerock-icon0</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#firerock-iconInsertLine"></use>
+                </svg>
+                <div class="name">Insert Line</div>
+                <div class="code-name">#firerock-iconInsertLine</div>
+            </li>
+          
             <li class="dib">
                 <svg class="icon svg-icon" aria-hidden="true">
                   <use xlink:href="#firerock-iconmima"></use>

+ 23 - 3
fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.css

@@ -1,8 +1,8 @@
 @font-face {
   font-family: "iconfont"; /* Project id 2390497 */
-  src: url('iconfont.woff2?t=1624604148407') format('woff2'),
-       url('iconfont.woff?t=1624604148407') format('woff'),
-       url('iconfont.ttf?t=1624604148407') format('truetype');
+  src: url('iconfont.woff2?t=1627295057848') format('woff2'),
+       url('iconfont.woff?t=1627295057848') format('woff'),
+       url('iconfont.ttf?t=1627295057848') format('truetype');
 }
 
 .iconfont {
@@ -13,6 +13,26 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.firerock-iconliucheng:before {
+  content: "\e634";
+}
+
+.firerock-iconright:before {
+  content: "\e60e";
+}
+
+.firerock-iconApp_New_Line:before {
+  content: "\e6e3";
+}
+
+.firerock-icon0:before {
+  content: "\e609";
+}
+
+.firerock-iconInsertLine:before {
+  content: "\e61d";
+}
+
 .firerock-iconmima:before {
   content: "\e611";
 }

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 1
fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.js


+ 35 - 0
fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.json

@@ -5,6 +5,41 @@
   "css_prefix_text": "firerock-icon",
   "description": "",
   "glyphs": [
+    {
+      "icon_id": "1868952",
+      "name": "流程",
+      "font_class": "liucheng",
+      "unicode": "e634",
+      "unicode_decimal": 58932
+    },
+    {
+      "icon_id": "9651039",
+      "name": "长箭头",
+      "font_class": "right",
+      "unicode": "e60e",
+      "unicode_decimal": 58894
+    },
+    {
+      "icon_id": "17223736",
+      "name": "App_New_Line",
+      "font_class": "App_New_Line",
+      "unicode": "e6e3",
+      "unicode_decimal": 59107
+    },
+    {
+      "icon_id": "261001",
+      "name": "line",
+      "font_class": "0",
+      "unicode": "e609",
+      "unicode_decimal": 58889
+    },
+    {
+      "icon_id": "17197893",
+      "name": "Insert Line",
+      "font_class": "InsertLine",
+      "unicode": "e61d",
+      "unicode_decimal": 58909
+    },
     {
       "icon_id": "19410111",
       "name": "密 码",

BIN=BIN
fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.ttf


BIN=BIN
fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.woff


BIN=BIN
fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.woff2


+ 6 - 2
fhKeeper/formulahousekeeper/timesheet/src/main.js

@@ -46,8 +46,8 @@ import 'nprogress/nprogress.css'
 var addRouFlag = false;
 //角色权限对应关系
 var userModules = [{role:0, modules:["工时报告","自动计时","项目管理"]},
-            {role:3, modules:["工时成本统计","项目报表服务","费用报销","财务核算成本","项目管理"]},
-            {role:4, modules:["组织架构"]},
+            {role:3, modules:["工时报告","工时成本统计","项目报表服务","费用报销","财务核算成本","项目管理"]},
+            {role:4, modules:["工时报告", "组织架构"]},
             {role:5, modules:["工时报告","自动计时","项目管理"]},];
 router.beforeEach((to, from, next) => {
     NProgress.start();
@@ -76,6 +76,10 @@ router.beforeEach((to, from, next) => {
                 if (user.company.packageExpense == 0) {
                     filterRouter = allRouters.filter(r=>{return r.name != '费用报销' && r.name != '项目报表服务'});
                 }
+                if (user.company.packageCustomer == 0) {
+                    //没有客户管理功能的,需要去掉
+                    filterRouter = allRouters.filter(r=>{return r.name != '客户管理'});
+                }
 
                 if (user.role == 1 || user.role == 2) {
                     getRoutes = filterRouter;

+ 26 - 2
fhKeeper/formulahousekeeper/timesheet/src/routes.js

@@ -39,10 +39,13 @@ import PdfView from './views/pdf/pdfview';
 
 // 费用报销
 import expense from './views/expense/expense';
+//客户管理
+import customer from './views/customer/list';
 //企业报表
 import corpReport from './views/corpreport/list';
 
-
+//审批流程
+import workflow from './views/workflow/report';
 // 权限管理
 // import jurisdiction from './views/jurisdiction/jurisdiction'
 
@@ -171,6 +174,17 @@ export const allRouters = [//组织架构
             { path: '/corpreport', component: corpReport, name: '项目报表服务' }
         ]
     },
+    {
+        path: '/',
+        component: Home,
+        name: '客户管理',
+        iconCls: 'iconfont firerock-iconbaobiao',
+        leaf: true,
+        children: [
+            { path: '/customer', component: customer, name: '客户管理' }
+        ]
+    },
+    
     // 费用报销模块
     {
         path: '/',
@@ -202,7 +216,17 @@ export const allRouters = [//组织架构
     //         { path: '/role', component: role, name: '角色权限' },
     //     ]
     // },
-    
+    // {
+        
+    //     path: '/',
+    //     component: Home,
+    //     name: '',
+    //     iconCls: 'iconfont firerock-iconliucheng',
+    //     leaf: true,//只有一个节点
+    //     children: [
+    //         { path: '/workflow', component: workflow, name: '审批流程设置' },
+    //     ]
+    // },
     //设置时间类型
     {
         

+ 199 - 28
fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/list.vue

@@ -20,6 +20,7 @@
               <el-menu-item index="1-2"><p @click="ssl(1)">项目任务报表</p></el-menu-item>
               <el-menu-item index="1-3"><p @click="ssl(2)">项目成本报表</p></el-menu-item>
               <el-menu-item index="1-4"><p @click="ssl(3)">项目收支平衡表</p></el-menu-item>
+              <el-menu-item index="1-5" v-if="user.company.packageCustomer == 1"><p @click="ssl(4)">客户项目利润表</p></el-menu-item>
             </el-submenu>
           </el-menu>
       </el-col>
@@ -32,17 +33,17 @@
   <div class="contents">
     <div class="headine" ref="headine">
       <h3 ref="headHe" style="padding-left: 210px">{{shuz[ins]}}</h3>
-      <p style="float: right;margin-right: 25px;"><el-button type="primary" @click="exportExcel" size="mini">报表导出</el-button></p>
+      <p style="float: right;margin-right: 25px;" ><el-button type="primary" @click="exportExcel" size="mini">报表导出</el-button></p>
     </div>
     <div ref="staff" style="margin: 5px 0px 0px 200px; width: 84%">
         <div class="staff">
             <!--项目报表 -->
-            <el-table v-show="ins == 0" border :data="list" highlight-current-row v-loading="listLoading" :height="tableHeight" style="width: 100%;">
+            <el-table v-if="ins == 0" border :data="list" highlight-current-row v-loading="listLoading" :height="tableHeight" style="width: 100%;">
                 <el-table-column  prop="projectCode" label="项目编码"  width="120"></el-table-column>
                 <el-table-column  prop="projectName" label="项目名称" ></el-table-column>
                 <el-table-column prop="inchargerName" label="负责人"  width="80">
                 </el-table-column>
-                <el-table-column prop="contractAmount" label="合同金额(元)"  width="150">
+                <el-table-column prop="contractAmount" label="合同金额(元)"  width="150" align="right">
                   <template slot-scope="scope">
                         {{scope.row.contractAmount.toFixed(2)}}
                     </template>
@@ -64,19 +65,19 @@
             </el-table>
 
             <!-- 项目任务报表 -->
-            <el-table v-show="ins == 1" border :data="list" highlight-current-row v-loading="listLoading" :height="tableHeight" style="width: 100%;">
+            <el-table v-if="ins == 1" border :data="list" highlight-current-row v-loading="listLoading" :height="tableHeight" style="width: 100%;">
                 <el-table-column  prop="project_code" label="项目编码"  width="120"></el-table-column>
                 <el-table-column  prop="project_name" label="项目名称" width="200"></el-table-column>
                 <el-table-column prop="name" label="任务名称"  width="300">
                 </el-table-column>
                 <el-table-column prop="plan_hours" label="计划工时(h)"  width="150">
                   <template slot-scope="scope">
-                        {{scope.row.plan_hours.toFixed(1)}}
+                        {{scope.row.plan_hours == null? 0:scope.row.plan_hours.toFixed(1)}}
                     </template>
                 </el-table-column>
                 <el-table-column prop="real_hours" label="实际工时(h)"  width="150">
                    <template slot-scope="scope">
-                        {{scope.row.real_hours.toFixed(1)}}
+                        {{scope.row.real_hours == null? 0:scope.row.real_hours.toFixed(1)}}
                     </template>
                 </el-table-column>
                 <el-table-column prop="task_status" label="状态" width="80" >
@@ -97,80 +98,132 @@
             </el-table>
 
             <!--项目成本报表 -->
-            <el-table v-show="ins == 2" border :data="list" highlight-current-row v-loading="listLoading" :height="tableHeight" style="width: 100%;">
+            <el-table v-if="ins == 2" border :data="list" highlight-current-row v-loading="listLoading" :height="tableHeight" style="width: 100%;">
                 <el-table-column  prop="projectCode" label="项目编码"  width="120"></el-table-column>
                 <el-table-column  prop="projectName" label="项目名称" ></el-table-column>
-                <el-table-column prop="feeMan" label="人工成本"  width="100" >
+                <el-table-column prop="feeMan" label="人工成本"  width="100"  align="right">
+                  <template slot-scope="scope">
+                        {{scope.row.feeMan==null?0:scope.row.feeMan.toFixed(2)}}
+                    </template>
+                </el-table-column>
+                <el-table-column prop="feeNormal" label="一般费用"  width="100" align="right">
+                  <template slot-scope="scope">
+                        {{scope.row.feeNormal==null?0:scope.row.feeNormal.toFixed(2)}}
+                    </template>
+                </el-table-column>
+                <el-table-column prop="feeTravel" label="差旅费用"  width="100" align="right">
+                  <template slot-scope="scope">
+                        {{scope.row.feeTravel==null?0:scope.row.feeTravel.toFixed(2)}}
+                    </template>
+                </el-table-column>
+                <el-table-column prop="feeOutsourcing" label="外包费用"  width="100" align="right">
+                  <template slot-scope="scope">
+                        {{scope.row.feeOutsourcing==null?0:scope.row.feeOutsourcing.toFixed(2)}}
+                    </template>
+                </el-table-column>
+                <el-table-column  label="总费用"  width="100" align="right">
+                  <template slot-scope="scope">
+                        {{scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing}}
+                    </template>
+                </el-table-column>
+            </el-table>
+            <!--项目收支平衡表 -->
+            <el-table v-if="ins == 3" border :data="list" highlight-current-row v-loading="listLoading" :height="tableHeight" style="width: 100%;">
+                <el-table-column prop="projectCode" label="项目编码"  width="120"></el-table-column>
+                <el-table-column prop="projectName" label="项目名称" ></el-table-column>
+                <el-table-column prop="contractAmount" label="合同金额" width="100" align="right">
+                  <template slot-scope="scope">
+                        {{scope.row.contractAmount.toFixed(2)}}
+                    </template>
+                </el-table-column>
+                <el-table-column prop="feeMan" label="人工成本"   width="100" align="right">
                   <template slot-scope="scope">
                         {{scope.row.feeMan.toFixed(2)}}
                     </template>
                 </el-table-column>
-                <el-table-column prop="feeNormal" label="一般费用"  width="100">
+                <el-table-column prop="feeNormal" label="一般费用"  width="100" align="right">
                   <template slot-scope="scope">
                         {{scope.row.feeNormal.toFixed(2)}}
                     </template>
                 </el-table-column>
-                <el-table-column prop="feeTravel" label="差旅费用"  width="100">
+                <el-table-column prop="feeTravel" label="差旅费用"  width="100" align="right">
                   <template slot-scope="scope">
                         {{scope.row.feeTravel.toFixed(2)}}
                     </template>
                 </el-table-column>
-                <el-table-column prop="feeOutsourcing" label="外包费用"  width="100">
+                <el-table-column prop="feeOutsourcing" label="外包费用"  width="100" align="right">
                   <template slot-scope="scope">
                         {{scope.row.feeOutsourcing.toFixed(2)}}
                     </template>
                 </el-table-column>
-                <el-table-column  label="总费用"  width="100">
+                <el-table-column  label="总费用"  width="100" align="right">
                   <template slot-scope="scope">
                         {{scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing}}
                     </template>
                 </el-table-column>
+                <el-table-column  label="利润"  width="100" align="right">
+                  <template slot-scope="scope">
+                        {{(scope.row.contractAmount==null?0:scope.row.contractAmount) - (scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing)}}
+                    </template>
+                </el-table-column>
+                <el-table-column  label="利润率"  width="100" align="right">
+                  <template slot-scope="scope">
+                        {{(scope.row.contractAmount==null||scope.row.contractAmount==0)?'-':((scope.row.contractAmount - (scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing))*100/scope.row.contractAmount).toFixed(1)+"%"}}
+                    </template>
+                </el-table-column>
             </el-table>
-            <!--项目收支平衡表 -->
-            <el-table v-show="ins == 3" border :data="list" highlight-current-row v-loading="listLoading" :height="tableHeight" style="width: 100%;">
-                <el-table-column prop="projectCode" label="项目编码"  width="120"></el-table-column>
-                <el-table-column prop="projectName" label="项目名称" ></el-table-column>
-                <el-table-column prop="contractAmount" label="合同金额" width="100">
+            <!--客户项目报表 -->
+            <el-table v-if="ins == 4" border :data="list" 
+            highlight-current-row v-loading="listLoading" :height="tableHeight" 
+             style="width: 100%;">
+                <el-table-column prop="customerName" label="客户名称" ></el-table-column>
+                <el-table-column prop="projectNames" label="相关项目">
+                  <template slot-scope="scope" >
+                    <el-Link @click="expandRow(scope.row, scope.$index)">{{scope.row.projectNames}}</el-Link>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="contractAmount" label="合同金额" width="100" align="right">
                   <template slot-scope="scope">
                         {{scope.row.contractAmount.toFixed(2)}}
                     </template>
                 </el-table-column>
-                <el-table-column prop="feeMan" label="人工成本"   width="100">
+                <el-table-column prop="feeMan" label="人工成本"   width="100" align="right">
                   <template slot-scope="scope">
                         {{scope.row.feeMan.toFixed(2)}}
                     </template>
                 </el-table-column>
-                <el-table-column prop="feeNormal" label="一般费用"  width="100">
+                <el-table-column prop="feeNormal" label="一般费用"  width="100" align="right">
                   <template slot-scope="scope">
                         {{scope.row.feeNormal.toFixed(2)}}
                     </template>
                 </el-table-column>
-                <el-table-column prop="feeTravel" label="差旅费用"  width="100">
+                <el-table-column prop="feeTravel" label="差旅费用"  width="100" align="right">
                   <template slot-scope="scope">
                         {{scope.row.feeTravel.toFixed(2)}}
                     </template>
                 </el-table-column>
-                <el-table-column prop="feeOutsourcing" label="外包费用"  width="100">
+                <el-table-column prop="feeOutsourcing" label="外包费用"  width="100" align="right">
                   <template slot-scope="scope">
                         {{scope.row.feeOutsourcing.toFixed(2)}}
                     </template>
                 </el-table-column>
-                <el-table-column  label="总费用"  width="100">
+                <el-table-column  label="总费用"  width="100" align="right">
                   <template slot-scope="scope">
                         {{scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing}}
                     </template>
                 </el-table-column>
-                <el-table-column  label="利润"  width="100">
+                <el-table-column  label="利润"  width="100" align="right">
                   <template slot-scope="scope">
                         {{(scope.row.contractAmount==null?0:scope.row.contractAmount) - (scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing)}}
                     </template>
                 </el-table-column>
-                <el-table-column  label="利润率"  width="100">
+                <el-table-column  label="利润率"  width="100" align="right">
                   <template slot-scope="scope">
                         {{(scope.row.contractAmount==null||scope.row.contractAmount==0)?'-':((scope.row.contractAmount - (scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing))*100/scope.row.contractAmount).toFixed(1)+"%"}}
                     </template>
                 </el-table-column>
             </el-table>
+            
         <!--工具条-->
         <el-col :span="24" class="toolbar">
             <el-pagination
@@ -189,7 +242,58 @@
     
   </div>
   </div>
-    
+    <!--新增界面-->
+        <el-dialog :title="title" show-summary v-if="addFormVisible" :visible.sync="addFormVisible" :close-on-click-modal="false" customClass="customWidth" width="1000px">
+            <el-table border :data="childrenList" 
+            highlight-current-row v-loading="listLoading" height="400"
+             style="width: 100%;">
+                <el-table-column prop="projectNames" label="相关项目">
+                </el-table-column>
+                <el-table-column prop="contractAmount" label="合同金额" width="100" align="right">
+                  <template slot-scope="scope">
+                        {{scope.row.contractAmount.toFixed(2)}}
+                    </template>
+                </el-table-column>
+                <el-table-column prop="feeMan" label="人工成本"   width="100" align="right">
+                  <template slot-scope="scope">
+                        {{scope.row.feeMan.toFixed(2)}}
+                    </template>
+                </el-table-column>
+                <el-table-column prop="feeNormal" label="一般费用"  width="100" align="right">
+                  <template slot-scope="scope">
+                        {{scope.row.feeNormal.toFixed(2)}}
+                    </template>
+                </el-table-column>
+                <el-table-column prop="feeTravel" label="差旅费用"  width="100" align="right">
+                  <template slot-scope="scope">
+                        {{scope.row.feeTravel.toFixed(2)}}
+                    </template>
+                </el-table-column>
+                <el-table-column prop="feeOutsourcing" label="外包费用"  width="100" align="right">
+                  <template slot-scope="scope">
+                        {{scope.row.feeOutsourcing.toFixed(2)}}
+                    </template>
+                </el-table-column>
+                <el-table-column  label="总费用"  width="100" align="right">
+                  <template slot-scope="scope">
+                        {{scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing}}
+                    </template>
+                </el-table-column>
+                <el-table-column  label="利润"  width="100" align="right">
+                  <template slot-scope="scope">
+                        {{(scope.row.contractAmount==null?0:scope.row.contractAmount) - (scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing)}}
+                    </template>
+                </el-table-column>
+                <el-table-column  label="利润率"  width="100" align="right">
+                  <template slot-scope="scope">
+                        {{(scope.row.contractAmount==null||scope.row.contractAmount==0)?'-':((scope.row.contractAmount - (scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing))*100/scope.row.contractAmount).toFixed(1)+"%"}}
+                    </template>
+                </el-table-column>
+            </el-table>
+            <div slot="footer" class="dialog-footer;">
+                <el-button @click.native="addFormVisible = false">关闭</el-button>
+            </div>
+        </el-dialog>
   </section>
 </template>
 
@@ -200,6 +304,9 @@ export default {
   props: {},
   data() {
     return {
+      addFormVisible:false,
+      title:'',
+      childrenList:[],
       taskTypeTxt:["任务", "里程碑", "风险"],
       taskStatusTxt:["进行中","已完成","已撤销"],
       statusTxt:["-","进行中","已完成","已撤销"],
@@ -217,8 +324,9 @@ export default {
       z   : null,
       value: null,
       dialog: false, // 单据查看展示
-      shuz: ["项目报表","项目任务报表","项目成本报表","项目收支平衡表(利润表)"],
-      ins: 0
+      shuz: ["项目报表","项目任务报表","项目成本报表","项目收支平衡表(利润表)","客户项目利润报表"],
+      ins: 0,
+      user: JSON.parse(sessionStorage.user)
     };
   },
   computed: {},
@@ -236,8 +344,9 @@ export default {
     this.getProjectList();
   },
   filters: {
+      
       numberToCurrency(value) {
-          if (!value) return '0.00'
+          if (value == undefined || !value) return '0.00'
           value = value.toFixed(2)
           const intPart = Math.trunc(value)
           const intPartFormat = intPart.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,')
@@ -251,6 +360,37 @@ export default {
       }
   },
   methods: {
+    expandRow(row, index) {
+      this.title = '客户:'+row.customerName;
+        this.childrenList = row.children;
+        this.addFormVisible = true;
+      },
+    // load(tree, treeNode, resolve) {
+    //     // setTimeout(() => {
+    //     //   resolve()
+    //     // }, 1000)
+    //     [
+    //         {
+    //           projectIds: 31,
+    //           projectNames: '2016-05-01',
+    //           contractAmount: 0,
+    //           feeMan:0,
+    //           feeNormal:0,
+    //           feeTravel:0,
+    //           feeOutsourcing:0,
+    //         },
+    //         {
+    //           projectIds: 32,
+    //           projectNames: '2016-05-01',
+    //           contractAmount: 0,
+    //           feeMan:0,
+    //           feeNormal:0,
+    //           feeTravel:0,
+    //           feeOutsourcing:0,
+    //         },
+    //       ]
+    //   },
+
             //分页
             handleCurrentChange(val) {
                 this.page = val;
@@ -270,6 +410,8 @@ export default {
                     this.getAllProjectCost();
                 } else if (this.ins == 3) {
                     this.getProjectInAndOut();
+                } else if (this.ins == 4) {
+                    this.getCustomerProjectInAndOut();
                 }
             },
       exportExcel() {
@@ -287,6 +429,9 @@ export default {
         } else if (this.ins == 3) {
           fName = "项目收支平衡表.xls";
           url += "/exportProjectInAndOut";
+        } else if (this.ins == 4) {
+          fName = "客户项目利润报表.xls";
+          url += "/exportCustomerProjectInAndOut";
         }
           this.http.post(url, {},
             res => {
@@ -314,10 +459,36 @@ export default {
     ssl(index) {
       this.z = index
       this.ins = index;
+      this.list = [];
       this.page = 1;
       this.pageSize = 20;
       this.getList();
     },
+    getCustomerProjectInAndOut() {
+      this.listLoading = true;
+      this.http.post('/project/getCustomerProjectInAndOut', {
+                    pageIndex: this.page,
+                    pageSize: this.size,
+                    },
+        res => {
+            if (res.code == "ok") {
+                this.list = res.data.records;
+                this.total = res.data.total;
+                this.listLoading = false; 
+            } else {
+                this.$message({
+                message: res.msg,
+                type: "error"
+                });
+            }
+        },
+        error => {
+            this.$message({
+                message: error,
+                type: "error"
+            });
+        });
+    },
     getProjectInAndOut() {
       this.listLoading = true;
       this.http.post('/project/getProjectInAndOut', {

+ 461 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/customer/list.vue

@@ -0,0 +1,461 @@
+<template>
+    <section>
+        <!--工具条-->
+        <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
+            <el-form :inline="true">
+                <el-form-item label="客户列表">
+                    
+                </el-form-item>
+                <el-form-item >
+                    <div>
+                    <el-input style="float:left;" v-model="keyword" class="input-with-select" placeholder="请输入客户名称关键字" clearable="true">
+                        <el-button slot="append" @click="searchList" icon="el-icon-search"></el-button>
+                    </el-input>
+                    </div>
+                </el-form-item>
+                <el-form-item style="float:right;" v-if="user.role == 1||user.role == 2||user.role == 5">
+                    <el-link type="primary" :underline="false" @click="handleAdd(-1,null)">新增客户</el-link>
+                </el-form-item>
+            </el-form>
+        </el-col>
+
+        <!--列表-->
+        <el-table :data="list" highlight-current-row v-loading="listLoading" :height="tableHeight" style="width: 100%;">
+            <el-table-column type="index" width="60">
+                <template slot-scope="scope" >
+                        {{scope.$index+1+(page-1)*size}}
+                    </template>
+            </el-table-column>
+            <el-table-column prop="customerCode" label="客户编码"  width="120"></el-table-column>
+            <el-table-column prop="customerName" label="客户名称" >
+            </el-table-column>
+            <el-table-column prop="contactName" label="联系人"  width="120">
+            </el-table-column>
+            <el-table-column prop="contactPhone" label="联系电话"  width="150">
+            </el-table-column>
+            <el-table-column prop="email" label="邮箱"  width="150">
+            </el-table-column>
+            <el-table-column prop="address" label="地址" >
+            </el-table-column>
+            
+            <el-table-column label="操作" width="150" v-if="user.role == 1||user.role == 2||user.role == 5 || user.leader">
+                <template slot-scope="scope">
+                    <el-button size="mini" v-if="user.role>0" type="primary" @click="handleAdd(scope.$index, scope.row)">编辑</el-button>
+                    <el-button v-if="user.role>0" size="mini"  @click="deletePro(scope.$index, scope.row)">删除</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+
+        <!--工具条-->
+        <el-col :span="24" class="toolbar">
+            <el-pagination
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :page-sizes="[20 , 50 , 80 , 100]"
+                :page-size="20"
+                layout="total, sizes, prev, pager, next"
+                :total="total"
+                style="float:right;"
+            ></el-pagination>
+        </el-col>
+
+        <!--新增界面-->
+        <el-dialog :title="title" v-if="addFormVisible" :visible.sync="addFormVisible" :close-on-click-modal="false" customClass="customWidth" width="800px">
+            <el-form ref="form1" :model="addForm" :rules="rules" label-width="120px">
+                <el-form-item label="客户编号" >
+                    <el-input v-model="addForm.customerCode" :max="20" :disabled="user.role==0" placeholder="请输入客户编号" clearable></el-input>
+                </el-form-item>
+                <el-form-item label="客户名称" prop="customerName">
+                    <el-input v-model="addForm.customerName" :max="20" :disabled="user.role==0" placeholder="请输入客户名称" clearable></el-input>
+                </el-form-item>
+                <el-form-item label="联系人" prop="contactName">
+                    <el-input v-model="addForm.contactName" :max="20" :disabled="user.role==0" placeholder="请输入客户联系人" clearable></el-input>
+                </el-form-item>
+                <el-form-item label="联系电话" prop="contactPhone">
+                    <el-input v-model="addForm.contactPhone" :max="20" :disabled="user.role==0" placeholder="请输入客户联系电话" clearable></el-input>
+                </el-form-item>
+                <el-form-item label="邮箱" prop="email">
+                    <el-input v-model="addForm.email" :max="25" :disabled="user.role==0" placeholder="请输入客户邮箱" clearable></el-input>
+                </el-form-item>
+                <el-form-item label="地址" prop="address">
+                    <el-input v-model="addForm.address" :max="50"  :disabled="user.role==0" placeholder="请输入客户联系地址" clearable></el-input>
+                </el-form-item>
+
+            </el-form>
+            <div slot="footer" class="dialog-footer;">
+                <el-button @click.native="addFormVisible = false">取消</el-button>
+                <el-button type="primary" @click="submitInsert" :loading="addLoading">提交</el-button>
+            </div>
+        </el-dialog>
+    </section>
+</template>
+<style scoped>
+.input-with-select .el-input-group__prepend {
+    background-color: #fff;
+  }
+.line {
+    padding:10px;
+}
+.line span{
+    font-size:15px;
+}
+.line span:nth-child(even){
+    float:right;
+}
+</style>
+<script>
+    import util from "../../common/js/util";
+    export default {
+        data() {
+            return {
+                roleArray:["普通员工","超级管理员", "系统管理员", "公司高层","人事管理员", "项目管理员"],
+                status:null,
+                statusTxt:["-","进行中","已完成","已撤销"],
+                importanceList:[{id:1,label:'正常'},{id:2,label:'紧急'},{id:3,label:'重要'},{id:4,label:'重要且紧急'}],
+                searchField:null,
+                keyword:null,
+                user: JSON.parse(sessionStorage.getItem("user")),
+                userDetailVisible: false,
+                userDetail:{},
+                date: new Date(),
+                users: [],
+                participator:[],
+                tableHeight: 0,
+                listLoading: false,
+                total: 0,
+                page: 1,
+                size: 20,
+                list: [],
+                subProjectVisible: false,
+                subProjectList: [],//子项目列表
+                currentProject:{},
+                addSubProject: false,
+                addFormVisible: false,
+                addLoading: false,
+                addUp: 0, // 合计
+                title: "",
+                addForm: {
+                    name: '',
+                    userId: [],
+                    level:1,
+                },
+                rules: {
+                    customerName: [{ required: true, message: "请输入客户名称", trigger: "blur" }],
+                }
+            };
+        },
+        // 过滤器
+        filters: {
+            numberToCurrency(value) {
+                if (!value) return '0.00'
+                // 将数值截取,保留两位小数
+                value = value.toFixed(2)
+                // 获取整数部分
+                const intPart = Math.trunc(value)
+                // 整数部分处理,增加,
+                const intPartFormat = intPart.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,')
+                // 预定义小数部分
+                let floatPart = '.00'
+                // 将数值截取为小数部分和整数部分
+                const valueArray = value.toString().split('.')
+                if (valueArray.length === 2) { // 有小数部分
+                floatPart = valueArray[1].toString() // 取得小数部分
+                return intPartFormat + '.' + floatPart
+                }
+                return intPartFormat + floatPart
+            }
+        },
+        methods: {
+            importProject(item) {
+                //首先判断文件类型
+                let str = item.file.name.split(".");
+                let format = str[str.length - 1];
+                if (format != "xls" && format != "xlsx") {
+                    this.$message({
+                        message: "请选择.xls或.xlsx文件",
+                        type: "error"
+                    });
+                } else {
+                    this.listLoading = true;
+                    let formData = new FormData();
+                    formData.append("file", item.file);
+                    formData.append("userId", this.user.id);
+                    this.http.uploadFile('/project/importData', formData,
+                    res => {
+                        this.$refs.upload.clearFiles();
+                        this.listLoading = false;
+                        if (res.code == "ok") {
+                            this.$message({
+                                message: "导入成功",
+                                type: "success"
+                            });
+                            this.getList();
+                        } else {
+                            this.$message({
+                                message: res.msg,
+                                type: "error"
+                            });
+                        }
+                    },
+                    error => {
+                        this.$refs.upload.clearFiles();
+                        this.listLoading = false;
+                        this.$message({
+                            message: error,
+                            type: "error"
+                        });
+                    });
+                }
+            },
+            number(){  
+        //      this.addForm.budget = this.addForm.budget.replace(/[^\.\d]/g,'');
+        //         this.addForm.budget = this.addForm.budget.replace('.','');
+          },
+            deleteSubPro(subProject) {
+                this.$confirm("确定要删除子项目" + subProject.name + "吗?","删除子项目", {
+                    confirmButtonText: "确定",
+                    cancelButtonText: "取消",
+                    type: "warning"
+                })
+                .then(() => {
+                    this.listLoading = true;
+                    this.http.post('/sub-project/deleteProject',{ 
+                        id: subProject.id 
+                    },
+                    res => {
+                        this.listLoading = false;
+                        if (res.code == "ok") {
+                            this.$message({
+                                message: "删除成功",
+                                type: "success"
+                            });
+                            this.subProject(this.currentProject);
+                        } else {
+                            this.$message({
+                                message: res.msg,
+                                type: "error"
+                            });
+                        }
+                    },
+                    error => {
+                        this.listLoading = false;
+                        this.$message({
+                            message: error,
+                            type: "error"
+                        });
+                        }
+                    );
+                })
+                .catch(() => {});
+            },
+            searchList() {
+                this.page = 1;
+                this.getList();
+            },
+            addNewSubProject(subProject) {
+                console.log(123);
+                if (subProject == null) {
+                    this.addForm = {projectId: this.currentProject.id, level:1}
+                } else {
+                    this.addForm = subProject;
+                }
+                this.addSubProject = true;
+            },
+            //显示子项目
+            subProject(item) {
+                this.subProjectVisible = true;
+                this.currentProject = item;
+                this.http.post('/sub-project/list', {
+                    projectId: item.id
+                },
+                res => {
+                    if (res.code == "ok") {
+                        this.subProjectList = res.data;
+                    } else {
+                        this.$message({
+                        message: res.msg,
+                        type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            //显示用户详情
+            showUser(userId) {
+                this.userDetailVisible = true;
+                this.http.post(this.port.manage.userDetail, {
+                    userId: userId
+                },
+                res => {
+                    if (res.code == "ok") {
+                        this.userDetail = res.data;
+                    } else {
+                        this.$message({
+                        message: res.msg,
+                        type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            
+            
+            //分页
+            handleCurrentChange(val) {
+                this.page = val;
+                this.getList();
+            },
+
+            handleSizeChange(val) {
+                this.size = val;
+                this.getList();
+            },
+
+            //获取项目列表
+            getList() {
+                this.listLoading = true;
+                this.http.post('/customer-info/list', {
+                    pageIndex: this.page,
+                    pageSize: this.size,
+                    keyword:this.keyword
+                },
+                res => {
+                    this.listLoading = false;
+                    if (res.code == "ok") {
+                        var list = res.data.records;
+                        this.list = list;
+                        this.total = res.data.total;
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.listLoading = false;
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+
+            //显示新增界面
+            handleAdd(i, item) {
+                if(i == -1) {
+                    this.title = "新增客户";
+                    this.addForm = {
+                    }
+                } else {
+                    this.title = "修改客户";
+                    this.addForm = JSON.parse(JSON.stringify(item));
+                }
+                this.addFormVisible = true;
+            },
+
+            submitInsert() {
+                this.$refs.form1.validate(valid => {
+                    if (valid) {
+                        this.addLoading = true;
+                        this.http.post('/customer-info/addOrMod', this.addForm,
+                        res => {
+                            this.addLoading = false;
+                            if (res.code == "ok") {
+                                this.addFormVisible = false;
+                                this.getList();
+                            } else {
+                                this.$message({
+                                    message: res.msg,
+                                    type: "error"
+                                });
+                            }
+                        },
+                        error => {
+                            this.addLoading = false;
+                            this.$message({
+                                message: error,
+                                type: "error"
+                            });
+                        });
+                        }
+                });
+            },
+
+            // 删除
+            deletePro(i, item) {
+                this.$confirm("确定要客户" + item.customerName + "吗?","删除客户", {
+                    confirmButtonText: "确定",
+                    cancelButtonText: "取消",
+                    type: "warning"
+                })
+                .then(() => {
+                    this.listLoading = true;
+                    this.http.post('/customer-info/delete',{ 
+                        id: item.id 
+                    },
+                    res => {
+                        this.listLoading = false;
+                        if (res.code == "ok") {
+                            this.$message({
+                                message: "删除成功",
+                                type: "success"
+                            });
+                            this.getList();
+                        } else {
+                            this.$message({
+                                message: res.msg,
+                                type: "error"
+                            });
+                        }
+                    },
+                    error => {
+                        this.listLoading = false;
+                        this.$message({
+                            message: error,
+                            type: "error"
+                        });
+                        }
+                    );
+                })
+                .catch(() => {});
+            },
+        },
+        created() {
+            let height = window.innerHeight;
+            this.tableHeight = height - 195;
+            const that = this;
+            window.onresize = function temp() {
+                that.tableHeight = window.innerHeight - 195;
+            };
+        },
+        mounted() {
+            this.getList();
+        }
+    };
+</script>
+
+<style lang="scss" scoped>
+.rg_span{
+    display: inline-block;
+}
+.rg_span span {
+    text-align: right;
+    box-sizing: border-box;
+    padding-right: 10px;
+}
+.el-dialog__title {
+    display: inline-table;
+    margin-top: 20px;
+}
+</style>

+ 98 - 210
fhKeeper/formulahousekeeper/timesheet/src/views/project/earning.vue

@@ -5,50 +5,46 @@
             <el-col :span="24">    
             <div class="box" style="height:650px;">
                 <div >
-                    <div class="lableTxt">项目利润快照</div>
+                    <div class="lableTxt">项目利润快照<el-button type="default" size="small" style="float:right;margin-left:10px;" @click="cancelDelete" v-if="deleteTxt == '确认删除'">取消操作</el-button><el-button type="default" size="small" style="float:right;" @click="showDeleteBox">{{deleteTxt}}</el-button></div>
                     <el-divider></el-divider>
                     <!--利润率列表-->
-                    <el-table :data="list" highlight-current-row v-loading="listLoading" max-height="300" style="width: 100%;">
+                    <el-table :data="list" highlight-current-row v-loading="listLoading" max-height="300" :height="300" style="width: 100%;" @selection-change="handleSelectionChange">
                         <el-table-column prop="indate" label="校准日期"  ></el-table-column>
-                        <el-table-column prop="profitA"  >
+                        <el-table-column prop="profit" align="right" >
                             <template slot="header">
-                               <span>利润率A</span>
-                               <el-popover placement="top" width="250" trigger="hover" content="利润率A = (合同金额 - 总成本)/合同金额">
+                               <span>利润</span>
+                               <el-popover placement="top" width="250" trigger="hover" content="利润 = (合同金额 - 总成本)">
                                    <i class="el-icon-question" slot="reference" />
                                </el-popover>
                             </template>
-                            <template slot-scope="scope">
-                                {{scope.row.profitA}}%
+                            <template slot-scope="scope" >
+                               ¥{{scope.row.profit | numberToCurrency}}
                             </template>
                         </el-table-column>
-                        <el-table-column prop="profitB" label="利润率B"  >
+                        <el-table-column prop="profitPercent" label="利润率B"  align="right">
                             <template slot="header">
-                               <span>利润率B</span>
-                               <el-popover placement="top" width="350" trigger="hover" content="利润率B = (合同金额 - 总成本 - 预留金额1)/合同金额">
+                               <span>利润率</span>
+                               <el-popover placement="top" width="350" trigger="hover" content="利润率 = (合同金额 - 总成本)/合同金额">
                                    <i class="el-icon-question" slot="reference" />
                                </el-popover>
                             </template>
                             <template slot-scope="scope">
-                                {{scope.row.profitB}}%
-                            </template>
-                        </el-table-column>
-                        <el-table-column prop="profitC" label="利润率C"  >
-                            <template slot="header">
-                               <span>利润率C</span>
-                               <el-popover placement="top" width="430" trigger="hover" content="利润率C = (合同金额 - 总成本 - 预留金额1 - 预留金额2)/合同金额">
-                                   <i class="el-icon-question" slot="reference" />
-                               </el-popover>
-                            </template>
-                            <template slot-scope="scope">
-                                {{scope.row.profitC}}%
+                                {{scope.row.profitPercent| numberToCurrency}}%
                             </template>
                         </el-table-column>
+                        
                         <el-table-column prop="contractAmount" label="合同金额" width="110" >
                             <template slot-scope="scope">
-                               <span style="font-size: 10px">¥{{scope.row.contractAmount | numberToCurrency}}</span>
+                               <span >¥{{scope.row.contractAmount | numberToCurrency}}</span>
                             </template>
                         </el-table-column>
-                        <el-table-column  label="基线成本" >
+                        <el-table-column label="基线成本" align="center">
+                            <el-table-column v-for="item in costFields" :prop="contractAmount" :label="item.baseName" :key="item.id" align="right">
+                                <template slot-scope="scope">
+                                ¥{{scope.row.costList.filter(c=>c.baseId == item.baseId)[0].baseAmount | numberToCurrency}}
+                                </template>
+                            </el-table-column>
+<!-- 
                             <el-table-column prop="baseMan" label="人员成本">
                                 <template slot-scope="scope">
                                 ¥{{scope.row.baseMan | numberToCurrency}}
@@ -73,6 +69,9 @@
                                 <template slot-scope="scope">
                                 ¥{{scope.row.baseRisk2 | numberToCurrency}}
                                 </template>
+                            </el-table-column> -->
+                            <el-table-column  label="选择" width="55" type="selection" v-if="deleteTxt == '确认删除'">
+                                
                             </el-table-column>
                         </el-table-column>
                     </el-table>
@@ -121,14 +120,15 @@
     export default {
         data() {
             return {
+                costFields:[],
+                selectionArray:[],
+                deleteTxt:"删除记录",
                 yList3:[],
                 yList2:[],
                 yList1:[],
                 xList:[],
                 list:[],
-                costChart:null,
-                stagesChart: null,
-                executorChart: null,
+                profitChart:null,
                 pVisible:false,
                 taskSum:{},
                 users:[],
@@ -163,21 +163,84 @@
             }
         },
         methods: {
+            handleSelectionChange(value) {
+                this.selectionArray = value;
+                console.log(this.selectionArray);
+            },
+            cancelDelete() {
+                this.deleteTxt = "删除记录";
+            },
+            showDeleteBox() {
+                if (this.deleteTxt == '删除记录') {
+                    this.deleteTxt = "确认删除";
+                } else {
+                    if (this.selectionArray.length == 0) {
+                        this.$message({
+                            message: '请先选择要删除的记录',
+                            type: "error"
+                        });
+                        return;
+                    }
+                    
+                    this.$confirm("确定要删除该记录吗吗?","删除记录", {
+                        confirmButtonText: "确定",
+                        cancelButtonText: "取消",
+                        type: "warning"
+                    })
+                    .then(() => {
+                        //调接口删除
+                        this.listLoading = true;
+                        var ids = '';
+                        this.deleteTxt = "删除记录";
+                        for (var i=0;i<this.selectionArray.length; i++) {
+                            ids += this.selectionArray[i].id+',';
+                        }
+                        this.http.post('/earning-snapshot/delete',{ 
+                            ids: ids, projectId:this.curProjectId
+                        },
+                        res => {
+                            this.listLoading = false;
+                            if (res.code == "ok") {
+                                this.getProfitSnapshot();
+                            } else {
+                                this.$message({
+                                    message: res.msg,
+                                    type: "error"
+                                });
+                            }
+                        },
+                        error => {
+                            this.listLoading = false;
+                            this.$message({
+                                message: error,
+                                type: "error"
+                            });
+                            }
+                        );
+                    }
+                    );
+                }
+
+            },
             getProfitSnapshot() {
                 let _this = this;
+                this.xList = [];
+                this.yList1 = [];
                 this.http.post('/earning-snapshot/list', {projectId: this.curProjectId},
                 res => {
                     if (res.code == "ok") {
                         var list = JSON.parse(JSON.stringify(res.data)).reverse();
+                        if (list.length > 0) {
+                            this.costFields = list[0].costList;
+                        }
                         _this.list = res.data;
                         for (var m=0;m<list.length; m++) {
                             this.xList.push(list[m].indate);
-                            this.yList1.push(list[m].profitA);
-                            this.yList2.push(list[m].profitB);
-                            this.yList3.push(list[m].profitC);
+                            this.yList1.push(list[m].profitPercent);
                         }
                         //图表展示
                         var myChart = echarts.init(document.getElementById("chartPanel"));
+                        this.profitChart = myChart;
                         myChart.setOption({
                             title: {
                                 textStyle: {
@@ -201,7 +264,7 @@
                                trigger: 'axis'
                             },
                             legend: {
-                                data: ['利润率A', '利润率B', '利润率C']
+                                data: ['利润率(%)']
                             },
                             grid: {
                                 left: '3%',
@@ -219,78 +282,12 @@
                             },
                             series : [
                                 {
-                                    name: '利润率A',
+                                    name: '利润率(%)',
                                     type: 'line',
                                     stack: '百分比',
                                     data: this.yList1
                                 },
-                                {
-                                    name: '利润率B',
-                                    type: 'line',
-                                    stack: '百分比',
-                                    data: this.yList2
-                                },
-                                {
-                                    name: '利润率C',
-                                    type: 'line',
-                                    stack: '百分比',
-                                    data: this.yList3
-                                },
-                            ]
-                        })
-                    } else {
-                        this.$message({
-                            message: res.msg,
-                            type: "error"
-                        });
-                    }
-                },
-                error => {
-                    this.$message({
-                        message: error,
-                        type: "error"
-                    });
-                });
-            },
-            getStagesPanel(){
-                let _this = this;
-                this.http.post('/task/getStagesPanel', {projectId: this.curProjectId},
-                res => {
-                    if (res.code == "ok") {
-                        var list = res.data;
-                        var myChart = echarts.init(document.getElementById("stagesPanel"));
-                        _this.stagesChart = myChart;
-                        myChart.setOption({
-                            title: {
-                                show:list.length == 0,
-                                textStyle: {
-                                    color: "#666666",
-                                    fontSize: 18,
-                                    fontWeight: 'normal',
-                                 },
-                              text: list.length == 0?"暂无数据":"任务列表统计",
-                              left: "center",
-                              top: "center"
-                            },
-                            toolbox: {
-                                show: true,
-                                feature:{
-                                    saveAsImage:{
-                                        show:true
-                                    },
-                                }
-                            },
-                            tooltip:{
-                                trigger:'item',
-                                formatter: "{b}<br/>任务数:{c} ({d}%)",
-                            },
-                            series : [
-                                {
-                                    name: '任务列表',
-                                    type: 'pie',
-                                    radius: '55%',
-                                    data:list
-                                }
+                                
                             ]
                         })
                     } else {
@@ -307,119 +304,13 @@
                     });
                 });
             },
-            getExecutorPanel(){
-                let _this = this;
-                this.http.post('/task/getExecutorPanel', {projectId: this.curProjectId},
-                res => {
-                    if (res.code == "ok") {
-                        var xList = [], yList = [], list = res.data;
-                        for(var i in list) {
-                            xList.push(list[i].executorName);
-                            yList.push({
-                                "value": list[i].taskCount,
-                                "id": list[i].executorId
-                            });
-                        }
-                        var myChart = echarts.init(document.getElementById("executorPanel"));
-                        _this.executorChart = myChart;
-                        var option = {
-                            title: {
-                                show:list.length == 0,
-                                textStyle: {
-                                    color: "#666666",
-                                    fontSize: 18,
-                                    fontWeight: 'normal',
-                                 },
-                              text: list.length == 0?"暂无数据":"执行人分配图",
-                              left: "center",
-                              top: "center"
-                            },
-                            toolbox: {
-                                show: true,
-                                feature:{
-                                    saveAsImage:{
-                                        show:true
-                                    },
-                                    restore:{
-                                        show:true
-                                    },
-                                    magicType:{
-                                        type:['line','bar']
-                                    },
-                                }
-                            },
-                            tooltip:{
-                                trigger:'axis',
-                                formatter: function (params,ticket,callback) {
-                                    var res = params[0].name + ""+" : " + params[0].data.value 
-                                    + "个";
-                                    _this.params = params;
-                                    return res;
-                                }
-                            },
-                            xAxis: {
-                                data: xList,
-                                axisLabel: {
-                                    interval:0,rotate:20
-                                }
-                            },
-                            yAxis: [{
-                                type : 'value',
-                                axisLabel: {
-                                    formatter:'{value} '
-                                }
-                            }],
-                            series: [{
-                                name: '任务数量(个)',
-                                type: 'bar',
-                                barMaxWidth: 30,
-                                data: yList,
-                            }]
-                        };
-                        myChart.setOption(option);
-                        console.log('===这是完成');
-                    } else {
-                        this.$message({
-                            message: res.msg,
-                            type: "error"
-                        });
-                    }
-                },
-                error => {
-                    this.$message({
-                        message: error,
-                        type: "error"
-                    });
-                });
-            },
-            getProjectTaskSum() {
-                this.http.post('/project/taskSum', {
-                    id: this.curProjectId
-                },
-                res => {
-                    if (res.code == "ok") {
-                        this.taskSum = res.data;
-                    } else {
-                        this.$message({
-                        message: res.msg,
-                        type: "error"
-                        });
-                    }
-                },
-                error => {
-                    this.$message({
-                        message: error,
-                        type: "error"
-                    });
-                });
-            },
+            
             refreshPage() {
                 this.curProjectId = parseInt(this.$route.params.id);
                 this.getProfitSnapshot();
             }
         },
         created() {
-            console.log('created===');
             let height = window.innerHeight;
             this.tableHeight = height - 160;
             const that = this;
@@ -428,13 +319,10 @@
             };
         },
         mounted() {
-            console.log('=========图表mounted===');
             this.curProjectId = parseInt(this.$route.params.id);
             var _this = this;
             window.addEventListener("resize", function() {
-                _this.executorChart.resize();
-                _this.stagesChart.resize();
-                _this.costChart.resize();
+                _this.profitChart.resize();
             });
             this.getProfitSnapshot(); // 调用图表方法
         }

+ 7 - 5
fhKeeper/formulahousekeeper/timesheet/src/views/project/fileCenter.vue

@@ -29,11 +29,12 @@
             <el-table :data="recentFiles" highlight-current-row :height="tableHeight">
                 <el-table-column prop="documentName" label="近期文件" sortable="true">
                     <template slot-scope="scope">
-                        <el-link @click.stop.native="viewOnline(scope.row)">
+                        <!-- <el-link @click.stop.native="viewOnline(scope.row)"> -->
                         <i v-if="scope.row.documentType == -1" class="iconfont firerock-iconfile fileTypeIcon"></i>
                         <i v-if="scope.row.documentType != -1" :class="docTypeList[scope.row.documentType]+' fileTypeIcon'" ></i>
-                        <span style="margin-left:8px;color:#262626;" @click="viewOnline(scope.row)">{{scope.row.documentName}}</span>
-                        </el-link>
+                        <span style="margin-left:8px;color:#262626;" >{{scope.row.documentName}}</span>
+                        <!-- <span style="margin-left:8px;color:#262626;" @click="viewOnline(scope.row)">{{scope.row.documentName}}</span> -->
+                        <!-- </el-link> -->
                     </template>
                 </el-table-column>
                 <el-table-column width="60">
@@ -50,10 +51,11 @@
                             <i class="el-icon-folder fileTypeIcon"></i><span style="margin-left:8px;color:#262626;" >{{scope.row.documentName}}</span>
                         </div>
                         <div v-if="scope.row.isFolder==0">
-                            <el-link @click.stop.native="viewOnline(scope.row)">
+                            <!-- <el-link @click.stop.native="viewOnline(scope.row)"> -->
                             <i v-if="scope.row.documentType == -1" class="iconfont firerock-iconfile fileTypeIcon"></i>
                             <i v-if="scope.row.documentType != -1" :class="docTypeList[scope.row.documentType]+' fileTypeIcon'"></i>
-                            <span style="margin-left:8px;color:#262626;" >{{scope.row.documentName}}</span></el-link>
+                            <span style="margin-left:8px;color:#262626;" >{{scope.row.documentName}}</span>
+                            <!-- </el-link> -->
                         </div>
                     </template>
                 </el-table-column>

+ 51 - 16
fhKeeper/formulahousekeeper/timesheet/src/views/project/info.vue

@@ -48,7 +48,12 @@
                 <div class="box info" style="margin-top:10px;">
                     <div><label>成本基线<el-link v-if="user.id == project.creatorId || user.id == project.inchargerId" @click="showEditBase" style="float:right;"><i class="el-icon-edit"  ></i></el-link></label>
                     <el-row :gutter="10">
-                        <el-col :span="5" ><span class="gray_label">人工成本:</span></el-col><el-col :span="7" ><span>
+                        <div v-for="item in projectBaseCostData" :key="item.id">
+                        <el-col :span="5" ><span class="gray_label">{{item.baseName}}:</span></el-col>
+                        <el-col :span="7" align="right" ><span style="padding-right:20px;">
+                            ¥{{item.baseAmount==null?'-':item.baseAmount | numberToCurrency}}</span></el-col>
+                        </div>
+                        <!-- <el-col :span="5" ><span class="gray_label">人工成本:</span></el-col><el-col :span="7" ><span>
                             ¥{{project.baseMan==null?'-':project.baseMan | numberToCurrency}}</span></el-col>
                         <el-col :span="5" ><span class="gray_label">费用:</span></el-col><el-col :span="7" ><span>
                         ¥{{project.baseFee==null?'-':project.baseFee | numberToCurrency}}</span></el-col></el-row>
@@ -59,7 +64,7 @@
                         <el-row :gutter="10"><el-col :span="5" ><span class="gray_label">风险预留金额2:</span></el-col><el-col :span="7" ><span>
                         ¥{{project.baseRisk2==null?'-':project.baseRisk2 | numberToCurrency}}</span></el-col>
                         <el-col :span="5" ><span class="gray_label">总成本:</span></el-col><el-col :span="7" ><span>
-                        ¥{{project.budget==null?'-':project.budget | numberToCurrency}}</span></el-col>
+                        ¥{{project.budget==null?'-':project.budget | numberToCurrency}}</span></el-col> -->
                     </el-row>
                     </div>
                 </div>
@@ -169,8 +174,11 @@
         </el-dialog>
 
         <el-dialog title="校正成本基线" v-if="addBaseFormVisible" :visible.sync="addBaseFormVisible" :close-on-click-modal="false" customClass="customWidth" width="600px">
-            <el-form ref="basicInfoForm" :model="addForm" :rules="rules" label-width="120px">
-                <el-form-item label="人工成本" >
+            <el-form ref="basicInfoForm" label-width="120px">
+                <el-form-item v-for="item in modBaseCostData" :label="item.baseName" :key="item.id">
+                    <el-input v-model="item.baseAmount"  placeholder="请输入" clearable></el-input>
+                </el-form-item>
+                <!-- <el-form-item label="人工成本" >
                     <el-input v-model="addForm.baseMan"  placeholder="请输入" clearable></el-input>
                 </el-form-item>
                 <el-form-item label="费用" prop="baseFee">
@@ -184,7 +192,8 @@
                 </el-form-item>
                 <el-form-item label="风险预留金额2" prop="baseRisk2">
                     <el-input v-model="addForm.baseRisk2"  placeholder="请输入" clearable></el-input>
-                </el-form-item>
+                </el-form-item> -->
+                
             </el-form>
             <div slot="footer" class="dialog-footer">
                 <el-button @click.native="addBaseFormVisible = false">取消</el-button>
@@ -261,6 +270,8 @@
     export default {
         data() {
             return {
+                modBaseCostData:[],
+                projectBaseCostData:[],
                 roleArray:["普通员工","超级管理员", "系统管理员", "公司高层","人事管理员", "项目管理员"],
                 addBaseFormVisible:false,
                 addMembVisible:false,
@@ -311,33 +322,55 @@
             }
         },
         methods: {
+            getProjectBaseData(projectId) {
+                this.http.post('/project-basecost/get',{projectId: projectId},
+                        res => {
+                            if (res.code == "ok") {
+                               this.projectBaseCostData = res.data;
+                            } else {
+                                this.$message({
+                                    message: res.msg,
+                                    type: "error"
+                                });
+                            }
+                        },
+                        error => {
+                            this.$message({
+                                message: error,
+                                type: "error"
+                            });
+                            }
+                        );
+            },
             adjustBase() {
                 //如果没有做修改,不提交数据
-                if (this.addForm.baseMan == this.project.baseMan 
-                        && this.addForm.baseFee == this.project.baseFee
-                        && this.addForm.baseOutsourcing == this.project.baseOutsourcing
-                        && this.addForm.baseRisk1 == this.project.baseRisk1
-                        && this.addForm.baseRisk2 == this.project.baseRisk2) {
+                var hasChangeData = false;
+                for (var i=0;i<this.modBaseCostData.length; i++) {
+                    var item = this.modBaseCostData[i];
+                    var oldAmount = this.projectBaseCostData.filter(p=>p.id == item.id)[0].baseAmount;
+                    if (item.baseAmount != oldAmount) {
+                        hasChangeData = true;
+                        break;
+                    }
+                }
+                if (!hasChangeData) {
                     this.addBaseFormVisible = false;
                     return;
                 }
                 this.http.post('/project/adjustBase', {
                     id: this.addForm.id,
                     contractAmount: this.addForm.contractAmount,
-                    baseMan: this.addForm.baseMan,
-                    baseFee:this.addForm.baseFee,
-                    baseOutsourcing:this.addForm.baseOutsourcing,
-                    baseRisk1:this.addForm.baseRisk1,
-                    baseRisk2: this.addForm.baseRisk2
+                    baseCostData:JSON.stringify(this.modBaseCostData),
                 },
                 res => {
                     if (res.code == "ok") {
-                        this.getProjectInfo();
+                        this.getProjectBaseData(this.curProjectId);
                         this.addBaseFormVisible = false;
                         this.$message({
                             message: '校准成功',
                             type: "success"
                         });
+                        this.$emit("basecost-change", null);
                     } else {
                         this.$message({
                         message: res.msg,
@@ -564,6 +597,7 @@
                 this.addForm.userId = arr;
                 this.addForm.code = this.addForm.projectCode;
                 this.addForm.name = this.addForm.projectName;
+                this.modBaseCostData = JSON.parse(JSON.stringify(this.projectBaseCostData));
                 this.addBaseFormVisible = true;
 
             },
@@ -758,6 +792,7 @@
             this.getProjectInfo();
             this.getUsers();
             this.getProjectTaskSum();
+            this.getProjectBaseData(this.curProjectId);
         }
     };
 </script>

+ 246 - 57
fhKeeper/formulahousekeeper/timesheet/src/views/project/list.vue

@@ -27,6 +27,10 @@
                             <el-option label="已撤销" value=3 ></el-option>
                         </el-select>
                 </el-form-item>
+                <!-- 项目成本基线条目 -->
+                <el-form-item style="float:right;" v-if="user.role == 1||user.role == 2||user.role == 5">
+                    <el-link type="primary" :underline="false" @click="showBaseCostItemDialog">基线成本项</el-link>
+                </el-form-item> 
                 <el-form-item style="float:right;" v-if="user.role == 1||user.role == 2||user.role == 5">
                     <el-link type="primary" style="margin-left:5px;" :underline="false" href="./upload/项目导入模板.xlsx" download="项目导入模板.xlsx">模板下载</el-link>
                 </el-form-item>
@@ -67,6 +71,9 @@
                     </v-for>
                 </template>
             </el-table-column>
+            <!-- 客户管理 -->
+            <el-table-column prop="customerName" label="客户"  v-if="user.company.packageCustomer == 1">
+            </el-table-column>
             <!--专业项目协作-->
             <el-table-column prop="status" label="状态" width="100" v-if="user.company.packageProject == 1">
                 <template slot-scope="scope">
@@ -109,6 +116,11 @@
                 <el-form-item label="项目名称" prop="name">
                     <el-input v-model="addForm.name" :disabled="user.role==0" placeholder="请输入项目名称" clearable></el-input>
                 </el-form-item>
+                <el-form-item label="客户" v-if="user.company.packageCustomer == 1">
+                    <el-select v-model="addForm.customerId" clearable="true" filterable placeholder="请选择客户" style="width:100%;" >
+                        <el-option v-for="item in customerList" :key="item.id" :label="item.customerName" :value="item.id"></el-option>
+                    </el-select>
+                </el-form-item>
                 <el-form-item label="全部参与者">
                     <el-select v-model="addForm.userId" multiple filterable placeholder="请选择参与者" style="width:100%;" @change="changeParticipator">
                         <el-option v-for="item in users" :key="item.id" :label="item.name" :value="item.id"></el-option>
@@ -158,45 +170,45 @@
                     <el-divider></el-divider>
                     <span class="el-dialog__title">成本基线</span>
                 </div>
-            <!-- 人工成本 -->
-            <span class="rg_span">
+            <!--新版 -->
+            <span class="rg_span" v-for="(item) in projectBaseCostData" :key="item.id">
+                <span style="width:120px;display: inline-block;" v-if="user.company.packageProject==1">{{item.baseName}}</span>
+                <el-input @input="addUpfun()" v-model="item.baseAmount" style="width:200px; margin-bottom: 20px"
+                placeholder="整数" clearable  @keyup.native="item.baseAmount=item.baseAmount.replace(/[^\d]/g,'');"></el-input><span style="margin-left:10px;">元</span>
+            </span>    
+
+            <!-- <span class="rg_span">
                 <span style="width:120px;display: inline-block;" v-if="user.company.packageProject==1">人工成本</span>
                 <el-input @input="addUpfun(addForm.baseMan)" v-model="addForm.baseMan" style="width:200px; margin-bottom: 20px"
                 placeholder="整数" clearable  @keyup.native="addForm.baseMan=addForm.baseMan.replace(/[^\d]/g,'');"></el-input><span style="margin-left:10px;">元</span>
             </span>
-            <!-- 费用 -->
             <span class="rg_span">
                 <span style="width:120px;display: inline-block;" v-if="user.company.packageProject==1">费用</span>
                 <el-input @input="addUpfun(addForm.baseFee)" v-model="addForm.baseFee" style="width:200px;"
                 placeholder="整数" clearable  @keyup.native="addForm.baseFee=addForm.baseFee.replace(/[^\d]/g,'');"></el-input><span style="margin-left:10px;">元</span>
             </span>
-            <!-- 外包费用 -->
             <div class="rg_span" style="margin-bottom: 20px;">
                 <span style=" width:120px;display: inline-block;" v-if="user.company.packageProject==1">外包费用</span>
                 <el-input @input="addUpfun(addForm.baseOutsourcing)" v-model="addForm.baseOutsourcing" style="width:200px;"
                 placeholder="整数" clearable @keyup.native="addForm.baseOutsourcing=addForm.baseOutsourcing.replace(/[^\d]/g,'');"></el-input><span style="margin-left:10px;">元</span>
             </div>
-            <!-- 预留风险金额1 -->
             <div style="display: inline-block;" class="rg_span">
                 <span style="width:120px;display: inline-block;text-align: right;" v-if="user.company.packageProject==1">预留风险金额1</span>
                 <el-input @input="addUpfun(addForm.baseRisk1)" v-model="addForm.baseRisk1" style="width:200px;"
                 placeholder="整数" clearable @keyup.native="addForm.baseRisk1=addForm.baseRisk1.replace(/[^\d]/g,'');"></el-input><span style="margin-left:10px;">元</span>
             </div>
-            <!-- 预留风险金额2 -->
             <div class="rg_span">
                 <span style="width:120px;display: inline-block;text-align: right;" v-if="user.company.packageProject==1">预留风险金额2</span>
                 <el-input @input="addUpfun(addForm.baseRisk2)" v-model="addForm.baseRisk2" style="width:200px;"
                 placeholder="整数" clearable @keyup.native="addForm.baseRisk2=addForm.baseRisk2.replace(/[^\d]/g,'');"></el-input><span style="margin-left:10px;">元</span>
-            </div>
+            </div> -->
             <!-- 合计 -->
-            <div style="margin-top: 20px;float:right;">
+            <div style="margin-top: 10px;float:right;">
                 <span style="margin-right:50px;margin-right:10px;" v-if="user.company.packageProject==1">合计</span>
                  <span v-if="addForm.budget <= 0 || addForm.budget == undefined">0</span>
                  <span v-else>{{addForm.budget | numberToCurrency}}</span>
                 <span style="margin-right:50px;margin-left:10px;">元</span>
             </div>
-
-
             </el-form>
             <div slot="footer" class="dialog-footer;">
                 <el-button @click.native="addFormVisible = false">取消</el-button>
@@ -251,6 +263,41 @@
                 <el-button type="primary" @click="submitInsertSubProject" :loading="addLoading">提交</el-button>
             </div>
         </el-dialog>
+
+        <!-- 项目基线成本项配置弹出框 -->
+        <el-dialog title="项目基线成本项管理" show-header="false" v-if="showBaseConfig" :visible.sync="showBaseConfig" :close-on-click-modal="false" customClass="customWidth" width="500px">
+            <el-table :data="baseCostItemList" highlight-current-row  height="400" style="width: 100%;">
+            <el-table-column type="index" width="60" label="序号">
+                <template slot-scope="scope" >
+                        {{scope.$index+1+(page-1)*size}}
+                    </template>
+            </el-table-column>
+            <el-table-column prop="name" label="名称" ></el-table-column>
+            <el-table-column label="操作" width="150">
+                <template slot-scope="scope" >
+                    <el-button size="small" type="primary" @click="addNewBaseItem(scope.row)">编辑</el-button>
+                    <el-button size="small" type="danger" @click="deleteBaseItem(scope.row)">删除</el-button>
+                </template>
+            </el-table-column>
+
+            </el-table>
+            <div slot="footer" class="dialog-footer">
+                <el-button type="primary" @click="showBaseConfig = false" >关闭</el-button>
+                <el-button type="primary" @click="addNewBaseItem()" >新增成本项</el-button>
+            </div>
+        </el-dialog>
+
+        <el-dialog title="新增/修改成本项" v-if="addBaseItemDialog" :visible.sync="addBaseItemDialog" :close-on-click-modal="false" customClass="customWidth" width="500px">
+            <el-form ref="form2" :model="addForm" :rules="rules" label-width="100px">
+                <el-form-item label="成本项名称" prop="name">
+                    <el-input v-model="addForm.name" placeholder="请输入名称" clearable></el-input>
+                </el-form-item>
+            </el-form>
+            <div slot="footer" class="dialog-footer">
+                <el-button @click.native="addBaseItemDialog = false">取消</el-button>
+                <el-button type="primary" @click="submitInsertBaseItem" :loading="addLoading">提交</el-button>
+            </div>
+        </el-dialog>
     </section>
 </template>
 <style scoped>
@@ -272,6 +319,10 @@
     export default {
         data() {
             return {
+                projectBaseCostData:[],
+                addBaseItemDialog:false,
+                showBaseConfig:false,
+                customerList:[],
                 roleArray:["普通员工","超级管理员", "系统管理员", "公司高层","人事管理员", "项目管理员"],
                 status:null,
                 statusTxt:["-","进行中","已完成","已撤销"],
@@ -304,7 +355,7 @@
                     level:1,
                 },
                 rules: {
-                    name: [{ required: true, message: "请输入项目名称", trigger: "blur" }],
+                    name: [{ required: true, message: "请输入名称", trigger: "blur" }],
                 }
             };
         },
@@ -330,6 +381,119 @@
             }
         },
         methods: {
+            getProjectBaseConfigList() {
+                this.http.post('/project-basecost-setting/list',{},
+                    res => {
+                        if (res.code == "ok") {
+                           this.baseCostItemList = res.data;
+                           this.$forceUpdate();
+                        } else {
+                            this.$message({
+                                message: res.msg,
+                                type: "error"
+                            });
+                        }
+                    },
+                    error => {
+                        this.$message({
+                            message: error,
+                            type: "error"
+                        });
+                        }
+                    );
+                
+            },
+            deleteBaseItem(row) {
+                this.$confirm("该操作可能造成已有数据丢失,确定要删除吗?","删除成本基线项", {
+                    confirmButtonText: "确定",
+                    cancelButtonText: "取消",
+                    type: "warning"
+                })
+                .then(() => {
+                    this.listLoading = true;
+                    this.http.post('/project-basecost-setting/delete',{ 
+                        id: row.id 
+                    },
+                    res => {
+                        this.listLoading = false;
+                        if (res.code == "ok") {
+                            this.$message({
+                                message: "删除成功",
+                                type: "success"
+                            });
+                            this.getProjectBaseConfigList();
+                        } else {
+                            this.$message({
+                                message: res.msg,
+                                type: "error"
+                            });
+                        }
+                    },
+                    error => {
+                        this.listLoading = false;
+                        this.$message({
+                            message: error,
+                            type: "error"
+                        });
+                        }
+                    );
+                })
+                .catch(() => {});
+            },
+            submitInsertBaseItem() {
+                this.http.post('/project-basecost-setting/addOrMod',this.addForm,
+                    res => {
+                        if (res.code == "ok") {
+                            this.addBaseItemDialog = false;
+                            this.baseCostItemList = res.data;
+                            this.$forceUpdate();
+                        } else {
+                            this.$message({
+                                message: res.msg,
+                                type: "error"
+                            });
+                        }
+                    },
+                    error => {
+                        this.$message({
+                            message: error,
+                            type: "error"
+                        });
+                        }
+                    );
+            },
+            showBaseCostItemDialog() {
+                this.showBaseConfig = true;
+            },
+            addNewBaseItem(row) {
+                this.addBaseItemDialog = true;
+                if (row == null) {
+                    this.addForm = {}
+                } else {
+                    this.addForm = row;
+                }
+            },
+            //获取客户列表
+            getCustomerList() {
+                this.http.post('/customer-info/getAll', {
+                },
+                res => {
+                    if (res.code == "ok") {
+                        this.customerList = res.data;
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
             importProject(item) {
                 //首先判断文件类型
                 let str = item.file.name.split(".");
@@ -475,13 +639,16 @@
             //选择参与人
             changeParticipator() {
                 //检查是否在参与人中,如果没有需要加入到参与人中
-                console.log(this.addForm.userId);
-                console.log(this.addForm)
-                var find = false;
                 this.participator = [];
                 this.addForm.userId.forEach(u=>{
-                    var findUser = this.users.filter(au=>au.id == u)[0];    
-                    this.participator.push(findUser);
+                    var list = this.users.filter(au=>au.id == u);
+                    if (list.length > 0) {
+                        var findUser = list[0];    
+                        this.participator.push(findUser);
+                    } else {
+                        console.log('未找到用户: '+u);
+                    }
+                    
                 })
             },
             getUsers() {
@@ -572,6 +739,11 @@
                         code:'',
                         inchargerId:null,
                         level:1,
+                        customerId:null,
+                    }
+                    this.projectBaseCostData = [];
+                    for (var m=0;m<this.baseCostItemList.length; m++) {
+                        this.projectBaseCostData.push({baseId: this.baseCostItemList[m].id, baseName:this.baseCostItemList[m].name, baseAmount:0});
                     }
                 } else {
                     this.title = "修改项目";
@@ -579,7 +751,6 @@
                     for(var j in list) {
                         arr.push(list[j].id)
                     }
-                    
                     this.addForm = {
                         id: item.id,
                         name: item.projectName,
@@ -595,13 +766,37 @@
                         baseFee: item.baseFee,
                         baseRisk1: item.baseRisk1,
                         baseRisk2: item.baseRisk2,
-                        baseOutsourcing: item.baseOutsourcing
+                        baseOutsourcing: item.baseOutsourcing,
+                        customerId:item.customerId==0?null:item.customerId,
                     }
                     this.changeParticipator();
+                    this.getProjectBaseData(item.id);
                 }
                 this.addFormVisible = true;
             },
 
+            getProjectBaseData(projectId) {
+                this.http.post('/project-basecost/get',{projectId: projectId},
+                        res => {
+                            if (res.code == "ok") {
+                               this.projectBaseCostData = res.data;
+                            } else {
+                                this.$message({
+                                    message: res.msg,
+                                    type: "error"
+                                });
+                            }
+                        },
+                        error => {
+                            this.listLoading = false;
+                            this.$message({
+                                message: error,
+                                type: "error"
+                            });
+                            }
+                        );
+            },
+
             //提交子项目创建修改请求
             submitInsertSubProject () {
                 this.$refs.form2.validate(valid => {
@@ -634,23 +829,28 @@
                 });
             },
             // 项目基线合计
-            addUpfun(je) {
-                var a = '0'
-                var q = '0'
-                var w = '0'
-                var e = '0'
-                var r = '0'
-                //  this.addForm.baseMan === undefined || this.addForm.baseMan === NaN ? this.addForm.baseMa = '0' : this.addForm.baseMan
-                if (this.addForm.baseMan == undefined || this.addForm.baseMan == NaN) {
-                    a = 0
-                } else {
-                    a = this.addForm.baseMan
+            addUpfun() {
+                var total = 0;
+                for (var i=0;i<this.projectBaseCostData.length; i++) {
+                    total += parseInt(this.projectBaseCostData[i].baseAmount);
                 }
-                if (this.addForm.baseFee !== undefined) q = this.addForm.baseFee
-                if (this.addForm.baseOutsourcing !== undefined) w = this.addForm.baseOutsourcing
-                if (this.addForm.baseRisk1 !== undefined) e = this.addForm.baseRisk1
-                if (this.addForm.baseRisk2 !== undefined) r = this.addForm.baseRisk2
-                this.addForm.budget = +a + +q + +w + +e + +r
+                this.addForm.budget = total;
+                // var a = '0'
+                // var q = '0'
+                // var w = '0'
+                // var e = '0'
+                // var r = '0'
+                // //  this.addForm.baseMan === undefined || this.addForm.baseMan === NaN ? this.addForm.baseMa = '0' : this.addForm.baseMan
+                // if (this.addForm.baseMan == undefined || this.addForm.baseMan == NaN) {
+                //     a = 0
+                // } else {
+                //     a = this.addForm.baseMan
+                // }
+                // if (this.addForm.baseFee !== undefined) q = this.addForm.baseFee
+                // if (this.addForm.baseOutsourcing !== undefined) w = this.addForm.baseOutsourcing
+                // if (this.addForm.baseRisk1 !== undefined) e = this.addForm.baseRisk1
+                // if (this.addForm.baseRisk2 !== undefined) r = this.addForm.baseRisk2
+                // this.addForm.budget = +a + +q + +w + +e + +r
             },
             submitInsert() {
                 this.$refs.form1.validate(valid => {
@@ -682,32 +882,19 @@
                             formData.append("level", this.addForm.level);
                         }
                         if(this.addForm.contractAmount != null) {
-                            formData.append("contractAmount", this.addForm.contractAmount)
-                        }
-                        if(this.addForm.baseMan != null) { // 人工成本
-                            formData.append("baseMan", this.addForm.baseMan)
+                            formData.append("contractAmount", this.addForm.contractAmount);
                         }
-                        if(this.addForm.baseFee != null) { // 费用
-                            formData.append("baseFee", this.addForm.baseFee)
+                        if (this.projectBaseCostData != null) {
+                            formData.append("projectBaseCostData", JSON.stringify(this.projectBaseCostData));
+                            //计算总预算成本
+                            formData.append("budget", this.addForm.budget);
                         }
-                        if(this.addForm.baseOutsourcing != null) { // 外包费用
-                            formData.append("baseOutsourcing", this.addForm.baseOutsourcing)
-                        }
-                        if(this.addForm.baseRisk1 != null) { // 预留风险金额1
-                            formData.append("baseRisk1", this.addForm.baseRisk1)
-                        }
-                        if(this.addForm.baseRisk2 != null) { //预留风险金额1
-                            formData.append("baseRisk2", this.addForm.baseRisk2)
-                        }
-                         if(this.addForm.budget != null) { //预留风险金额1
-                            formData.append("budget", this.addForm.budget)
+                        if (this.addForm.customerId == null) {
+                            formData.append("customerId", 0);
+                        } else {
+                            formData.append("customerId", this.addForm.customerId);
                         }
-                        // 合计
-                        // if(this.addUp != null) {
-                        //     this.addForm.budget = this.addUp
-                        //     formData.append("budget", this.addForm.budget);
-                        // }
-                        console.log(this.addForm.budget, 123, this.addUp);
+                        
                         this.http.uploadFile(this.port.project.add,formData,
                         res => {
                             this.addLoading = false;
@@ -790,6 +977,8 @@
         mounted() {
             this.getList();
             this.getUsers();
+            this.getCustomerList();
+            this.getProjectBaseConfigList();
         }
     };
 </script>

+ 5 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/project/projectInside.vue

@@ -222,7 +222,7 @@
                 </el-container>
             </el-tab-pane>
             <el-tab-pane label="文件中心" name="files"><FileCenter ref="fileCenter"></FileCenter></el-tab-pane>
-            <el-tab-pane label="项目概览" name="info"><ProjectInfo ref="projectInfo"></ProjectInfo></el-tab-pane>
+            <el-tab-pane label="项目概览" name="info"><ProjectInfo ref="projectInfo" @basecost-change="changeBase"></ProjectInfo></el-tab-pane>
             <el-tab-pane label="数据统计" name="summary"><Summary ref="summary"></Summary></el-tab-pane>
             <el-tab-pane label="挣值分析" name="earning" v-if="user.role >= 1 && user.role<=3"><Earning ref="earning"></Earning></el-tab-pane>
         </el-tabs>
@@ -806,6 +806,9 @@
             
         },
         methods: {
+            changeBase() {
+                this.$refs.earning.refreshPage();
+            },
             // 批量导入人员
             importTask(item) {
                 //首先判断文件类型
@@ -1717,6 +1720,7 @@
                 this.$refs.fileCenter.refreshPage();
                 this.$refs.projectInfo.refreshPage();
                 this.$refs.summary.refreshPage();
+                this.$refs.earning.refreshPage();
             },
             //获取我的项目列表
             getMyProjectList() {

+ 168 - 7
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

@@ -70,8 +70,12 @@
                 <div class="allDaily" style="float:left;flex-grow:1">
                     <!--系统管理员和部门负责人 -->
                     <div class="report_title" v-if="user.role == 1 || user.role == 2 || user.manageDeptId > 0">
-                        <span>工作日报 | {{depData.label}}</span> - 已填写<span style="margin-left:5px;margin-right:5px;color:green;">{{reportList.length}}</span>人,
-                    未填写<span style="margin-left:5px;margin-right:5px;color:red;">{{(depData == null?data[0].membCount:(depData.isUser == 1?1:depData.membCount))-reportList.length}}</span>人
+                        <span>工作日报 | {{depData != null ?depData.label:""}}</span>
+                        <span v-if="targetUid == null">
+                         - 已填写
+                        <el-link :underline="false" @click="showMembList(1)"><span style="margin-left:5px;margin-right:5px;color:green;">{{reportList.length}}</span></el-link>人,
+                    未填写<el-link :underline="false" @click="showMembList(0)"><span style="margin-left:5px;margin-right:5px;color:red;">{{(depData == null?data[0].membCount:(depData.isUser == 1?1:depData.membCount))-reportList.length}}</span></el-link>人
+                        </span>
                         <span style="float:right;">
                             <el-link type="primary" style="margin-right:10px;" :underline="false" @click="fillInReport(-1,0)">填写日报</el-link>
                             <el-link type="primary" style="margin-right:10px;" :underline="false" @click="fillInReport(-1,1)">批量填报</el-link>
@@ -293,6 +297,24 @@
                 <el-button type="primary" @click="exportReport" style="width:100%;" >导出</el-button>
             </div>
         </el-dialog>
+        <!--人员列表 -->
+        <el-dialog  :title="(isFill?'已填':'未填')+'人员列表'" v-if="membListVisible" :visible.sync="membListVisible"  width="500px">
+            <el-table :show-header="false" :data="fillMembList" highlight-current-row :height="400" style="width: 100%;">
+            <el-table-column type="index" width="60">
+                <template slot-scope="scope" >
+                        {{scope.$index+1}}
+                    </template>
+            </el-table-column>
+            <el-table-column prop="label" label="姓名" ></el-table-column>
+            <el-table-column prop="deptName" label="部门" >
+            </el-table-column>
+
+            </el-table>
+            <div slot="footer" class="dialog-footer">
+                <el-button type="primary" @click="weixinNotify"  v-if="!isFill" :disabled="fillMembList == 0">微信催填</el-button>
+                <el-button type="default" @click="exportMemb"  :disabled="fillMembList == 0">导出</el-button>
+            </div>
+        </el-dialog>
     </section>
 </template>
 
@@ -302,6 +324,11 @@
     export default {
         data() {
             return {
+                isFill:false,
+                unFillList:[],
+                fillList:[],
+                fillMembList:[],
+                membListVisible: false,
                 isBatch:0,//是否是批量填报
                 weekDay : ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],
                 statusStyle:["waiting", "filledReportStyle", "RejectStyle", ""],
@@ -385,6 +412,68 @@
             };
         },
         methods: {
+            //微信通知人员填写
+            weixinNotify() {
+                if (this.fillMembList.length == 0) return;
+                var ids = '';
+                this.fillMembList.forEach(f=>{
+                    ids += f.id+',';
+                })
+                this.http.post('/user/pushFillReport',{ 
+                        ids: ids, date: this.curDate
+                    },
+                    res => {
+                        if (res.code == "ok") {
+                            this.$message({
+                                message: '已发送成功',
+                                type: "success"
+                            });
+                        } 
+                    },
+                    error => {
+                        this.$message({
+                            message: error,
+                            type: "error"
+                        });
+                        }
+                    );
+            },
+            //导出人员列表
+            exportMemb() {
+                if (this.fillMembList.length == 0) return;
+                var ids = '';
+                this.fillMembList.forEach(f=>{
+                    ids += f.id+',';
+                })
+                this.http.post('/user/exportMembList',{ 
+                        ids: ids,isFill: this.isFill, date: this.curDate
+                    },
+                    res => {
+                        if (res.code == "ok") {
+                            var aTag = document.createElement('a');
+                            aTag.download = this.curDate+(this.isFill?"已填":"未填")+"人员列表.xls";
+                            aTag.href = res.data;
+                            aTag.click();
+                        } 
+                    },
+                    error => {
+                        this.$message({
+                            message: error,
+                            type: "error"
+                        });
+                        }
+                    );
+            },
+            showMembList(fill) {
+                this.membListVisible = true;
+                if (fill == 0) {
+                    this.fillMembList = this.unFillList;
+                    this.isFill = false;
+                } else {
+                    this.fillMembList = this.fillList;
+                    this.isFill = true;
+                }
+            },
             //获取自己填写的日报状态
             getReportFillStatus() {
                 this.http.post('/report/getReportFillStatus',{ 
@@ -693,23 +782,26 @@
             },
             // 部门列表点击
             handleNodeClick(data) {
-                // if(this.depData == null || data.id != this.depData.id) {
-                //     this.depData = data;
-                //     //this.getUser();
-                    
-                // }
                 this.depData = data;
+                var list = [];
                 if (data.id == -1) {
                     this.deptId = null;
                     this.targetUid = null;
+                    list = this.data;
                 } else if (data.isUser == 1) {
                     this.deptId = null;
                     this.targetUid = data.id;
                 } else {
                     this.deptId = data.id;
                     this.targetUid = null;
+                    list.push(data);
                 }
                 this.getReportList();
+                if (list.length > 0) {
+                    this.unFillList = this.getUserMembListFromDeptList(list, 0);
+                    this.fillList = this.getUserMembListFromDeptList(list, 1);
+                } 
+                
             },
             
             // 获取部门列表
@@ -739,7 +831,25 @@
                         list[0].membCount = this.membCount;
                         if (this.depData.id == -1) {
                             this.depData.membCount = this.membCount;
+                            this.unFillList = this.getUserMembListFromDeptList(this.data, 0);
+                            this.fillList = this.getUserMembListFromDeptList(this.data, 1);
+                        } else {
+                            if (this.depData.isUser == null) {
+                                var dep = this.findTargetDept(this.data, this.depData.id);
+                                var membDeptList = [];
+                                membDeptList.push(dep);
+                                this.unFillList = this.getUserMembListFromDeptList(membDeptList, 0);
+                                this.fillList = this.getUserMembListFromDeptList(membDeptList, 1);
+                            }
+                        }
+                        if (this.depData.isUser == null) {
+                            if (this.isFill) {
+                                this.fillMembList = this.fillList;
+                            } else {
+                                this.fillMembList = this.unFillList;
+                            }
                         }
+                        
                     } else {
                         this.$message({
                             message: res.msg,
@@ -757,6 +867,57 @@
                 this.getReportFillStatus();
             },
 
+            findTargetDept(list, deptId) {
+                var t = null;
+                for (var i=0;i<list.length; i++) {
+                    if (list[i].isUser == null && list[i].id == deptId) {
+                        t = list[i];
+                        break;
+                    }
+                }
+                if (t == null) {
+                    for (var i=0;i<list.length; i++) {
+                        if (list[i].children != null && list[i].children.length > 0) {
+                            t = this.findTargetDept(list[i].children, deptId);
+                            if (t != null) {
+                                break;
+                            }
+                        }
+                    }
+                }
+                return t;
+            },
+
+            getUserMembListFromDeptList(list, isFill) {
+                var membList = [];
+                for (var i in list) {
+                    var deptName = list[i].label;
+                    if (list[i].userList != null) {
+                        list[i].userList.forEach(element => {
+                            if (isFill == 0) {
+                                //获取未填的
+                                if (element.state == null) {
+                                    var obj = {id: element.id, label:element.name, deptId:element.departmentId, deptName: deptName};
+                                    membList.push(obj);
+                                }
+                            } else {
+                                if (element.state != null) {
+                                    var obj = {id: element.id, label:element.name, deptId:element.departmentId, deptName: deptName};
+                                    membList.push(obj);
+                                }
+                            }
+                            
+                        });
+                    }
+
+                    if (list[i].children != null) {
+                        membList = membList.concat(this.getUserMembListFromDeptList(list[i].children, isFill));
+                    }
+                }
+
+                return membList;
+            },
+
             setUserToDept(list) {
                 for (var i in list) {
                     var cnt = 0;

+ 234 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/workflow/report.vue

@@ -0,0 +1,234 @@
+<template>
+    <section >
+        <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
+            <el-form :inline="true">
+                <el-form-item label="审批流程设置">
+                </el-form-item>
+                <el-form-item  style="float:right">
+                    <el-button  type="primary" @click="submitInsert" :loading="addLoading">保存</el-button>
+                </el-form-item>
+            </el-form>
+        </el-col>
+        <p style="padding-top:80px;margin: 0 0 10px 10px;color:#666;">工时审批流程</p>
+        <div class="panel" style="margin-left:20px;margin-right:20px;">
+          <el-button type="primary">员工填报</el-button>
+          <icon class="iconfont firerock-iconright" ></icon>
+          <el-button type="primary">项目负责人</el-button>
+          <icon class="iconfont firerock-iconright"></icon>
+          <icon class="iconfont firerock-iconInsertLine addNode" @click="showNodeDialog(0)"></icon>
+          <icon class="iconfont firerock-iconright"></icon>
+          <span v-for="(item, index) in dataArray" :key="item.roleId" >
+            <el-button type="primary" @click="editNodeDialog(index, item)">{{item.roleName}}<span v-if="item.userId != null">({{item.userName}})</span></el-button>
+            <icon class="iconfont firerock-iconright"></icon>
+            <icon class="iconfont firerock-iconInsertLine addNode" @click="showNodeDialog(index+1)"></icon>
+            <icon class="iconfont firerock-iconright"></icon>
+          </span>
+
+          <!--结束点 -->
+          <icon class="iconfont firerock-iconApp_New_Line" style="color:#20A0FF;"></icon>
+        </div>
+        <div style="width:80px;margin:0 auto;padding:20px;">
+            <el-button type="primary" @click="submitInsert" :loading="addLoading">保存</el-button>
+        </div>
+        <!--人员列表 -->
+        <el-dialog  title="请选择审批角色" v-if="dialogVisible" :visible.sync="dialogVisible"  width="400px">
+              <el-form label-width="80px">
+              <el-form-item label="角色" >
+                  <el-select style="width:100%;" v-model="curRoleId" >
+                    <el-option v-for="item in roleArray"  :label="item.label"  :value="item.value" :key="item.name">
+                        {{item.label}}
+                    </el-option>
+                  </el-select>
+              </el-form-item>
+              <el-form-item label="指定人员" v-if="curRoleId==4">
+                  <el-select style="width:100%;" v-model="curUserId" >
+                    <el-option v-for="item in userList"  :label="item.name"  :value="item.id" :key="item.id">
+                        {{item.name}}
+                    </el-option>
+                  </el-select>
+              </el-form-item>
+              </el-form>
+
+            <div slot="footer" class="dialog-footer">
+              <el-button type="default" @click="deleteNode" v-if="!isAdd" style="float:left;">删除</el-button>
+                <el-button type="primary" @click="addNode" >确定</el-button>
+            </div>
+        </el-dialog>
+    </section>
+</template>
+<script>
+    import util from "../../common/js/util";
+
+    export default {
+        data() {
+            return {
+                isAdd: false,
+                dataArray:[],
+                curRoleId:null,
+                curUserId: null,
+                index:0,
+                roleArray:[
+                {label:"项目管理员",value:5},
+                {label:"部门主管",value:6},
+                {label:"人事管理员",value:4},
+                ],
+                dialogVisible:false,
+                editNode:{},
+                user: JSON.parse(sessionStorage.getItem("user")),
+                userList:[],
+            };
+        },
+        methods: {
+            deleteNode() {
+              this.dialogVisible = false;
+              this.dataArray.splice(this.index, 1);
+            },
+            addNode() {
+              this.dialogVisible = false;
+              if (this.curRoleId == null) return;
+              var label = this.roleArray.filter(r=>r.value == this.curRoleId)[0].label;
+              if (this.isAdd) {
+                var node = {roleId: this.curRoleId, roleName: label};
+                if (this.curUserId != null) {
+                  node.userId = this.curUserId;
+                  node.userName = this.userList.filter(u=>u.id == node.userId)[0].name;
+                }
+                this.dataArray.splice(this.index, 0, node);
+              } else {
+                //编辑
+                this.dataArray[this.index].roleId = this.curRoleId;
+                this.dataArray[this.index].roleName = label;
+                this.dataArray[this.index].userId = this.curUserId;
+                let uid = this.curUserId;
+                console.log(uid);
+                if (uid != null) {
+                  this.dataArray[this.index].userName = this.userList.filter(u=>u.id == uid)[0].name;
+                } else {
+                  this.dataArray[this.index].userName = null;
+                }
+              }
+            },
+            editNodeDialog(index, item) {
+                this.isAdd = false;
+                this.index = index;
+                this.curUserId = item.userId;
+                this.dialogVisible = true;
+                this.curRoleId = item.roleId;
+            },
+            showNodeDialog(index) {
+              this.isAdd = true;
+              this.index = index;
+              this.curRoleId = null;
+              this.curUserId = null;
+              this.dialogVisible = true;
+            },
+            
+            getHRList() {
+              this.http.post('/user/getHRList',{},
+                            res => {
+                                this.listLoading = false;
+                                if (res.code == "ok") {
+                                    this.userList = res.data;
+                                } else {
+                                    this.$message({
+                                        message: res.msg,
+                                        type: "error"
+                                    });
+                                }
+                            },
+                            error => {
+                                this.listLoading = false;
+                                this.$message({
+                                    message: error,
+                                    type: "error"
+                                });
+                                }
+                            );
+            },
+            submitInsert() {
+                this.http.post('/audit-workflow-time-setting/add',{json:JSON.stringify(this.dataArray)},
+                            res => {
+                                this.listLoading = false;
+                                if (res.code == "ok") {
+                                    this.$message({
+                                        message: '保存成功',
+                                        type: "success"
+                                    });
+                                } else {
+                                    this.$message({
+                                        message: res.msg,
+                                        type: "error"
+                                    });
+                                }
+                            },
+                            error => {
+                                this.listLoading = false;
+                                this.$message({
+                                    message: error,
+                                    type: "error"
+                                });
+                                }
+                            );
+            },
+
+            // 获取本公司的工时日报审批流程设置
+            getSettings() {
+                this.http.post('/audit-workflow-time-setting/get',{},
+                    res => {
+                        this.listLoading = false;
+                        if (res.code == "ok") {
+                            this.dataArray = res.data;
+                        } else {
+                            this.$message({
+                                message: res.msg,
+                                type: "error"
+                            });
+                        }
+                    },
+                    error => {
+                        this.listLoading = false;
+                        this.$message({
+                            message: error,
+                            type: "error"
+                        });
+                        }
+                    );
+            },
+
+        },
+        created() {
+            let height = window.innerHeight;
+            this.tableHeight = height - 195;
+            const that = this;
+            window.onresize = function temp() {
+                that.tableHeight = window.innerHeight - 195;
+            };
+        },
+        mounted() {
+            this.getHRList();
+            this.getSettings();
+        }
+    };
+</script>
+
+<style lang="scss" scoped>
+.addNode {
+  cursor:pointer;
+}
+.addNode:hover {
+  color:#20a0ff;
+}
+
+.panel {
+    padding:50px 15px ;box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
+    
+}
+.sample {
+    margin-top:30px;
+    color: #999;
+}
+.tip {
+    margin-left:10px; color:gray;
+    
+}
+</style>

+ 22 - 0
fhKeeper/formulahousekeeper/timesheet_h5/public/index.html

@@ -12,6 +12,27 @@
 
     <meta name="wpk-bid" content="dta_2_71020"> <script>    !(function(c,i,e,b){var h=i.createElement("script");var f=i.getElementsByTagName("script")[0];h.type="text/javascript";h.crossorigin=true;h.onload=function(){c[b]||(c[b]=new c.wpkReporter({bid:"dta_2_71020"}));c[b].installAll()};f.parentNode.insertBefore(h,f);h.src=e})(window,document,"https://g.alicdn.com/woodpeckerx/jssdk??wpkReporter.js","__wpk");</script>
     <meta name="wpk-bid" content="dta_2_71020"> <script>    !(function(c,i,e,b){var h=i.createElement("script");var f=i.getElementsByTagName("script")[0];h.type="text/javascript";h.crossorigin=true;h.onload=function(){c[b]||(c[b]=new c.wpkReporter({bid:"dta_2_71020"}));c[b].installAll()};f.parentNode.insertBefore(h,f);h.src=e})(window,document,"https://g.alicdn.com/woodpeckerx/jssdk??wpkReporter.js","__wpk");</script>
+    <script>
+        function IsPC() {
+            var userAgentInfo = navigator.userAgent;
+            var Agents = ["Android", "iPhone",
+                        "SymbianOS", "Windows Phone",
+                        "iPad", "iPod"];
+            var flag = true;
+            for (var v = 0; v < Agents.length; v++) {
+                if (userAgentInfo.indexOf(Agents[v]) > 0) {
+                    flag = false;
+                    break;
+                }
+            }
+            return flag;
+        }
+        var flag = IsPC(); //true为PC端,false为手机端
+        if (flag) {
+            //跳转到PC登录页面
+            location.href = 'https://worktime.ttkuaiban.com';
+        }
+    </script>
 </head>
 
 <body>
@@ -19,6 +40,7 @@
         <strong>非常抱歉,网页丢了</strong>
     </noscript>
     <div id="app"></div>
+    
 </body>
 
 </html>