finance.vue 79 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581
  1. <template>
  2. <section>
  3. <!--工具条-->
  4. <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
  5. <el-form :inline="true">
  6. <!-- <el-form-item label="财务核算成本 | 月份选择" style="margin-top:5px;"> -->
  7. <el-form-item label="月份选择" >
  8. <el-date-picker size="small" v-model="date" :editable="false" format="yyyy-MM" value-format="yyyy-MM" @change="changeMonth" :clearable="false" type="month" placeholder="选择月份" style="margin-right: 20px"></el-date-picker>
  9. <el-link type="primary" :underline="false" @click="audits()" v-if="user.timeType.financeAudit == '1'">{{revaelse}}</el-link>
  10. </el-form-item>
  11. <!-- <el-radio-group v-model="radio" @change="switchList" style="margin-left:160px;margin-top:5px;"> -->
  12. <el-radio-group size="small" v-model="radio" @change="switchList" style="margin-left:150px;margin-top:5px;">
  13. <el-radio-button label="全部人员" >全部人员({{allFinanceList.length}})</el-radio-button>
  14. <el-radio-button label="无项目工时人员">无项目工时人员({{noReportUserList.length}})</el-radio-button>
  15. </el-radio-group>
  16. <el-form-item v-if="permissions.financialProportion" style="margin-left:5px;">
  17. <el-link type="primary" :underline="false" @click="showSettingDialog()" >分摊比例设置</el-link>
  18. </el-form-item>
  19. <el-form-item style="float:right;" v-if="permissions.financialUpload">
  20. <el-link type="primary" :underline="false" @click="getTemplate()" >模板下载</el-link>
  21. </el-form-item>
  22. <!-- <el-form-item style="float:right;">
  23. <el-upload ref="upload" action="#" :limit="1" :http-request="importFinance" :show-file-list="false">
  24. <el-link type="primary" :underline="false" >财务数据上传</el-link>
  25. </el-upload>
  26. </el-form-item> -->
  27. <el-form-item style="float:right;" v-if="permissions.financialUpload">
  28. <el-link type="primary" :underline="false" @click="importDialog = true;isUploading=false;">数据上传</el-link>
  29. </el-form-item>
  30. <el-form-item style="float:right;" v-if="permissions.financialExport">
  31. <el-link type="primary" :underline="false" @click="exportDialog = true;exportMonth = date;">数据导出</el-link>
  32. </el-form-item>
  33. <el-form-item style="float:right;" v-if="permissions.financialCustom">
  34. <el-link type="primary" :underline="false" @click="showItemDialog()">自定义薪资项</el-link>
  35. </el-form-item>
  36. <el-form-item style="float:right;" v-if="user.timeType.financeAudit == '1' && permissions.setFinanceAuditor">
  37. <el-link type="primary" :underline="false" @click="reviewerVisible = true">设置审核人</el-link>
  38. </el-form-item>
  39. </el-form>
  40. </el-col>
  41. <!-- 上传记录 -->
  42. <el-dialog title="薪资上传记录" :visible.sync="xzImportVisible" width="1100px" :before-close="handleClose">
  43. <div>
  44. <el-table :data="xzList" style="width: 100%" :height="400">
  45. <el-table-column prop="userName" label="操作人"></el-table-column>
  46. <el-table-column prop="ymonth" label="所属月份"></el-table-column>
  47. <el-table-column prop="fileName" label="文件名">
  48. <template slot-scope="scope">
  49. <div>
  50. <el-link type="primary" @click="downloadByA({name:scope.row.fileName,url:scope.row.serverName})"> {{scope.row.fileName}}</el-link>
  51. </div>
  52. </template>
  53. </el-table-column>
  54. <el-table-column prop="recoverReport" label="是否覆盖日报成本" width="150">
  55. <template slot-scope="scope">
  56. <div>
  57. {{scope.row.recoverReport == 1? '是' : '否'}}
  58. </div>
  59. </template>
  60. </el-table-column>
  61. <el-table-column prop="recoverMonthcost" label="是否覆盖人员月成本" width="150">
  62. <template slot-scope="scope">
  63. <div>
  64. {{scope.row.recoverMonthcost == 1? '是' : '否'}}
  65. </div>
  66. </template>
  67. </el-table-column>
  68. <el-table-column prop="indate" label="上传时间"></el-table-column>
  69. <!-- <el-table-column prop="date" label="操作" v-if="(tabPosition == 1 || tabPosition == 0) && (reviewerRuleForm.auditorId == user.id || user.role == 1 || user.role == 2)">
  70. <template slot-scope="scope">
  71. <div>
  72. <el-button type="primary" size="small" v-if="tabPosition == 0" @click="operationList(0, scope.row.id)">通过</el-button>
  73. <el-button type="warning" size="small" v-if="tabPosition == 0" @click="operationList(1, scope.row.id)">驳回</el-button>
  74. <el-button type="warning" size="small" v-if="tabPosition == 1" @click="operationList(2, scope.row.id)">撤销</el-button>
  75. </div>
  76. </template>
  77. </el-table-column> -->
  78. </el-table>
  79. </div>
  80. </el-dialog>
  81. <!-- 财务报表审核 -->
  82. <el-dialog :title="shenhe" :visible.sync="importVisible" width="1100px" :before-close="handleClose">
  83. <div>
  84. <el-radio-group v-model="tabPosition" style="margin-bottom: 20px;" @change="operationalData()">
  85. <el-radio-button label="1">已通过</el-radio-button>
  86. <el-radio-button label="0">待审核</el-radio-button>
  87. <el-radio-button label="2">已驳回</el-radio-button>
  88. <el-radio-button label="-1">已撤销</el-radio-button>
  89. </el-radio-group>
  90. <el-table :data="reviewLis" style="width: 100%" :height="400">
  91. <el-table-column prop="userName" label="操作人"></el-table-column>
  92. <el-table-column prop="ymonth" label="所属月份"></el-table-column>
  93. <el-table-column prop="fileName" label="文件名">
  94. <template slot-scope="scope">
  95. <div>
  96. <el-link type="primary" @click="downloadByA({name:scope.row.fileName,url:scope.row.serverName})"> {{scope.row.fileName}}</el-link>
  97. </div>
  98. </template>
  99. </el-table-column>
  100. <el-table-column prop="recoverReport" label="是否覆盖日报成本" width="150">
  101. <template slot-scope="scope">
  102. <div>
  103. {{scope.row.recoverReport == 1? '是' : '否'}}
  104. </div>
  105. </template>
  106. </el-table-column>
  107. <el-table-column prop="recoverMonthcost" label="是否覆盖人员月成本" width="150">
  108. <template slot-scope="scope">
  109. <div>
  110. {{scope.row.recoverMonthcost == 1? '是' : '否'}}
  111. </div>
  112. </template>
  113. </el-table-column>
  114. <el-table-column prop="indate" label="上传时间"></el-table-column>
  115. <el-table-column prop="date" label="操作" v-if="(tabPosition == 1 || tabPosition == 0) && (reviewerRuleForm.auditorId == user.id)">
  116. <template slot-scope="scope">
  117. <div>
  118. <el-button type="primary" size="small" v-if="tabPosition == 0" @click="operationList(0, scope.row.id)">通过</el-button>
  119. <el-button type="warning" size="small" v-if="tabPosition == 0" @click="operationList(1, scope.row.id)">驳回</el-button>
  120. <el-button type="warning" size="small" v-if="tabPosition == 1" @click="operationList(2, scope.row.id)">撤销</el-button>
  121. </div>
  122. </template>
  123. </el-table-column>
  124. </el-table>
  125. </div>
  126. </el-dialog>
  127. <!-- 设置审核人弹窗 -->
  128. <el-dialog title="设置审核人" :visible.sync="reviewerVisible" width="350px" :before-close="handleCloses">
  129. <el-form :model="reviewerRuleForm" ref="reviewerRuleForm" label-width="100px" class="demo-ruleForm">
  130. <el-form-item label="选择审核人" prop="auditorId" :rules="{required: true, message: '审核人不能为空', trigger: 'blur'}">
  131. <el-select v-model="reviewerRuleForm.auditorId" clearable placeholder="请选择审核人" >
  132. <el-option v-for="(item, index) in people" :key="index" :label="item.name" :value="item.id"></el-option>
  133. </el-select>
  134. </el-form-item>
  135. <el-form-item>
  136. <el-button type="primary" @click="submitreviewerRuleForm('reviewerRuleForm')">提交</el-button>
  137. </el-form-item>
  138. </el-form>
  139. </el-dialog>
  140. <el-dialog title="财务数据导出" v-if="exportDialog" :visible.sync="exportDialog" :close-on-click-modal="false" customClass="customWidth" width="400px">
  141. <el-form ref="form3" >
  142. <el-form-item label="导出月份" >
  143. <!-- <div style="color:orange;">{{date}}</div> -->
  144. <el-date-picker v-model="exportMonth" type="month" placeholder="选择月份" format="yyyy-MM" value-format="yyyy-MM" style="width:280px;"></el-date-picker>
  145. </el-form-item>
  146. </el-form>
  147. <div slot="footer" class="dialog-footer">
  148. <el-button type="primary" style="width:100%;" :loading="isUploading" @click="exportFinance">导出</el-button>
  149. </div>
  150. </el-dialog>
  151. <!--列表-->
  152. <!-- 222 -->
  153. <el-table :data="list" highlight-current-row v-loading="listLoading"
  154. :show-summary='user.timeType.isSecretSalary==0?true:false'
  155. ref="table"
  156. :height="300" style="width: 100%;">
  157. <el-table-column prop="name" label="姓名" sortable width="150"></el-table-column>
  158. <el-table-column v-if="user.timeType.isSecretSalary==0" :prop="headerCols[index]" :label="item" sortable show-overflow-tooltip v-for="(item, index) in tblCols" :key="index" width="130px" align="center">
  159. </el-table-column>
  160. <el-table-column v-if="user.timeType.isSecretSalary==1" :label="item" sortable show-overflow-tooltip v-for="(item, index) in tblCols" :key="index" width="130px" align="center">
  161. <template slot-scope="scope" >
  162. *
  163. </template>
  164. </el-table-column>
  165. <el-table-column prop="totalCost" label="总成本">
  166. <template slot-scope="scope" >
  167. {{user.timeType.isSecretSalary==0?scope.row.totalCost:'*'}}
  168. </template>
  169. </el-table-column>
  170. </el-table>
  171. <el-form :inline="true" >
  172. <el-form-item >
  173. <!-- <el-checkbox style="margin-left:10px;" v-model="assignNoProUser" @click="assignToProject">均摊无项目人员成本</el-checkbox> -->
  174. <!-- <el-button type="primary" :underline="false" size="small" @click="assignNoProUser=false;assignToProject();" style="margin-left:10px;">分摊已填工时人员成本</el-button>
  175. <el-button type="primary" :underline="false" size="small" @click="assignNoProUser=true;assignToProject();" style="margin-left:10px;">分摊全部人员成本</el-button> -->
  176. <el-radio-group size="small" v-model="costListRadio" @change="switchCostList" style="margin-left:5px;margin-top:5px;">
  177. <el-radio-button label="1" >分摊已填工时人员成本</el-radio-button>
  178. <el-radio-button label="2">分摊全部人员成本</el-radio-button>
  179. </el-radio-group>
  180. </el-form-item>
  181. <el-form-item style="float:right;margin-right:20px;" v-if="permissions.financialShare">
  182. <el-link type="primary" :underline="false" @click="exportFinanceDialog=true">导出分摊数据</el-link>
  183. </el-form-item>
  184. <!-- <el-form-item style="float:right;margin-right:30px;" v-if="hasNoProjectUsers">
  185. <el-link type="primary" :underline="false" @click="showNoProjectUsers">查看无项目数据</el-link>
  186. </el-form-item> -->
  187. </el-form>
  188. <!-- 图表 -->
  189. <!-- <div id="container" :style="'height:300px;width:'+ widthHtval+'px;'"></div> -->
  190. <div id="clearfix" :style="'overflow-x: auto;width:100%;padding-bottom: 100px; position: relative; height:300px;'">
  191. <div id="container" :style="'height: 300px;width:100%;'"></div>
  192. </div>
  193. <!--新增界面-->
  194. <el-dialog :title="title" v-if="addFormVisible" :visible.sync="addFormVisible" :close-on-click-modal="false" customClass="customWidth" width="600px">
  195. <el-form ref="form1" :model="addForm" :rules="rules" label-width="100px">
  196. <el-form-item label="项目编号" >
  197. <el-input v-model="addForm.code" placeholder="请输入项目编号" clearable></el-input>
  198. </el-form-item>
  199. <el-form-item label="项目名称" prop="name">
  200. <el-input v-model="addForm.name" placeholder="请输入项目名称" clearable></el-input>
  201. </el-form-item>
  202. <el-form-item label="全部参与者">
  203. <el-select v-model="addForm.userId" multiple filterable placeholder="请选择参与者" style="width:100%;" @change="changeParticipator">
  204. <el-option v-for="item in users" :key="item.id" :label="item.name" :value="item.id"></el-option>
  205. </el-select>
  206. </el-form-item>
  207. <el-form-item label="主要负责人" >
  208. <el-select v-model="addForm.inchargerId" :disabled="addForm.userId.length==0" filterable placeholder="请选择负责人" style="width:100%;" @change="changeIncharger">
  209. <el-option v-for="item in participator" :key="item.id" :label="item.name" :value="item.id"></el-option>
  210. </el-select>
  211. </el-form-item>
  212. </el-form>
  213. <div slot="footer" class="dialog-footer">
  214. <el-button @click.native="addFormVisible = false">取消</el-button>
  215. <el-button type="primary" @click="submitInsert" :loading="addLoading">提交</el-button>
  216. </div>
  217. </el-dialog>
  218. <!--用户详细信息弹出框-->
  219. <el-dialog title="查看详情" v-if="userDetailVisible" :visible.sync="userDetailVisible" :close-on-click-modal="false" customClass="customWidth" width="400px">
  220. <div class="line"><span>姓名</span><span>{{userDetail.name}}</span></div>
  221. <div class="line"><span>手机号码</span><span>{{userDetail.phone}}</span></div>
  222. <div class="line"><span>部门</span><span>{{userDetail.departmentName}}</span></div>
  223. <div class="line"><span>成本</span><span>{{userDetail.cost}}元/小时</span></div>
  224. <div slot="footer" class="dialog-footer">
  225. <el-button type="primary" @click="userDetailVisible = false" >确定</el-button>
  226. </div>
  227. </el-dialog>
  228. <!--导入时的设置界面 -->
  229. <el-dialog title="财务数据导入" v-if="importDialog" :visible.sync="importDialog" :close-on-click-modal="false" customClass="customWidth" width="500px">
  230. <el-form ref="form3" :model="importParam" >
  231. <el-form-item label="导入月份" >
  232. <!-- <div style="color:orange;">{{date}}</div> -->
  233. <el-date-picker v-model="date" type="month" placeholder="选择月份" format="yyyy-MM" value-format="yyyy-MM"></el-date-picker>
  234. </el-form-item>
  235. <el-form-item prop="syncHistoryReport" >
  236. <el-checkbox label="重新计算该月已填日报成本" v-model="importParam.syncHistoryReport"></el-checkbox>
  237. </el-form-item>
  238. <el-form-item prop="syncUserCost" >
  239. <el-checkbox label="同步到组织架构中员工月薪成本" v-model="importParam.syncUserCost" ></el-checkbox>
  240. </el-form-item>
  241. </el-form>
  242. <div slot="footer" class="dialog-footer">
  243. <el-link v-if="user.timeType.financeAudit == '0'"
  244. style="float:left;"
  245. type="primary" :underline="false" @click="xzjl(),xzImportVisible = true">查看导入历史记录</el-link>
  246. <el-upload ref="upload" action="#" :limit="1" :http-request="importFinance" :show-file-list="false" >
  247. <el-button type="primary" style="width:100%;" :loading="isUploading" >选择文件并开始导入</el-button>
  248. </el-upload>
  249. </div>
  250. </el-dialog>
  251. <!--无项目人员列表-->
  252. <!-- <el-dialog title="无项目人员列表" v-if="showNPDialog" :visible.sync="showNPDialog" :close-on-click-modal="false" customClass="customWidth" width="1200px">
  253. <el-table :data="npUserList" highlight-current-row v-loading="listLoading"
  254. show-summary=true
  255. ref="table"
  256. :height="400" style="width: 100%;">
  257. <el-table-column prop="name" label="姓名" sortable width="150"></el-table-column>
  258. <el-table-column prop="monthCost" label="工资" width="150"></el-table-column>
  259. <el-table-column prop="bonus" label="奖金" ></el-table-column>
  260. <el-table-column prop="allowance" label="津贴" ></el-table-column>
  261. <el-table-column prop="insuranceOld" label="养老保险" ></el-table-column>
  262. <el-table-column prop="insuranceMedical" label="医疗保险" ></el-table-column>
  263. <el-table-column prop="insuranceLosejob" label="失业保险" ></el-table-column>
  264. <el-table-column prop="insuranceInjury" label="工伤保险" ></el-table-column>
  265. <el-table-column prop="houseFund" label="住房公积金" ></el-table-column>
  266. <el-table-column prop="others" label="其他" ></el-table-column>
  267. <el-table-column :label="item.fieldName" v-for="(item, index) in customCols" :key="item.id" :prop="index==0?'customField1':(index==1?'customField2':(index==2?'customField3':''))">
  268. <template slot-scope="scope">
  269. {{index==0?scope.row.customField1:(index==1?scope.row.customField2:(index==2?scope.row.customField3:''))}}
  270. </template>
  271. </el-table-column>
  272. <el-table-column prop="totalCost" label="总成本" ></el-table-column>
  273. </el-table>
  274. <div slot="footer" class="dialog-footer">
  275. <div style="float:left;color:#ff9900;">*以上人员当月尚无投入的项目,请提醒他们填写日报。</div>
  276. <el-button type="primary" @click="showNPDialog = false" >关闭</el-button>
  277. </div>
  278. </el-dialog> -->
  279. <el-dialog title="自定义薪资项" show-header="false" v-if="itemDialog" :visible.sync="itemDialog" :close-on-click-modal="false" customClass="customWidth" width="500px" top="20px">
  280. <div style="margin-left:30px;">
  281. <!-- 111 -->
  282. <p><el-input size="medium" v-model.trim="customCols.monthCost" placeholder="请输入自定义薪资项名称" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  283. <template v-if="customCols.monthCost != null && customCols.monthCost != ''">
  284. 计入总成本
  285. <el-radio size="medium" v-model="customCols.monthCostCalculate" :label="1" style="margin-right:10px;margin-left:10px">是</el-radio>
  286. <el-radio size="medium" v-model="customCols.monthCostCalculate" :label="0">否</el-radio>
  287. </template>
  288. </p>
  289. <p><el-input size="medium" v-model.trim="customCols.bonus" placeholder="请输入自定义薪资项名称" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  290. <template v-if="customCols.bonus != null && customCols.bonus != ''">
  291. 计入总成本
  292. <el-radio size="medium" v-model="customCols.bonusCalculate" :label="1" style="margin-right:10px;margin-left:10px">是</el-radio>
  293. <el-radio size="medium" v-model="customCols.bonusCalculate" :label="0">否</el-radio>
  294. </template>
  295. </p>
  296. <p><el-input size="medium" v-model.trim="customCols.allowance" placeholder="请输入自定义薪资项名称" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  297. <template v-if="customCols.allowance != null && customCols.allowance != ''">
  298. 计入总成本
  299. <el-radio size="medium" v-model="customCols.allowanceCalculate" :label="1" style="margin-right:10px;margin-left:10px">是</el-radio>
  300. <el-radio size="medium" v-model="customCols.allowanceCalculate" :label="0">否</el-radio>
  301. </template>
  302. </p>
  303. <p><el-input size="medium" v-model.trim="customCols.insuranceOld" placeholder="请输入自定义薪资项名称" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  304. <template v-if="customCols.insuranceOld != null && customCols.insuranceOld != ''">
  305. 计入总成本
  306. <el-radio size="medium" v-model="customCols.insuranceOldCalculate" :label="1" style="margin-right:10px;margin-left:10px">是</el-radio>
  307. <el-radio size="medium" v-model="customCols.insuranceOldCalculate" :label="0">否</el-radio>
  308. </template>
  309. </p>
  310. <p><el-input size="medium" v-model.trim="customCols.insuranceMedical" placeholder="请输入自定义薪资项名称" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  311. <template v-if="customCols.insuranceMedical != null && customCols.insuranceMedical != ''">
  312. 计入总成本
  313. <el-radio size="medium" v-model="customCols.insuranceMedicalCalculate" :label="1" style="margin-right:10px;margin-left:10px">是</el-radio>
  314. <el-radio size="medium" v-model="customCols.insuranceMedicalCalculate" :label="0">否</el-radio>
  315. </template>
  316. </p>
  317. <p><el-input size="medium" v-model.trim="customCols.insuranceLosejob" placeholder="请输入自定义薪资项名称" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  318. <template v-if="customCols.insuranceLosejob != null && customCols.insuranceLosejob != ''">
  319. 计入总成本
  320. <el-radio size="medium" v-model="customCols.insuranceLosejobCalculate" :label="1" style="margin-right:10px;margin-left:10px">是</el-radio>
  321. <el-radio size="medium" v-model="customCols.insuranceLosejobCalculate" :label="0">否</el-radio>
  322. </template>
  323. </p>
  324. <p><el-input size="medium" v-model.trim="customCols.insuranceInjury" placeholder="请输入自定义薪资项名称" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  325. <template v-if="customCols.insuranceInjury != null && customCols.insuranceInjury != ''">
  326. 计入总成本
  327. <el-radio size="medium" v-model="customCols.insuranceInjuryCalculate" :label="1" style="margin-right:10px;margin-left:10px">是</el-radio>
  328. <el-radio size="medium" v-model="customCols.insuranceInjuryCalculate" :label="0">否</el-radio>
  329. </template>
  330. </p>
  331. <p><el-input size="medium" v-model.trim="customCols.houseFund" placeholder="请输入自定义薪资项名称" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  332. <template v-if="customCols.houseFund != null && customCols.houseFund != ''">
  333. 计入总成本
  334. <el-radio size="medium" v-model="customCols.houseFundCalculate" :label="1" style="margin-right:10px;margin-left:10px">是</el-radio>
  335. <el-radio size="medium" v-model="customCols.houseFundCalculate" :label="0">否</el-radio>
  336. </template>
  337. </p>
  338. <p><el-input size="medium" v-model.trim="customCols.field1" placeholder="请输入自定义薪资项1名称" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  339. <template v-if="customCols.field1 != null && customCols.field1 != ''">
  340. 计入总成本
  341. <el-radio size="medium" v-model="customCols.field1Calculate" :label="1" style="margin-right:10px;margin-left:10px">是</el-radio>
  342. <el-radio size="medium" v-model="customCols.field1Calculate" :label="0">否</el-radio>
  343. </template>
  344. </p>
  345. <p><el-input size="medium" v-model.trim="customCols.field2" placeholder="请输入自定义薪资项2名称" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  346. <template v-if="customCols.field2 != null && customCols.field2 != ''">
  347. 计入总成本
  348. <el-radio size="medium" v-model="customCols.field2Calculate" :label="1" style="margin-right:10px;margin-left:10px">是</el-radio>
  349. <el-radio size="medium" v-model="customCols.field2Calculate" :label="0">否</el-radio>
  350. </template>
  351. </p>
  352. <p><el-input size="medium" v-model.trim="customCols.field3" placeholder="请输入自定义薪资项3名称" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  353. <template v-if="customCols.field3 != null && customCols.field3 != ''">
  354. 计入总成本
  355. <el-radio size="medium" v-model="customCols.field3Calculate" :label="1" style="margin-right:10px;margin-left:10px">是</el-radio>
  356. <el-radio size="medium" v-model="customCols.field3Calculate" :label="0">否</el-radio>
  357. </template>
  358. </p>
  359. </div>
  360. <div slot="footer" class="dialog-footer">
  361. <el-button type="primary" @click="itemDialog = false" >关闭</el-button>
  362. <el-button type="primary" @click="saveItems()" >保存</el-button>
  363. </div>
  364. </el-dialog>
  365. <el-dialog :title="date+'月 无项目工时人员分摊比例设置'" show-header="false" v-if="settingDialog" :visible.sync="settingDialog"
  366. :close-on-click-modal="false" customClass="customWidth" width="1200px">
  367. <div>
  368. <div>
  369. <el-button :disabled="multipleSelection.length==0" @click="setPercent(true, null)">批量设置比例</el-button>
  370. <el-button :disabled="projectCols.length==0 || userCostSettingList.length == 0" @click="getLastMonthSetting">使用上月比例设置</el-button>
  371. <el-button @click="showSelectProjectDialog">管理待分摊项目</el-button>
  372. <el-button @click="intoAmortizationRatio">导入分摊比例</el-button>
  373. </div>
  374. <el-table :data="userCostSettingList" highlight-current-row v-loading="costSettingLoading"
  375. ref="settingTable" @selection-change="handleSelectionChange"
  376. :height="400" style="width: 100%;">
  377. <el-table-column type="selection" width="55"></el-table-column>
  378. <el-table-column prop="name" label="姓名" sortable width="90" fixed="left"></el-table-column>
  379. <el-table-column :label="item.projectName" v-for="(item) in projectCols" width="180" size="small"
  380. :key="item.id" align="center">
  381. <template slot-scope="scope">
  382. <span>{{scope.row[item.projectId]}}</span>%
  383. </template>
  384. </el-table-column>
  385. <el-table-column label="设置比例" width="80" fixed="right">
  386. <template slot-scope="scope">
  387. <el-button size="small" @click="setPercent(false,scope.row)">设置</el-button>
  388. </template>
  389. </el-table-column>
  390. </el-table>
  391. </div>
  392. <div slot="footer" class="dialog-footer">
  393. <el-button type="primary" @click="settingDialog = false" >关闭</el-button>
  394. <el-button type="primary" @click="saveMonthSetting()" >保存</el-button>
  395. </div>
  396. </el-dialog>
  397. <el-dialog title="待分摊项目选择" show-header="false" v-if="projectsDialog" :visible.sync="projectsDialog"
  398. :close-on-click-modal="false" customClass="customWidth" width="1000px">
  399. <el-select v-model="chosenProjects" multiple filterable clearable style="width:100%">
  400. <el-option v-for="item in allProjectList" :label="item.projectName" :key="item.id" :value="item.id"></el-option>
  401. </el-select>
  402. <div slot="footer" class="dialog-footer">
  403. <el-button type="default" @click="projectsDialog = false" >关闭</el-button>
  404. <el-button type="primary" @click="saveProjectSetting()" >确定</el-button>
  405. </div>
  406. </el-dialog>
  407. <el-dialog title="导入分摊比例数据" v-if="intoAmortizationDialog" :visible.sync="intoAmortizationDialog" customClass="customWidth" width="500px">
  408. <p>1. 下载
  409. <el-link type="primary" style="margin-left:5px;" :underline="false" href="./upload/员工项目分摊比例导入模板.xlsx" download="员工项目分摊比例导入模板.xlsx">员工项目分摊比例导入模板.xlsx</el-link>
  410. </p>
  411. <p>2. 填写excel模板,请确保模板中的项目和人员已添加到系统中。</p>
  412. <p style="display: flex;justify-content: center;padding:1em 0">
  413. <el-upload ref="upload" action="#" :limit="1" :http-request="batchImportData" :show-file-list="false">
  414. <el-button type="primary" :underline="false" :loading="importingData">开始导入</el-button>
  415. </el-upload>
  416. </p>
  417. </el-dialog>
  418. <el-dialog title="设置员工成本各项目占比" show-header="false" v-if="setPercentDialog" :visible.sync="setPercentDialog"
  419. :close-on-click-modal="false" customClass="customWidth" width="600px" >
  420. <div style="margin:0px 10px 10px 10px;">
  421. <span>选择员工</span>
  422. <el-select v-model="chosenNoReportUserIds" multiple filterable clearable style="width:330px;" collapse-tags>
  423. <el-option v-for="item in noReportUserList" :label="item.name" :key="item.id" :value="item.userId"></el-option>
  424. </el-select>
  425. <el-button @click="averageCost" >自动分摊</el-button>
  426. </div>
  427. <el-divider ></el-divider>
  428. <!--项目列表 -->
  429. <el-form v-model="curPercentVal" label-width="365px" style="margin-top:10px;">
  430. <div class="nameList">
  431. <el-form-item v-for="item in projectCols" :label="item.projectName" :key="item.projectId" >
  432. 占比: <el-input v-model="curPercentVal[item.projectId]" style="width:100px;" @input="updatePercentValue"></el-input>&nbsp;%
  433. </el-form-item>
  434. </div>
  435. <el-form-item >
  436. 总比例: {{totalPercent}}&nbsp;%
  437. </el-form-item>
  438. </el-form>
  439. <div slot="footer" class="dialog-footer">
  440. <el-button type="default" @click="setPercentDialog = false" >关闭</el-button>
  441. <el-button type="primary" @click="setPercentSetting()" >确定</el-button>
  442. </div>
  443. </el-dialog>
  444. <!-- 导入结果说明 -->
  445. <el-dialog title="分摊比例导入结果" v-if="showImportResult" :visible.sync="showImportResult" customClass="customWidth" width="500px">
  446. <div>
  447. <span>{{importResultMsg}}</span>
  448. </div>
  449. <span slot="footer" class="dialog-footer">
  450. <el-button type="primary" @click="showImportResult=false">确定</el-button>
  451. </span>
  452. </el-dialog>
  453. <el-dialog title="分摊数据导出" v-if="exportFinanceDialog" :visible.sync="exportFinanceDialog" :close-on-click-modal="false" customClass="customWidth" width="500px">
  454. <div style="margin:30px;">
  455. <el-radio-group v-model="groupByCategory" >
  456. <el-radio :label="0">按项目导出</el-radio>
  457. <el-radio :label="1">按项目分类导出</el-radio>
  458. </el-radio-group>
  459. </div>
  460. <div slot="footer" class="dialog-footer">
  461. <el-button @click="exportData" :loading="exportDataProcessing" type="primary">导出</el-button>
  462. </div>
  463. </el-dialog>
  464. </section>
  465. </template>
  466. <style scoped>
  467. .line {
  468. padding:10px;
  469. }
  470. .line span{
  471. font-size:18px;
  472. }
  473. .line span:nth-child(even){
  474. float:right;
  475. }
  476. </style>
  477. <style>
  478. .customWidth .el-dialog__body{
  479. padding-top: 0;
  480. padding-bottom: 0;
  481. }
  482. </style>
  483. <script>
  484. import { error } from 'dingtalk-jsapi';
  485. import util from "../../common/js/util";
  486. export default {
  487. data() {
  488. return {
  489. groupByCategory:0,
  490. exportFinanceDialog:false,
  491. exportMonth:null,
  492. exportDialog:false,
  493. headerCols:['monthCost','bonus', 'allowance', 'insuranceOld', 'insuranceMedical', 'insuranceLosejob', 'insuranceInjury', 'houseFund', 'customField1','customField2','customField3'],
  494. tblCols:[],
  495. costListRadio: 0,
  496. costSettingLoading: false,
  497. chosenNoReportUserIds:[],
  498. curPercentVal:{},
  499. setPercentDialog: false,
  500. chosenProjects:[],
  501. projectsDialog: false,
  502. projectCols:[],
  503. allProjectList:[],
  504. multipleSelection:[],
  505. userCostSettingList: [],
  506. settingDialog: false,
  507. radio:"全部人员",
  508. noReportUserList:[],
  509. allFinanceList:[],
  510. assignNoProUser: false,
  511. customFieldList:[],
  512. itemDialog: false,
  513. customCols:{},
  514. customColsi:{},
  515. // showNPDialog: false,
  516. npUserList:[],
  517. hasNoProjectUsers: false,
  518. isUploading:false,
  519. importDialog: false,
  520. importParam:{syncUserCost:true, syncHistoryReport:true},
  521. user: JSON.parse(sessionStorage.getItem("user")),
  522. permissions: JSON.parse(sessionStorage.getItem("permissions")),
  523. userDetailVisible: false,
  524. userDetail:{},
  525. date: null,
  526. tableHeight: 0,
  527. listLoading: false,
  528. list: [],
  529. addLoading: false,
  530. myChart: null,
  531. params: null,
  532. totalPercent:0,
  533. importVisible: false,
  534. shenhe: '',
  535. tabPosition: '0',
  536. reviewerVisible: false,
  537. reviewerRuleForm: {
  538. auditorId: ''
  539. },
  540. people: [],
  541. revaelse: '',
  542. reviewLis: [],
  543. ovReviewLis: [],
  544. xzImportVisible: false,
  545. xzList: [],
  546. intoAmortizationDialog : false ,
  547. importingData: false,
  548. importResultMsg:null,
  549. showImportResult:false,
  550. widthHtval: document.body.clientWidth - 230,
  551. };
  552. },
  553. methods: {
  554. exportFinance() {
  555. this.isUploading = true;
  556. this.http.post('/finance/exportFinance', {
  557. date: this.exportMonth
  558. },res =>{
  559. this.isUploading = false;
  560. if(res.code == 'ok') {
  561. this.downloadByA({name:this.exportMonth+'财务数据.xls', url: res.data});
  562. }
  563. },error => {
  564. this.$message({
  565. message: error,
  566. type: "error"
  567. });
  568. })
  569. },
  570. arrter() {
  571. this.http.post('/user/getEmployeeList', {
  572. departmentId: '-1',
  573. pageIndex: 1,
  574. pageSize: 99999
  575. },res =>{
  576. if(res.code == 'ok') {
  577. this.people = res.data.records
  578. }
  579. },error => {
  580. this.$message({
  581. message: error,
  582. type: "error"
  583. });
  584. })
  585. },
  586. addreviewer() {
  587. this.http.post('/finance-auditor/get', {
  588. companyId: this.user.companyId
  589. },
  590. res => {
  591. if (res.code == "ok") {
  592. console.log(res.data, '数据')
  593. if(res.data) {
  594. this.reviewerRuleForm.auditorId = res.data.auditorId
  595. } else {
  596. this.reviewerRuleForm.auditorId = ''
  597. }
  598. }
  599. },error => {
  600. this.$message({
  601. message: error,
  602. type: "error"
  603. });
  604. }
  605. );
  606. },
  607. // 提交审核人
  608. submitreviewerRuleForm(formName) {
  609. this.$refs[formName].validate((valid) => {
  610. if (valid) {
  611. this.reviewerRuleForm.companyId = this.user.companyId
  612. this.http.post('/finance-auditor/save', this.reviewerRuleForm,
  613. res =>{
  614. if(res.code == 'ok') {
  615. this.$message({
  616. message: '操作成功',
  617. type: "success"
  618. });
  619. this.addreviewer()
  620. } else {
  621. this.$message({
  622. message: '操作失败',
  623. type: "error"
  624. });
  625. }
  626. },error => {
  627. this.$message({
  628. message: error,
  629. type: "error"
  630. });
  631. })
  632. this.reviewerVisible = false
  633. } else {
  634. return false;
  635. }
  636. });
  637. },
  638. handleCloses(done) {
  639. var formName = 'reviewerRuleForm'
  640. this.$refs[formName].resetFields();
  641. done()
  642. },
  643. // 审核
  644. audits() {
  645. this.shenhe = '导入审核'
  646. this.importVisible = true
  647. },
  648. switchCostList() {
  649. //已填日报的人员成本
  650. if (this.costListRadio == 1) {
  651. this.assignNoProUser=false;
  652. this.assignToProject();
  653. } else if (this.costListRadio == 2) {
  654. //全部人员成本
  655. this.assignNoProUser=true;
  656. this.assignToProject();
  657. }
  658. },
  659. getLastMonthSetting() {
  660. this.costSettingLoading = true;
  661. var dataArr = this.date.split('-');
  662. var year = dataArr[0];
  663. var month = dataArr[1];
  664. if (parseInt(month) == 1) {
  665. year = parseInt(year) -1;
  666. month = 12;
  667. } else {
  668. month = parseInt(month) -1;
  669. if (month < 10) {
  670. month = '0'+month;
  671. }
  672. }
  673. var lastMonth = year + '-' + month;
  674. this.http.post('/project-percentage/getMonthSetting', {ymonth: lastMonth},
  675. res => {
  676. this.costSettingLoading = false;
  677. if (res.code == "ok") {
  678. this.projectCols = res.data.financeProjects;
  679. this.allProjectList = res.data.allProjectList;
  680. this.userCostSettingList = res.data.userCostSetting;
  681. //上次如果没有配置过,需要初始化
  682. for (var i=0;i<this.noReportUserList.length; i++) {
  683. var rUser = this.noReportUserList[i];
  684. //检查当前列表中的无项目人员是否在之前的里面存在,如果不在需要加上去
  685. if (this.userCostSettingList.filter(c=>c.id == rUser.userId).length == 0) {
  686. var item = {name: rUser.name, id: rUser.userId};
  687. this.projectCols.forEach(p=>{
  688. item[p.projectId] = 0;
  689. });
  690. this.userCostSettingList.push(item);
  691. }
  692. }
  693. this.$nextTick(()=>{
  694. this.$refs.settingTable.doLayout();
  695. })
  696. } });
  697. },
  698. //获取当月的无项目工时人员的分配比例设置
  699. getMonthSetting() {
  700. this.costSettingLoading = true;
  701. this.http.post('/project-percentage/getMonthSetting', {ymonth: this.date},
  702. res => {
  703. this.costSettingLoading = false;
  704. if (res.code == "ok") {
  705. this.projectCols = res.data.financeProjects;
  706. this.allProjectList = res.data.allProjectList;
  707. this.userCostSettingList = res.data.userCostSetting;
  708. //上次如果没有配置过,需要初始化
  709. for (var i=0;i<this.noReportUserList.length; i++) {
  710. var rUser = this.noReportUserList[i];
  711. console.log('userId====='+rUser.userId);
  712. //检查当前列表中的无项目人员是否在之前的里面存在,如果不在需要加上去
  713. if (this.userCostSettingList.filter(c=>c.id == rUser.userId).length == 0) {
  714. var item = {name: rUser.name, id: rUser.userId};
  715. this.projectCols.forEach(p=>{
  716. item[p.projectId] = 0;
  717. });
  718. this.userCostSettingList.push(item);
  719. }
  720. }
  721. this.$nextTick(()=>{
  722. this.$refs.settingTable.doLayout();
  723. })
  724. } });
  725. },
  726. //提交无工时人员的分配设置
  727. saveMonthSetting() {
  728. //检查数据是否都分配到100%了,防止由于修改了项目列而导致之前的数据不正确的情况
  729. var errorList = this.userCostSettingList.filter(u=>{
  730. let totalPercent = 0.0;
  731. this.projectCols.forEach(p=>{
  732. totalPercent += parseFloat(u[p.projectId]);
  733. });
  734. totalPercent = totalPercent.toFixed(1);
  735. if (totalPercent != 100) {
  736. return true;
  737. } else {
  738. return false;
  739. }
  740. });
  741. if (errorList.length > 0) {
  742. var nameList = errorList.map(e=>e.name);
  743. this.$message({type:'error', message:'存在人员分配比例非100%: '+nameList});
  744. return;
  745. }
  746. this.http.post('/project-percentage/saveMonthSetting', {projectCols: JSON.stringify(this.projectCols),
  747. ymonth: this.date, userSettings: JSON.stringify(this.userCostSettingList)},
  748. res => {
  749. if (res.code == "ok") {
  750. this.$message({type:'success', message:'保存成功'});
  751. this.settingDialog = false;
  752. } else {
  753. this.$message({type:'error', message:'发生错误:'+res.msg});
  754. }});
  755. },
  756. updatePercentValue() {
  757. var total = 0.0;
  758. this.projectCols.forEach(p=>{
  759. total += parseFloat(this.curPercentVal[p.projectId]);
  760. })
  761. this.totalPercent = total.toFixed(1);
  762. this.$forceUpdate();
  763. },
  764. averageCost() {
  765. var avg = (100/this.projectCols.length).toFixed(1);
  766. //最后一个用100减去前面的总和,保证最终合计为100
  767. for (var i=0;i<this.projectCols.length; i++) {
  768. if (i < this.projectCols.length -1) {
  769. this.curPercentVal[this.projectCols[i].projectId] = avg;
  770. } else {
  771. this.curPercentVal[this.projectCols[i].projectId] = (100-avg*(this.projectCols.length-1)).toFixed(1);
  772. }
  773. }
  774. this.updatePercentValue();
  775. this.$forceUpdate();
  776. },
  777. setPercent(isBatch, row) {
  778. this.setPercentDialog = true;
  779. this.chosenNoReportUserIds = [];
  780. if (!isBatch) {
  781. this.chosenNoReportUserIds.push(row.id);
  782. //获取当前比例
  783. this.projectCols.forEach(p=>{
  784. this.curPercentVal[p.projectId] = row[p.projectId];
  785. });
  786. } else {
  787. //批量处理
  788. this.multipleSelection.forEach(m=>{
  789. this.chosenNoReportUserIds.push(m.id);
  790. })
  791. //批量时获取第一条的比例进行加载
  792. this.projectCols.forEach(p=>{
  793. this.curPercentVal[p.projectId] = this.multipleSelection[0][p.projectId];
  794. });
  795. }
  796. this.updatePercentValue();
  797. },
  798. //确认设置的项目列
  799. saveProjectSetting() {
  800. this.projectsDialog = false;
  801. this.projectCols = [];
  802. this.chosenProjects.forEach(c=>{
  803. var item = this.allProjectList.filter(a=>a.id == c)[0];
  804. this.projectCols.push({projectId: item.id, projectName: item.projectName, projectCode: item.projectCode});
  805. });
  806. this.$nextTick(()=>{
  807. this.$refs.settingTable.doLayout();
  808. })
  809. },
  810. handleProjectSelectionChange(val) {
  811. this.projectSelection = val;
  812. },
  813. showSelectProjectDialog() {
  814. //设置选中状态
  815. this.chosenProjects = [];
  816. this.projectCols.forEach(item=>{
  817. this.chosenProjects.push(item.projectId);
  818. })
  819. this.projectsDialog = true;
  820. },
  821. setPercentSetting() {
  822. //检测是否填写的情况下,是否达到100%
  823. if (this.totalPercent != 100) {
  824. this.$message({
  825. message: '分配比例之和必须是100%',
  826. type: "error"
  827. });
  828. return;
  829. }
  830. this.setPercentDialog = false;
  831. this.chosenNoReportUserIds.forEach(u=>{
  832. var targetU = this.userCostSettingList.filter(a=>a.id == u)[0];
  833. //遍历项目
  834. this.projectCols.forEach(p=>{
  835. targetU[p.projectId] = this.curPercentVal[p.projectId];
  836. })
  837. });
  838. this.userCostSettingList.splice(1,0);
  839. },
  840. showSettingDialog() {
  841. this.settingDialog = true;
  842. this.getMonthSetting();
  843. },
  844. handleSelectionChange(val) {
  845. this.multipleSelection = val;
  846. },
  847. switchList() {
  848. if (this.radio == '全部人员') {
  849. this.list = this.allFinanceList;
  850. } else {
  851. this.list = this.noReportUserList;
  852. }
  853. },
  854. downloadByA(row) {
  855. const a = document.createElement('a'); // 创建a标签
  856. a.setAttribute('download', row.name);// download属性
  857. console.log(row.url);
  858. a.setAttribute('href', row.url);// href链接
  859. a.click();// 自执行点击事件
  860. a.remove();
  861. },
  862. getTemplate() {
  863. this.http.post('/finance/getTemplate', {companyId: this.user.companyId},
  864. res => {
  865. if (res.code == "ok") {
  866. if (res.data.indexOf('xlsx') > 0) {
  867. this.downloadByA({name:'财务成本报表.xlsx', url:res.data});
  868. } else {
  869. this.downloadByA({name:'财务成本报表.xls', url:res.data});
  870. }
  871. }});
  872. },
  873. saveItems() {
  874. // let savefields = {
  875. // monthCost : this.customCols.monthCost,
  876. // bonus : this.customCols.bonus,
  877. // allowance : this.customCols.allowance,
  878. // insuranceOld : this.customCols.insuranceOld,
  879. // insuranceMedical : this.customCols.insuranceMedical,
  880. // insuranceLosejob : this.customCols.insuranceLosejob,
  881. // insuranceInjury : this.customCols.insuranceInjury,
  882. // houseFund : this.customCols.houseFund,
  883. // field1 : this.customCols.field1,
  884. // field2 : this.customCols.field2,
  885. // field3 : this.customCols.field3
  886. // }
  887. if(this.customCols.field1 != null && this.customCols.field1 != ''){
  888. if(this.customCols.field1Calculate == null){
  889. this.$message({
  890. message: '请选择是否计入总成本',
  891. type: 'warning'
  892. })
  893. return
  894. }
  895. }
  896. if(this.customCols.field2 != null && this.customCols.field2 != ''){
  897. if(this.customCols.field1Calculate == null){
  898. this.$message({
  899. message: '请选择是否计入总成本',
  900. type: 'warning'
  901. })
  902. return
  903. }
  904. }
  905. if(this.customCols.field3 != null && this.customCols.field3 != ''){
  906. if(this.customCols.field1Calculate == null){
  907. this.$message({
  908. message: '请选择是否计入总成本',
  909. type: 'warning'
  910. })
  911. return
  912. }
  913. }
  914. this.http.post('/finance-tblcuscol/save', this.customCols,
  915. res => {
  916. if (res.code == "ok") {
  917. this.itemDialog = false;
  918. this.getCustomColumn();
  919. }});
  920. this.$forceUpdate();
  921. },
  922. showItemDialog() {
  923. // console.log(this.customColsi, '后台纯的')
  924. // console.log(this.customCols, '用来编辑的')
  925. this.customCols = JSON.parse(JSON.stringify(this.customColsi))
  926. // console.log(this.customColsi, '后台纯的')
  927. // console.log(this.customCols, '用来编辑的')
  928. this.itemDialog = true;
  929. // this.customFieldList = {field1:null,field2:null, field3:null};
  930. // if (this.customCols.field1 !== undefined) {
  931. // this.customFieldList.field1 = this.customCols.field1;
  932. // } else if (this.customCols.field2 !== undefined) {
  933. // this.customFieldList.field2 = this.customCols.field2;
  934. // } else if (this.customCols.field3 !== undefined) {
  935. // this.customFieldList.field3 = this.customCols.field3;
  936. // }
  937. },
  938. //获取自定义的字段
  939. getCustomColumn() {
  940. this.http.post('/finance-tblcuscol/getAll', {companyId: this.user.companyId},
  941. res => {
  942. if (res.code == "ok") {
  943. console.log("获取自定义字段",res.data);
  944. this.customColsi = res.data;
  945. this.tblCols = [];
  946. this.tblCols.push(this.customColsi.monthCost);
  947. this.tblCols.push(this.customColsi.bonus);
  948. this.tblCols.push(this.customColsi.allowance);
  949. this.tblCols.push(this.customColsi.insuranceOld);
  950. this.tblCols.push(this.customColsi.insuranceMedical);
  951. this.tblCols.push(this.customColsi.insuranceLosejob);
  952. this.tblCols.push(this.customColsi.insuranceInjury);
  953. this.tblCols.push(this.customColsi.houseFund);
  954. if (this.customColsi.field1 != null) {
  955. this.tblCols.push(this.customColsi.field1);
  956. }
  957. if (this.customColsi.field2 != null) {
  958. this.tblCols.push(this.customColsi.field2);
  959. }
  960. if (this.customColsi.field3 != null) {
  961. this.tblCols.push(this.customColsi.field3);
  962. }
  963. }});
  964. },
  965. // },
  966. // getProjects() {
  967. // this.http.post('/finance/getProjects', {companyId: this.user.companyId, yearMonth: this.date},
  968. // res => {
  969. // if (res.code == "ok") {
  970. // this.projectCols = res.data.financeProjects;
  971. // this.allProjectList = res.data.allProjectList;
  972. // }});
  973. // },
  974. // showNoProjectUsers() {
  975. // this.showNPDialog = true;
  976. // this.http.post('/finance/getNoProjectUsers', {yearMonth: this.date},
  977. // res => {
  978. // if (res.code == "ok") {
  979. // this.npUserList = res.data;
  980. // }});
  981. // },
  982. assignToProject(){
  983. var _this = this;
  984. this.http.post('/finance/getTimeCost', {yearMonth: this.date, assignNoProUser: this.assignNoProUser},
  985. res => {
  986. if (res.code == "ok") {
  987. // 待会删除
  988. // var lll = res.data.costList
  989. // var arrLists = []
  990. // for(var i = 0; i < 50; i++) {
  991. // arrLists.push(lll[1])
  992. // }
  993. // res.data.costList = arrLists
  994. // 待会删除
  995. for(var i in res.data.costList) {
  996. if(i>20) {
  997. this.widthHtval = +this.widthHtval + 40
  998. } else {
  999. this.widthHtval = document.body.clientWidth - 230
  1000. }
  1001. }
  1002. console.log(res.data, '图表数据', this.widthHtval)
  1003. var xList = [], yList = [], list = res.data.costList,
  1004. totalMoneyCost = res.data.totalMoneyCost;
  1005. var nopCost = 0;
  1006. if (res.data.noProjectItem.project != null) {
  1007. this.hasNoProjectUsers = true;
  1008. nopCost = res.data.noProjectItem.cost;
  1009. } else {
  1010. this.hasNoProjectUsers = false;
  1011. }
  1012. for(var i in list) {
  1013. xList.push(list[i].project);
  1014. yList.push({
  1015. "value": list[i].cost,
  1016. "id": list[i].id,
  1017. "time": list[i].workingTime
  1018. });
  1019. }
  1020. var myChart = echarts.init(document.getElementById("container"));
  1021. // 设置图表
  1022. myChart.resize({
  1023. width: this.widthHtval
  1024. })
  1025. _this.myChart = myChart;
  1026. var option = {
  1027. title: {
  1028. text: this.assignNoProUser?'成本总计 ' + totalMoneyCost + '元'
  1029. +(this.hasNoProjectUsers?",含无项目人员成本 " + nopCost+"元 ":"")
  1030. :'成本总计 ' + totalMoneyCost + '元',
  1031. left:'left',
  1032. },
  1033. grid : {
  1034. top : 40, //距离容器上边界40像素
  1035. // bottom: 100, //距离容器下边界30像素
  1036. bottom: 40, //距离容器下边界30像素
  1037. left: 100,
  1038. right: 100
  1039. },
  1040. // 工具箱
  1041. toolbox: {
  1042. show: true,
  1043. feature:{
  1044. saveAsImage:{
  1045. show:true
  1046. },
  1047. restore:{
  1048. show:true
  1049. },
  1050. magicType:{
  1051. type:['line','bar']
  1052. },
  1053. }
  1054. },
  1055. tooltip:{
  1056. trigger:'axis',
  1057. formatter: function (params,ticket,callback) {
  1058. var res = params[0].name + "<br/>工作成本"+" : " + params[0].data.value
  1059. + "元 <br/>工作时长"+" : " + params[0].data.time + "小时";
  1060. _this.params = params;
  1061. return res;
  1062. }
  1063. },
  1064. xAxis: {
  1065. data: xList,
  1066. axisLabel: {
  1067. interval:0,rotate:20
  1068. }
  1069. },
  1070. yAxis: [{
  1071. type : 'value',
  1072. axisLabel: {
  1073. formatter:'{value} (元)'
  1074. }
  1075. }],
  1076. series: [{
  1077. name: '工作时长(h)',
  1078. type: 'bar',
  1079. barMaxWidth: 30,
  1080. data: yList,
  1081. }]
  1082. };
  1083. option && myChart.setOption(option,{notMerge: true});
  1084. // myChart.getZr().on('click', params => {
  1085. // const pointInPixel = [params.offsetX, params.offsetY];
  1086. // if (myChart.containPixel('grid', pointInPixel)) {
  1087. // console.log(_this.params)
  1088. // if(_this.radio=='项目') {
  1089. // _this.$router.push("/cost/" + _this.params[0].data.id + "/" + _this.params[0].name);
  1090. // }
  1091. // }
  1092. // });
  1093. } else {
  1094. this.$message({
  1095. message: res.msg,
  1096. type: "error"
  1097. });
  1098. }
  1099. },
  1100. error => {
  1101. this.$message({
  1102. message: error,
  1103. type: "error"
  1104. });
  1105. });
  1106. },
  1107. //导出财务数据
  1108. exportData() {
  1109. this.exportDataProcessing = true;
  1110. this.http.post('/finance/exportData', {
  1111. date: this.date, assignNoProUser: this.assignNoProUser, groupByCategory: this.groupByCategory
  1112. },
  1113. res => {
  1114. this.exportDataProcessing = false;
  1115. if (res.code == "ok") {
  1116. this.exportFinanceDialog = false;
  1117. var aTag = document.createElement('a');
  1118. aTag.download = "财务成本统计.xls";
  1119. aTag.href = res.data;
  1120. aTag.click();
  1121. } else {
  1122. this.$message({
  1123. message: res.msg,
  1124. type: "error"
  1125. });
  1126. }
  1127. },
  1128. error => {
  1129. this.listLoading = false;
  1130. this.$message({
  1131. message: error,
  1132. type: "error"
  1133. });
  1134. });
  1135. },
  1136. getSummaries(param) {
  1137. const { columns, data } = param;
  1138. const sums = [];
  1139. columns.forEach((column, index) => {
  1140. if (index === 0) {
  1141. sums[index] = '总价';
  1142. return;
  1143. }
  1144. const values = data.map(item => Number(item[column.property]));
  1145. if (!values.every(value => isNaN(value))) {
  1146. sums[index] = values.reduce((prev, curr) => {
  1147. const value = Number(curr);
  1148. if (!isNaN(value)) {
  1149. return prev + curr;
  1150. } else {
  1151. return prev;
  1152. }
  1153. }, 0);
  1154. sums[index] += ' 元';
  1155. } else {
  1156. sums[index] = 'N/A';
  1157. }
  1158. });
  1159. return sums;
  1160. },
  1161. changeMonth() {
  1162. //改变月份
  1163. this.getList();
  1164. this.assignToProject();
  1165. this.getMonths()
  1166. },
  1167. // 批量导入人员
  1168. importFinance(item) {
  1169. //首先判断文件类型
  1170. let str = item.file.name.split(".");
  1171. let format = str[str.length - 1];
  1172. if (format != "xls" && format != "xlsx") {
  1173. this.$message({
  1174. message: "请选择.xls或.xlsx文件",
  1175. type: "error"
  1176. });
  1177. } else {
  1178. this.listLoading = true;
  1179. let formData = new FormData();
  1180. formData.append("file", item.file);
  1181. formData.append("companyId", this.user.companyId);
  1182. formData.append("yearMonth", this.date);
  1183. formData.append("syncUserCost", this.importParam.syncUserCost);
  1184. formData.append("syncHistoryReport", this.importParam.syncHistoryReport);
  1185. this.isUploading = true;
  1186. let urls = ''
  1187. if(this.user.timeType.financeAudit == '1') {
  1188. urls = '/finance-import/submitImport'
  1189. } else {
  1190. urls = '/finance/importData'
  1191. }
  1192. // this.http.uploadFile('/finance/importData', formData,
  1193. this.http.uploadFile(urls, formData,
  1194. res => {
  1195. console.log(this.user.timeType.financeAudit, '看看数据')
  1196. this.$refs.upload.clearFiles();
  1197. this.listLoading = false;
  1198. this.isUploading = false;
  1199. if (res.code == "ok") {
  1200. if (this.user.timeType.financeAudit == 1 ) {
  1201. this.$message({
  1202. message: '导入成功,请等待审核',
  1203. type: "warning"
  1204. });
  1205. this.getMonths();
  1206. } else {
  1207. this.$message({
  1208. message: '导入成功',
  1209. type: "success"
  1210. });
  1211. }
  1212. this.importDialog = false;
  1213. //重新读取列表
  1214. this.getList();
  1215. } else {
  1216. this.$message({
  1217. message: res.msg,
  1218. type: "error"
  1219. });
  1220. }
  1221. },
  1222. error => {
  1223. this.$refs.upload.clearFiles();
  1224. this.listLoading = false;
  1225. this.$message({
  1226. message: error,
  1227. type: "error"
  1228. });
  1229. });
  1230. }
  1231. },
  1232. // 导入提交审核
  1233. // submitReview(formData) {
  1234. // this.http.uploadFile(' /finance-import/submitImport', formData,
  1235. // res => {
  1236. // if (res.code == "ok") {
  1237. // console.log(res.data, '来的数据')
  1238. // } else {
  1239. // this.$message({
  1240. // message: res.msg,
  1241. // type: "error"
  1242. // });
  1243. // }
  1244. // },
  1245. // error => {
  1246. // this.$refs.upload.clearFiles();
  1247. // this.listLoading = false;
  1248. // this.$message({
  1249. // message: error,
  1250. // type: "error"
  1251. // });
  1252. // });
  1253. // },
  1254. //获取项目列表
  1255. getList() {
  1256. this.listLoading = true;
  1257. this.http.post('/finance/getByMonth', {
  1258. companyId: this.user.companyId,
  1259. yearMonth: this.date
  1260. },
  1261. res => {
  1262. this.listLoading = false;
  1263. if (res.code == "ok") {
  1264. var list = res.data;
  1265. this.allFinanceList = list;
  1266. this.list = this.allFinanceList;
  1267. this.noReportUserList = list.filter(r=>r.hasReport == 0);
  1268. } else {
  1269. this.$message({
  1270. message: res.msg,
  1271. type: "error"
  1272. });
  1273. }
  1274. },
  1275. error => {
  1276. this.listLoading = false;
  1277. this.$message({
  1278. message: error,
  1279. type: "error"
  1280. });
  1281. });
  1282. },
  1283. // 获取当月的审核状态
  1284. getMonths() {
  1285. this.http.post('/finance-import/getStatus', {
  1286. companyId: this.user.companyId,
  1287. yearMonth: this.date
  1288. },
  1289. res => {
  1290. this.listLoading = false;
  1291. if (res.code == "ok") {
  1292. console.log(res.data, '审核状态')
  1293. if(res.data) {
  1294. if(res.data.state == '0') {
  1295. this.revaelse = '待审核'
  1296. this.tabPosition = '0'
  1297. } else if(res.data.state == '1') {
  1298. this.revaelse = '审核记录'
  1299. this.tabPosition = '1'
  1300. }else if (res.data.state == '2') {
  1301. this.revaelse = '已驳回'
  1302. this.tabPosition = '2'
  1303. } else if (res.data.state == '3') {
  1304. this.revaelse = '已撤销'
  1305. this.tabPosition = '-1'
  1306. }
  1307. this.getReviewList()
  1308. } else {
  1309. this.revaelse = ''
  1310. }
  1311. } else {
  1312. this.$message({
  1313. message: res.msg,
  1314. type: "error"
  1315. });
  1316. }
  1317. },
  1318. error => {
  1319. this.listLoading = false;
  1320. this.$message({
  1321. message: error,
  1322. type: "error"
  1323. });
  1324. });
  1325. },
  1326. // 获取审核列表
  1327. getReviewList() {
  1328. this.http.post('/finance-import/list', {
  1329. companyId: this.user.companyId,
  1330. },
  1331. res => {
  1332. if (res.code == "ok") {
  1333. console.log(res.data, '拿到的数据')
  1334. this.ovReviewLis = res.data
  1335. if(this.tabPosition == 0) {
  1336. this.reviewLis = res.data.pendingList
  1337. } else if(this.tabPosition == 1) {
  1338. this.reviewLis = res.data.passList
  1339. } else if(this.tabPosition == 2) {
  1340. this.reviewLis = res.data.rejectList
  1341. } else {
  1342. this.reviewLis = res.data.cancelList
  1343. }
  1344. console.log(this.reviewLis, '数据')
  1345. } else {
  1346. this.$message({
  1347. message: res.msg,
  1348. type: "error"
  1349. });
  1350. }
  1351. },
  1352. error => {
  1353. this.$message({
  1354. message: error,
  1355. type: "error"
  1356. });
  1357. });
  1358. },
  1359. // 操作数据
  1360. operationalData () {
  1361. var sss = this.ovReviewLis
  1362. if(this.tabPosition == 0) {
  1363. this.reviewLis = sss.pendingList
  1364. } else if(this.tabPosition == 1) {
  1365. this.reviewLis = sss.passList
  1366. } else if(this.tabPosition == 2) {
  1367. this.reviewLis = sss.rejectList
  1368. } else {
  1369. this.reviewLis = sss.cancelList
  1370. }
  1371. console.log(this.reviewLis, '数据')
  1372. },
  1373. // 审核操作
  1374. operationList(zhi, id) {
  1375. let urls
  1376. if(zhi == 0) {
  1377. urls = '/finance-import/agree'
  1378. } else if(zhi == 1){
  1379. urls = '/finance-import/deny'
  1380. } else {
  1381. urls = '/finance-import/cancel'
  1382. }
  1383. this.http.post(urls, {
  1384. id: id,
  1385. },
  1386. res => {
  1387. if (res.code == "ok") {
  1388. this.$message({
  1389. message: '操作成功',
  1390. type: "success"
  1391. });
  1392. this.getReviewList()
  1393. } else {
  1394. this.$message({
  1395. message: res.msg,
  1396. type: "error"
  1397. });
  1398. }
  1399. },
  1400. error => {
  1401. this.$message({
  1402. message: error,
  1403. type: "error"
  1404. });
  1405. });
  1406. },
  1407. // 获取薪资上传记录
  1408. xzjl() {
  1409. this.http.post('/finance-import/list', {
  1410. companyId: this.user.companyId,
  1411. // pageIndex:1,
  1412. // pageSize: 9999
  1413. },
  1414. res => {
  1415. if (res.code == "ok") {
  1416. console.log('123',res.data)
  1417. this.xzList = res.data.passList
  1418. } else {
  1419. this.$message({
  1420. message: res.msg,
  1421. type: "error"
  1422. });
  1423. }
  1424. },
  1425. error => {
  1426. this.$message({
  1427. message: error,
  1428. type: "error"
  1429. });
  1430. });
  1431. },
  1432. //导入分摊比例
  1433. intoAmortizationRatio(){
  1434. this.intoAmortizationDialog = true;
  1435. },
  1436. batchImportData(item) {
  1437. //首先判断文件类型
  1438. let str = item.file.name.split(".");
  1439. let format = str[str.length - 1];
  1440. if (format != "xls" && format != "xlsx") {
  1441. this.$message({
  1442. message: "请选择.xls或.xlsx文件",
  1443. type: "error"
  1444. });
  1445. } else {
  1446. this.importingData = true;
  1447. let formData = new FormData();
  1448. formData.append("file", item.file);
  1449. formData.append("companyId", this.user.companyId);
  1450. this.http.uploadFile('/project-percentage/importData', formData,
  1451. res => {
  1452. this.$refs.upload.clearFiles();
  1453. this.importingData = false;
  1454. this.showImportResult = true;
  1455. if (res.code == "ok") {
  1456. //换成弹出框,以免有人等了半天回来啥也没看到
  1457. this.importResultMsg = "成功导入"+res.data+"条分摊比例数据。"+(res.msg?res.msg:"");
  1458. this.showSettingDialog();
  1459. } else {
  1460. this.importResultMsg = "导入失败:"+res.msg;
  1461. }
  1462. },
  1463. error => {
  1464. this.$refs.upload.clearFiles();
  1465. this.importingData = false;
  1466. this.$message({
  1467. message: error,
  1468. type: "error"
  1469. });
  1470. });
  1471. }
  1472. },
  1473. // 左右滚动
  1474. scrollFunction () {
  1475. this.domObj = document.getElementById('clearfix') // 通过id获取要设置的div
  1476. if (this.domObj.attachEvent) { // IE
  1477. this.domObj.attachEvent('onmousewheel', this.mouseScroll)
  1478. } else if (this.domObj.addEventListener) {
  1479. this.domObj.addEventListener('DOMMouseScroll', this.mouseScroll, false)
  1480. }
  1481. this.domObj.onmousewheel = this.domObj.onmousewheel = this.mouseScroll
  1482. },
  1483. mouseScroll(event) { // google 浏览器下
  1484. let detail = event.wheelDelta || event.detail
  1485. let moveForwardStep = -1
  1486. let moveBackStep = 1
  1487. let step = 0
  1488. step = detail > 0 ? moveForwardStep * 100 : moveBackStep * 100
  1489. event.preventDefault() // 阻止浏览器默认事件
  1490. this.domObj.scrollLeft = this.domObj.scrollLeft + step
  1491. },
  1492. },
  1493. created() {
  1494. var d = new Date();
  1495. this.date = d.getFullYear() +'-'+ ((d.getMonth()+1) < 10? '0'+(d.getMonth()+1):d.getMonth()+1);
  1496. },
  1497. mounted() {
  1498. let height = window.innerHeight;
  1499. this.tableHeight = height - 245;
  1500. const that = this;
  1501. window.onresize = function temp() {
  1502. that.tableHeight = window.innerHeight - 245;
  1503. };
  1504. this.getCustomColumn();
  1505. this.getList();
  1506. // this.getProjects();
  1507. this.addreviewer();
  1508. this.arrter()
  1509. this.getMonths()
  1510. this.scrollFunction()
  1511. },
  1512. updated() {
  1513. this.$nextTick(() => {
  1514. this.$refs['table'].doLayout();
  1515. })
  1516. }
  1517. };
  1518. </script>
  1519. <style lang="scss" scoped>
  1520. .nameList {
  1521. height: 400px;
  1522. overflow: auto;
  1523. }
  1524. </style>