finance.vue 103 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996
  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="this.$t('Selectmonth')" >
  8. <el-date-picker size="small" v-model="date" :editable="false" format="yyyy-MM" value-format="yyyy-MM" @change="loadMonthData" :clearable="false" type="month" :placeholder="$t('Selectmonth')" 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="$t('lable.allStaff')" >{{$t('lable.allStaff')}}({{allFinanceList.length}})</el-radio-button>
  14. <el-radio-button :label="$t('projectworker')">{{$t('projectworker')}}({{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="showProjSettingDialog()" v-if="user.companyId == 88">{{ $t('ApportionmentProjsetting')}}</el-link>
  18. <el-link type="primary" :underline="false" @click="showSettingDialog()" style="margin-left:50px;">{{ $t('Apportionmentratesetting') }}</el-link>
  19. </el-form-item>
  20. <el-form-item style="float:right;" v-if="permissions.financialUpload">
  21. <el-link type="primary" :underline="false" @click="getTemplate()" >{{ $t('Downloadthetemplate') }}</el-link>
  22. </el-form-item>
  23. <!-- <el-form-item style="float:right;">
  24. <el-upload ref="upload" action="#" :limit="1" :http-request="importFinance" :show-file-list="false">
  25. <el-link type="primary" :underline="false" >财务数据上传</el-link>
  26. </el-upload>
  27. </el-form-item> -->
  28. <el-form-item style="float:right;" v-if="permissions.financialUpload">
  29. <el-link type="primary" :underline="false" @click="importDialog = true;isUploading=false;">{{ $t('Dataupload') }}</el-link>
  30. </el-form-item>
  31. <el-form-item style="float:right;" v-if="permissions.financialExport">
  32. <el-link type="primary" :underline="false" @click="exportDialog = true;exportMonth = date;">{{ $t('Exportdata') }}</el-link>
  33. </el-form-item>
  34. <el-form-item style="float:right;" v-if="permissions.financialCustom">
  35. <el-link type="primary" :underline="false" @click="showItemDialog()">{{ $t('Customizesalaryitems') }}</el-link>
  36. </el-form-item>
  37. <el-form-item style="float:right;">
  38. <el-link type="primary" :underline="false" @click="notParticipatingInSharedProjects()">
  39. 不参与分摊项目设置
  40. </el-link>
  41. </el-form-item>
  42. <el-form-item style="float:right;" v-if="user.timeType.financeAudit == '1' && permissions.setFinanceAuditor">
  43. <el-link type="primary" :underline="false" @click="reviewerVisible = true">{{ $t('Setupauditor') }}</el-link>
  44. </el-form-item>
  45. </el-form>
  46. </el-col>
  47. <!-- 上传记录 -->
  48. <el-dialog :title="$t('Salaryuploadrecord')" :visible.sync="xzImportVisible" width="1100px" :before-close="handleClose">
  49. <div>
  50. <el-table :data="xzList" style="width: 100%" :height="400">
  51. <el-table-column prop="userName" :label="$t('other.operator')">
  52. <template slot-scope="scope">
  53. <div>
  54. <span v-if="user.userNameNeedTranslate == '1'"><TranslationOpenDataText type='userName' :openid='scope.row.userName'></TranslationOpenDataText></span>
  55. <span v-if="user.userNameNeedTranslate != '1'">{{scope.row.userName}}</span>
  56. </div>
  57. </template>
  58. </el-table-column>
  59. <el-table-column prop="ymonth" :label="$t('BelongsIn')"></el-table-column>
  60. <el-table-column prop="fileName" :label="$t('filename')">
  61. <template slot-scope="scope">
  62. <div>
  63. <el-link type="primary" @click="downloadByA({name:scope.row.fileName,url:scope.row.serverName})"> {{scope.row.fileName}}</el-link>
  64. </div>
  65. </template>
  66. </el-table-column>
  67. <el-table-column prop="recoverReport" :label="$t('Whetherdailycostiscovered')" width="150">
  68. <template slot-scope="scope">
  69. <div>
  70. {{scope.row.recoverReport == 1? $t('state.yes') : $t('state.no')}}
  71. </div>
  72. </template>
  73. </el-table-column>
  74. <el-table-column prop="recoverMonthcost" :label="$t('Whethermonthlypersonnelcostiscovered')" width="150">
  75. <template slot-scope="scope">
  76. <div>
  77. {{scope.row.recoverMonthcost == 1? $t('state.yes') : $t('state.no')}}
  78. </div>
  79. </template>
  80. </el-table-column>
  81. <el-table-column prop="indate" :label="$t('Uploadtime')"></el-table-column>
  82. <!-- <el-table-column prop="date" label="操作" v-if="(tabPosition == 1 || tabPosition == 0) && (reviewerRuleForm.auditorId == user.id || user.role == 1 || user.role == 2)">
  83. <template slot-scope="scope">
  84. <div>
  85. <el-button type="primary" size="small" v-if="tabPosition == 0" @click="operationList(0, scope.row.id)">通过</el-button>
  86. <el-button type="warning" size="small" v-if="tabPosition == 0" @click="operationList(1, scope.row.id)">驳回</el-button>
  87. <el-button type="warning" size="small" v-if="tabPosition == 1" @click="operationList(2, scope.row.id)">撤销</el-button>
  88. </div>
  89. </template>
  90. </el-table-column> -->
  91. </el-table>
  92. </div>
  93. </el-dialog>
  94. <!-- 财务报表审核 -->
  95. <el-dialog :title="shenhe" :visible.sync="importVisible" width="1100px" :before-close="handleClose">
  96. <div>
  97. <el-radio-group v-model="tabPosition" style="margin-bottom: 20px;" @change="operationalData()">
  98. <el-radio-button label="1">{{ $t('state.alreadyPassed') }}</el-radio-button>
  99. <el-radio-button label="0">{{ $t('state.WaitingAudit') }}</el-radio-button>
  100. <el-radio-button label="2">{{ $t('state.rejected') }}</el-radio-button>
  101. <el-radio-button label="-1">{{ $t('state.undone') }}</el-radio-button>
  102. </el-radio-group>
  103. <el-table :data="reviewLis" style="width: 100%" :height="400">
  104. <el-table-column prop="userName" :label="$t('other.operator')" width="100">
  105. <template slot-scope="scope">
  106. <div>
  107. <span v-if="user.userNameNeedTranslate == '1'"><TranslationOpenDataText type='userName' :openid='scope.row.userName'></TranslationOpenDataText></span>
  108. <span v-if="user.userNameNeedTranslate != '1'">{{scope.row.userName}}</span>
  109. </div>
  110. </template>
  111. </el-table-column>
  112. <el-table-column prop="ymonth" :label="$t('BelongsIn')" width="100"></el-table-column>
  113. <el-table-column prop="fileName" :label="$t('filename')" >
  114. <template slot-scope="scope">
  115. <div>
  116. <el-link type="primary" @click="downloadByA({name:scope.row.fileName,url:scope.row.serverName})"> {{scope.row.fileName}}</el-link>
  117. </div>
  118. </template>
  119. </el-table-column>
  120. <el-table-column prop="recoverReport" :label="$t('Whetherdailycostiscovered')" width="150">
  121. <template slot-scope="scope">
  122. <div>
  123. {{scope.row.recoverReport == 1? $t('state.yes') : $t('state.no')}}
  124. </div>
  125. </template>
  126. </el-table-column>
  127. <el-table-column prop="recoverMonthcost" :label="$t('Whethermonthlypersonnelcostiscovered')" width="150">
  128. <template slot-scope="scope">
  129. <div>
  130. {{scope.row.recoverMonthcost == 1? $t('state.yes') : $t('state.no')}}
  131. </div>
  132. </template>
  133. </el-table-column>
  134. <el-table-column prop="indate" :label="$t('Uploadtime')" width="150"></el-table-column>
  135. <el-table-column prop="date" :label="$t('operation')" v-if="(tabPosition == 1 || tabPosition == 0) && (reviewerRuleForm.auditorId == user.id)" :width="tabPosition==0?210:120">
  136. <template slot-scope="scope">
  137. <div>
  138. <el-button type="primary" size="small" :loading="operating" v-if="tabPosition == 0" @click="operationList(0, scope.row.id)">{{ $t('btn.through') }}</el-button>
  139. <el-button type="warning" size="small" :loading="operating" v-if="tabPosition == 0" @click="operationList(1, scope.row.id)">{{ $t('btn.rejected') }}</el-button>
  140. <el-button type="warning" size="small" :loading="operating" v-if="tabPosition == 1" @click="operationList(2, scope.row.id)">{{ $t('btn.undo') }}</el-button>
  141. </div>
  142. </template>
  143. </el-table-column>
  144. </el-table>
  145. </div>
  146. </el-dialog>
  147. <!-- 设置审核人弹窗 -->
  148. <el-dialog :title="$t('Setupauditor')" :visible.sync="reviewerVisible" width="350px" :before-close="handleCloses">
  149. <el-form :model="reviewerRuleForm" ref="reviewerRuleForm" label-width="100px" class="demo-ruleForm">
  150. <el-form-item :label="$t('SelectionofAuditor')" prop="auditorId" :rules="{required: true, message: $t('reviewercannotbeempty'), trigger: 'blur'}">
  151. <el-select v-model="reviewerRuleForm.auditorId" clearable :placeholder="$t('SelectionofAuditor')" v-if="user.userNameNeedTranslate != '1'" >
  152. <el-option v-for="(item, index) in people" :key="index" :label="item.name" :value="item.id"></el-option>
  153. </el-select>
  154. <selectCat v-if="user.userNameNeedTranslate == '1'" @selectCal="selectCal" :subject="people" :subjectId="reviewerRuleForm.auditorId" :distinction="'1'" :size="'mini'"></selectCat>
  155. </el-form-item>
  156. <el-form-item>
  157. <el-button type="primary" @click="submitreviewerRuleForm('reviewerRuleForm')">{{ $t('btn.submit') }}</el-button>
  158. </el-form-item>
  159. </el-form>
  160. </el-dialog>
  161. <el-dialog :title="$t('Exportoffinancialdata')" v-if="exportDialog" :visible.sync="exportDialog" :close-on-click-modal="false" customClass="customWidth" width="400px">
  162. <el-form ref="form3" >
  163. <el-form-item :label="$t('Intheexport')" >
  164. <!-- <div style="color:orange;">{{date}}</div> -->
  165. <el-date-picker v-model="exportMonth" type="month" :placeholder="$t('Selectmonth')" format="yyyy-MM" value-format="yyyy-MM" style="width:280px;"></el-date-picker>
  166. </el-form-item>
  167. </el-form>
  168. <div slot="footer" class="dialog-footer">
  169. <el-button type="primary" style="width:100%;" :loading="isUploading" @click="exportFinance">{{ $t('export.export') }}</el-button>
  170. </div>
  171. </el-dialog>
  172. <el-dialog :title="`${notParticipatingInSharedProjectsTitle}月 不参与分摊项目设置`" v-if="notParticipatingInSharedProjectsVisable" :visible.sync="notParticipatingInSharedProjectsVisable" :close-on-click-modal="false" customClass="customWidth" width="1000px">
  173. <el-form ref="form3" >
  174. <el-form-item :label="''" >
  175. <el-select v-model="notParticipatingInSharedProjectsValue" placeholder="请选择项目" filterable multiple :disabled="notParticipatingInSharedProjectDisabled" style="width: 100%;" clearable>
  176. <el-option
  177. v-for="item in projectAllList"
  178. :key="item.id"
  179. :label="item.projectName"
  180. :value="item.id">
  181. </el-option>
  182. </el-select>
  183. </el-form-item>
  184. <el-form-item :label="''" >
  185. <el-checkbox v-model="notParticipatingInSharedAllProject" @change="selectAllItems">选中全部项目</el-checkbox>
  186. <br />
  187. <el-link type="warning" :underline="false">*设置后请重新导入该月人员薪资</el-link>
  188. </el-form-item>
  189. </el-form>
  190. <div slot="footer" class="dialog-footer">
  191. <el-button type="primary" style="width:100%;" :loading="notParticipatingInSharedProjectsLoading" @click="submitNotParticipatingInSharedProject()">确定</el-button>
  192. </div>
  193. </el-dialog>
  194. <!--列表-->
  195. <!-- 222 -->
  196. <el-table :data="list" highlight-current-row v-loading="listLoading"
  197. :show-summary='user.timeType.isSecretSalary==0?true:false'
  198. ref="table"
  199. :summary-method="getSummaries"
  200. @selection-change="deleteSel"
  201. :height="300" style="width: 100%;">
  202. <el-table-column type="selection" width="80" fixed="left"></el-table-column>
  203. <el-table-column prop="jobNumber" v-if="user.timeType.financeJobnumEnabled==1" :label="$t('Worknumber')" sortable width="100" fixed="left"></el-table-column>
  204. <el-table-column prop="name" :label="$t('lable.name')" sortable width="150" fixed="left">
  205. <template slot-scope="scope">
  206. <div>
  207. <!-- <span v-if="user.userNameNeedTranslate == '1'"><TranslationOpenDataText type='userName' :openid='scope.row.name'></TranslationOpenDataText></span>
  208. <span v-if="user.userNameNeedTranslate != '1'">{{scope.row.name}}</span> -->
  209. {{scope.row.name}}
  210. </div>
  211. </template>
  212. </el-table-column>
  213. <template v-if="user.timeType.isSecretSalary==0">
  214. <el-table-column :prop="headerCols[index]" :label="item" sortable show-overflow-tooltip v-for="(item, index) in tblCols" :key="index" width="130px" align="right">
  215. <template slot-scope="scope">
  216. <div style="padding-right:5px;">{{scope.row[headerCols[index]]==null?'0.00':scope.row[headerCols[index]].toFixed(2)}}</div>
  217. </template>
  218. </el-table-column>
  219. </template>
  220. <template v-if="user.timeType.isSecretSalary==1">
  221. <el-table-column :label="item" sortable show-overflow-tooltip v-for="(item, index) in tblCols" :key="index" width="130px" align="center">
  222. <template slot-scope="scope" >
  223. * <span v-if="scope.row"></span>
  224. </template>
  225. </el-table-column>
  226. </template>
  227. <el-table-column prop="totalCost" width="150" align="right" :label="$t('totalcost')" fixed="right">
  228. <template slot-scope="scope" >
  229. <div style="padding-right:5px;">{{user.timeType.isSecretSalary==0?scope.row.totalCost:'*'}}</div>
  230. </template>
  231. </el-table-column>
  232. </el-table>
  233. <div style="padding:5px 0 0 10px" v-if="permissions.financialUpload">
  234. <el-button @click="deleteUsers" size="mini" type="primary" :disabled="deleteSelList.length == 0">{{ $t('Batchdelete') }}</el-button>
  235. </div>
  236. <el-form :inline="true" >
  237. <el-form-item >
  238. <!-- <el-checkbox style="margin-left:10px;" v-model="assignNoProUser" @click="assignToProject">均摊无项目人员成本</el-checkbox> -->
  239. <!-- <el-button type="primary" :underline="false" size="small" @click="assignNoProUser=false;assignToProject();" style="margin-left:10px;">分摊已填工时人员成本</el-button>
  240. <el-button type="primary" :underline="false" size="small" @click="assignNoProUser=true;assignToProject();" style="margin-left:10px;">分摊全部人员成本</el-button> -->
  241. <el-radio-group size="small" v-model="costListRadio" @change="switchCostList" style="margin-left:5px;margin-top:5px;">
  242. <el-radio-button label="1" >{{ $t('Apportionmentofpersonnelcosts') }}</el-radio-button>
  243. <el-radio-button label="2">{{ $t('Spreadallpersonnelcosts') }}</el-radio-button>
  244. </el-radio-group>
  245. <span v-if="missingFinanceUserList.length > 0" style="color:red;">{{ $t('jianCeDaoYou') }} <el-link @click="showMissingDialog = true">&nbsp;{{ missingFinanceUserList.length }}&nbsp;</el-link> {{ $t('mingYiTianGongShiRenYuanZaiXinZiBiaoZhongWuJiLuBuCanYuChengBenFenTan') }}</span>
  246. </el-form-item>
  247. <el-form-item style="float:right;margin-right:20px;" v-if="permissions.financialShare">
  248. <el-link type="primary" :underline="false" @click="uploadTest()" v-if="user.companyId == 936" style="margin-right:10px">{{ $t('shangChuan') }}</el-link>
  249. <el-link type="primary" :underline="false" @click="exportFinanceDialog=true, personnelAllocation = true">{{ $t('ExportingtheAllocationData') }}</el-link>
  250. </el-form-item>
  251. </el-form>
  252. <!-- 图表 -->
  253. <div id="clearfix" :style="'overflow-x: auto;width:100%;padding-bottom: 100px; position: relative; height:300px;'">
  254. <div id="container" :style="'height: 300px;width:100%;'"></div>
  255. </div>
  256. <!--新增界面-->
  257. <el-dialog :title="title" v-if="addFormVisible" :visible.sync="addFormVisible" :close-on-click-modal="false" customClass="customWidth" width="600px">
  258. <el-form ref="form1" :model="addForm" :rules="rules" label-width="100px">
  259. <el-form-item :label="user.companyId == '7030' ? '项目令号' : $t('Itemno')" >
  260. <el-input v-model="addForm.code" :placeholder="$t('Pleaseentertheprojectnumber')" clearable></el-input>
  261. </el-form-item>
  262. <el-form-item :label="$t('headerTop.projectName')" prop="name">
  263. <el-input v-model="addForm.name" :placeholder="$t('Pleaseenteraprojectname')" clearable></el-input>
  264. </el-form-item>
  265. <el-form-item :label="$t('Allparticipants')">
  266. <el-select v-model="addForm.userId" multiple filterable :placeholder="$t('Pleaseselectparticipants')" style="width:100%;" @change="changeParticipator">
  267. <el-option v-for="item in users" :key="item.id" :label="item.name" :value="item.id"></el-option>
  268. </el-select>
  269. </el-form-item>
  270. <el-form-item :label="$t('Principalpersoninharge')" >
  271. <el-select v-model="addForm.inchargerId" :disabled="addForm.userId.length==0" filterable :placeholder="$t('Pleaseselectthepersonincharge')" style="width:100%;" @change="changeIncharger">
  272. <el-option v-for="item in participator" :key="item.id" :label="item.name" :value="item.id"></el-option>
  273. </el-select>
  274. </el-form-item>
  275. </el-form>
  276. <div slot="footer" class="dialog-footer">
  277. <el-button @click.native="addFormVisible = false">{{ $t('btn.cancel') }}</el-button>
  278. <el-button type="primary" @click="submitInsert" :loading="addLoading">{{ $t('btn.submit') }}</el-button>
  279. </div>
  280. </el-dialog>
  281. <!--用户详细信息弹出框-->
  282. <el-dialog :title="$t('Checkthedetails')" v-if="userDetailVisible" :visible.sync="userDetailVisible" :close-on-click-modal="false" customClass="customWidth" width="400px">
  283. <div class="line"><span>{{ $t('lable.name') }}</span>
  284. <span v-if="user.userNameNeedTranslate == '1'"><TranslationOpenDataText type='userName' :openid='userDetail.name'></TranslationOpenDataText></span>
  285. <span v-if="user.userNameNeedTranslate != '1'">{{userDetail.name}}</span>
  286. </div>
  287. <div class="line"><span>{{ $t('Worknumber') }}</span><span>{{userDetail.jobNumber}}</span></div>
  288. <div class="line"><span>{{ $t('lable.phone') }}</span><span>{{userDetail.phone}}</span></div>
  289. <div class="line"><span>{{ $t('lable.department') }}</span>
  290. <span v-if="user.userNameNeedTranslate == '1'"><TranslationOpenDataText type='departmentName' :openid='userDetail.departmentName'></TranslationOpenDataText></span>
  291. <span v-if="user.userNameNeedTranslate != '1'">{{userDetail.departmentName}}</span>
  292. </div>
  293. <div class="line"><span>{{ $t('costof') }}</span><span>{{userDetail.cost}}{{$t('Yuananhour')}}</span></div>
  294. <div slot="footer" class="dialog-footer">
  295. <el-button type="primary" @click="userDetailVisible = false" >{{ $t('btn.determine') }}</el-button>
  296. </div>
  297. </el-dialog>
  298. <!--导入时的设置界面 -->
  299. <el-dialog :title="$t('Financialdataimport')" v-if="importDialog" :visible.sync="importDialog" :close-on-click-modal="false" customClass="customWidth" width="550px">
  300. <el-form ref="form3" :model="importParam" >
  301. <el-form-item :label="$t('Itheimport')" >
  302. <!-- <div style="color:orange;">{{date}}</div> -->
  303. <el-date-picker v-model="date" type="month" :placeholder="$t('Selectmonth')" format="yyyy-MM" value-format="yyyy-MM"></el-date-picker>
  304. </el-form-item>
  305. <el-form-item prop="syncHistoryReport" >
  306. <el-checkbox :label="$t('Recalculatereportedcostsforthemonth')" v-model="importParam.syncHistoryReport"></el-checkbox>
  307. <span v-if="user.companyId == '936'">&nbsp;[ 按每月 {{$t(user.timeType.monthDays)}} 天 * 每天 {{$t(user.timeType.allday)}} 小时计算时薪 ]</span>
  308. </el-form-item>
  309. <el-form-item prop="syncUserCost" >
  310. <el-checkbox :label="$t('Synchronizeemployeemonthlycosttorganizationalstructure')" v-model="importParam.syncUserCost" ></el-checkbox>
  311. </el-form-item>
  312. </el-form>
  313. <div slot="footer" class="dialog-footer">
  314. <el-link v-if="user.timeType.financeAudit == '0'"
  315. style="float:left;"
  316. type="primary" :underline="false" @click="xzjl(),xzImportVisible = true">{{ $t('Viewtheimporthistory') }}</el-link>
  317. <el-upload ref="upload" action="#" :limit="1" :http-request="importFinance" :show-file-list="false" >
  318. <el-button type="primary" style="width:100%;" :loading="isUploading" >{{ $t('Selectthefilendstartimporting') }}</el-button>
  319. </el-upload>
  320. </div>
  321. </el-dialog>
  322. <!--无薪资人员列表-->
  323. <el-dialog :title="$t('wuXinZiRenYuanLieBiao')" v-if="showMissingDialog" :visible.sync="showMissingDialog" :close-on-click-modal="false" customClass="customWidth" width="600px">
  324. <el-table :data="missingFinanceUserList" highlight-current-row v-loading="listLoading" :height="400" style="width: 100%;">
  325. <el-table-column type="index"></el-table-column>
  326. <el-table-column prop="jobNumber" :label="$t('Worknumber')" sortable ></el-table-column>
  327. <el-table-column prop="name" :label="$t('lable.name')" >
  328. <template slot-scope="scope">
  329. <span v-if="user.userNameNeedTranslate == '1'"><TranslationOpenDataText type='userName' :openid='scope.row.name'></TranslationOpenDataText></span>
  330. <span v-if="user.userNameNeedTranslate != '1'">{{scope.row.name}}</span>
  331. </template>
  332. </el-table-column>
  333. </el-table>
  334. <div slot="footer" class="dialog-footer">
  335. <div style="float:left;color:#ff9900;">{{ $t('yiShangRenYuanDangYueYiTianXieGongShiQingDaoRuTaMenDeXinZi') }}</div>
  336. <el-button type="primary" @click="showMissingDialog = false" >{{ $t('Shutdown') }}</el-button>
  337. </div>
  338. </el-dialog>
  339. <el-dialog :title="$t('Customizesalaryitems')" show-header="false" v-if="itemDialog" :visible.sync="itemDialog" :close-on-click-modal="false" customClass="customWidth" width="500px" top="20px">
  340. <div style="margin-left:30px;">
  341. <!-- 111 -->
  342. <p><el-input size="medium" v-model.trim="customCols.monthCost" :placeholder="$t('Pleaseenteracustomsalaryitemname')" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  343. <template v-if="customCols.monthCost != null && customCols.monthCost != ''">
  344. {{ $t('Addttotalcost') }}
  345. <el-radio size="medium" v-model="customCols.monthCostCalculate" :label="1" style="margin-right:10px;margin-left:10px">{{ $t('state.yes') }}</el-radio>
  346. <el-radio size="medium" v-model="customCols.monthCostCalculate" :label="0">{{ $t('state.no') }}</el-radio>
  347. </template>
  348. </p>
  349. <p><el-input size="medium" v-model.trim="customCols.bonus" :placeholder="$t('Pleaseenteracustomsalaryitemname')" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  350. <template v-if="customCols.bonus != null && customCols.bonus != ''">
  351. {{ $t('Addttotalcost') }}
  352. <el-radio size="medium" v-model="customCols.bonusCalculate" :label="1" style="margin-right:10px;margin-left:10px">{{ $t('state.yes') }}</el-radio>
  353. <el-radio size="medium" v-model="customCols.bonusCalculate" :label="0">{{ $t('state.no') }}</el-radio>
  354. </template>
  355. </p>
  356. <p><el-input size="medium" v-model.trim="customCols.allowance" :placeholder="$t('Pleaseenteracustomsalaryitemname')" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  357. <template v-if="customCols.allowance != null && customCols.allowance != ''">
  358. {{ $t('Addttotalcost') }}
  359. <el-radio size="medium" v-model="customCols.allowanceCalculate" :label="1" style="margin-right:10px;margin-left:10px">{{ $t('state.yes') }}</el-radio>
  360. <el-radio size="medium" v-model="customCols.allowanceCalculate" :label="0">{{ $t('state.no') }}</el-radio>
  361. </template>
  362. </p>
  363. <p><el-input size="medium" v-model.trim="customCols.insuranceOld" :placeholder="$t('Pleaseenteracustomsalaryitemname')" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  364. <template v-if="customCols.insuranceOld != null && customCols.insuranceOld != ''">
  365. {{ $t('Addttotalcost') }}
  366. <el-radio size="medium" v-model="customCols.insuranceOldCalculate" :label="1" style="margin-right:10px;margin-left:10px">{{ $t('state.yes') }}</el-radio>
  367. <el-radio size="medium" v-model="customCols.insuranceOldCalculate" :label="0">{{ $t('state.no') }}</el-radio>
  368. </template>
  369. </p>
  370. <p><el-input size="medium" v-model.trim="customCols.insuranceMedical" :placeholder="$t('Pleaseenteracustomsalaryitemname')" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  371. <template v-if="customCols.insuranceMedical != null && customCols.insuranceMedical != ''">
  372. {{ $t('Addttotalcost') }}
  373. <el-radio size="medium" v-model="customCols.insuranceMedicalCalculate" :label="1" style="margin-right:10px;margin-left:10px">{{ $t('state.yes') }}</el-radio>
  374. <el-radio size="medium" v-model="customCols.insuranceMedicalCalculate" :label="0">{{ $t('state.no') }}</el-radio>
  375. </template>
  376. </p>
  377. <p><el-input size="medium" v-model.trim="customCols.insuranceLosejob" :placeholder="$t('Pleaseenteracustomsalaryitemname')" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  378. <template v-if="customCols.insuranceLosejob != null && customCols.insuranceLosejob != ''">
  379. {{ $t('Addttotalcost') }}
  380. <el-radio size="medium" v-model="customCols.insuranceLosejobCalculate" :label="1" style="margin-right:10px;margin-left:10px">{{ $t('state.yes') }}</el-radio>
  381. <el-radio size="medium" v-model="customCols.insuranceLosejobCalculate" :label="0">{{ $t('state.no') }}</el-radio>
  382. </template>
  383. </p>
  384. <p><el-input size="medium" v-model.trim="customCols.insuranceInjury" :placeholder="$t('Pleaseenteracustomsalaryitemname')" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  385. <template v-if="customCols.insuranceInjury != null && customCols.insuranceInjury != ''">
  386. {{ $t('Addttotalcost') }}
  387. <el-radio size="medium" v-model="customCols.insuranceInjuryCalculate" :label="1" style="margin-right:10px;margin-left:10px">{{ $t('state.yes') }}</el-radio>
  388. <el-radio size="medium" v-model="customCols.insuranceInjuryCalculate" :label="0">{{ $t('state.no') }}</el-radio>
  389. </template>
  390. </p>
  391. <p><el-input size="medium" v-model.trim="customCols.houseFund" :placeholder="$t('Pleaseenteracustomsalaryitemname')" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  392. <template v-if="customCols.houseFund != null && customCols.houseFund != ''">
  393. {{ $t('Addttotalcost') }}
  394. <el-radio size="medium" v-model="customCols.houseFundCalculate" :label="1" style="margin-right:10px;margin-left:10px">{{ $t('state.yes') }}</el-radio>
  395. <el-radio size="medium" v-model="customCols.houseFundCalculate" :label="0">{{ $t('state.no') }}</el-radio>
  396. </template>
  397. </p>
  398. <p><el-input size="medium" v-model.trim="customCols.field1" :placeholder="$t('Pleaseenterthenameofcustomsalaryitem1')" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  399. <template v-if="customCols.field1 != null && customCols.field1 != ''">
  400. {{ $t('Addttotalcost') }}
  401. <el-radio size="medium" v-model="customCols.field1Calculate" :label="1" style="margin-right:10px;margin-left:10px">{{ $t('state.yes') }}</el-radio>
  402. <el-radio size="medium" v-model="customCols.field1Calculate" :label="0">{{ $t('state.no') }}</el-radio>
  403. </template>
  404. </p>
  405. <p><el-input size="medium" v-model.trim="customCols.field2" :placeholder="$t('Pleaseenterthenameofcustomsalaryitem2')" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  406. <template v-if="customCols.field2 != null && customCols.field2 != ''">
  407. {{ $t('Addttotalcost') }}
  408. <el-radio size="medium" v-model="customCols.field2Calculate" :label="1" style="margin-right:10px;margin-left:10px">{{ $t('state.yes') }}</el-radio>
  409. <el-radio size="medium" v-model="customCols.field2Calculate" :label="0">{{ $t('state.no') }}</el-radio>
  410. </template>
  411. </p>
  412. <p><el-input size="medium" v-model.trim="customCols.field3" :placeholder="$t('Pleaseenterthenameofcustomsalaryitem3')" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  413. <template v-if="customCols.field3 != null && customCols.field3 != ''">
  414. {{ $t('Addttotalcost') }}
  415. <el-radio size="medium" v-model="customCols.field3Calculate" :label="1" style="margin-right:10px;margin-left:10px">{{ $t('state.yes') }}</el-radio>
  416. <el-radio size="medium" v-model="customCols.field3Calculate" :label="0">{{ $t('state.no') }}</el-radio>
  417. </template>
  418. </p>
  419. <p><el-input size="medium" v-model.trim="customCols.field4" :placeholder="$t('Pleaseenterthenameofcustomsalaryitem4')" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  420. <template v-if="customCols.field4 != null && customCols.field4 != ''">
  421. {{ $t('Addttotalcost') }}
  422. <el-radio size="medium" v-model="customCols.field4Calculate" :label="1" style="margin-right:10px;margin-left:10px">{{ $t('state.yes') }}</el-radio>
  423. <el-radio size="medium" v-model="customCols.field4Calculate" :label="0">{{ $t('state.no') }}</el-radio>
  424. </template>
  425. </p>
  426. <p><el-input size="medium" v-model.trim="customCols.field5" :placeholder="$t('Pleaseenterthenameofcustomsalaryitem5')" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  427. <template v-if="customCols.field5 != null && customCols.field5 != ''">
  428. {{ $t('Addttotalcost') }}
  429. <el-radio size="medium" v-model="customCols.field5Calculate" :label="1" style="margin-right:10px;margin-left:10px">{{ $t('state.yes') }}</el-radio>
  430. <el-radio size="medium" v-model="customCols.field5Calculate" :label="0">{{ $t('state.no') }}</el-radio>
  431. </template>
  432. </p>
  433. <p><el-input size="medium" v-model.trim="customCols.field6" :placeholder="$t('Pleaseenterthenameofcustomsalaryitem6')" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  434. <template v-if="customCols.field6 != null && customCols.field6 != ''">
  435. {{ $t('Addttotalcost') }}
  436. <el-radio size="medium" v-model="customCols.field6Calculate" :label="1" style="margin-right:10px;margin-left:10px">{{ $t('state.yes') }}</el-radio>
  437. <el-radio size="medium" v-model="customCols.field6Calculate" :label="0">{{ $t('state.no') }}</el-radio>
  438. </template>
  439. </p>
  440. <p><el-input size="medium" v-model.trim="customCols.field7" :placeholder="$t('Pleaseenterthenameofcustomsalaryitem7')" style="width:200px;margin-right:20px" maxlength="8"></el-input>
  441. <template v-if="customCols.field7 != null && customCols.field7 != ''">
  442. {{ $t('Addttotalcost') }}
  443. <el-radio size="medium" v-model="customCols.field7Calculate" :label="1" style="margin-right:10px;margin-left:10px">{{ $t('state.yes') }}</el-radio>
  444. <el-radio size="medium" v-model="customCols.field7Calculate" :label="0">{{ $t('state.no') }}</el-radio>
  445. </template>
  446. </p>
  447. </div>
  448. <div slot="footer" class="dialog-footer">
  449. <el-button type="primary" @click="itemDialog = false" >{{ $t('Shutdown') }}</el-button>
  450. <el-button type="primary" @click="saveItems()" >{{ $t('save') }}</el-button>
  451. </div>
  452. </el-dialog>
  453. <el-dialog :title="date+$t('weekDay.month')+' ' + $t('Noallocationratioofprojectworkinghoursisset')" show-header="false" v-if="settingDialog" :visible.sync="settingDialog"
  454. :close-on-click-modal="false" customClass="customWidth" width="1200px">
  455. <div>
  456. <div>
  457. <el-button :disabled="multipleSelection.length==0" @click="setPercent(true, null)">{{ $t('BatchSettingProportion') }}</el-button>
  458. <el-button :disabled="projectCols.length==0 || userCostSettingList.length == 0" @click="getLastMonthSetting">{{ $t('UselastmonthscaleSettings') }}</el-button>
  459. <!-- <el-button @click="showSelectProjectDialog">{{date}} 月待分摊项目设置</el-button> -->
  460. <el-button @click="showSelectProjectDialog">{{date}}{{ $t('Monthlyprojecttobeapportioned') }}</el-button>
  461. <el-button @click="intoAmortizationRatio">{{ $t('Importallocationratio') }}</el-button>
  462. </div>
  463. <el-table :data="userCostSettingList" highlight-current-row v-loading="costSettingLoading"
  464. ref="settingTable" @selection-change="handleSelectionChange"
  465. :height="400" style="width: 100%;">
  466. <el-table-column type="selection" width="55"></el-table-column>
  467. <el-table-column prop="name" :label="$t('lable.name')" sortable width="90" fixed="left">
  468. <template slot-scope="scope">
  469. <div>
  470. <span v-if="user.userNameNeedTranslate == '1'"><TranslationOpenDataText type='userName' :openid='scope.row.name'></TranslationOpenDataText></span>
  471. <span v-if="user.userNameNeedTranslate != '1'">{{scope.row.name}}</span>
  472. </div>
  473. </template>
  474. </el-table-column>
  475. <el-table-column :label="item.projectCode+'/'+item.projectName" v-for="(item) in projectCols" width="180" size="small"
  476. :key="item.id" align="center">
  477. <template slot-scope="scope">
  478. <span>{{scope.row[item.projectId]}}</span>%
  479. </template>
  480. </el-table-column>
  481. <el-table-column :label="$t('Settheproportion')" width="80" fixed="right">
  482. <template slot-scope="scope">
  483. <el-button size="small" @click="setPercent(false,scope.row)">{{ $t('setup') }}</el-button>
  484. </template>
  485. </el-table-column>
  486. </el-table>
  487. </div>
  488. <div slot="footer" class="dialog-footer">
  489. <el-button type="primary" @click="settingDialog = false" >{{ $t('Shutdown') }}</el-button>
  490. <el-button type="primary" @click="saveMonthSetting()" >{{ $t('save') }}</el-button>
  491. </div>
  492. </el-dialog>
  493. <el-dialog :title="date + $t('projectstobe assessed')" show-header="false" v-if="projectsDialog" :visible.sync="projectsDialog"
  494. :close-on-click-modal="false" customClass="customWidth" width="1000px">
  495. <el-select v-model="chosenProjects" multiple filterable clearable style="width:100%">
  496. <el-option v-for="item in allProjectList" :label="item.projectName" :key="item.id" :value="item.id"></el-option>
  497. </el-select>
  498. <el-checkbox v-model="chosenProjectsChecked" @change="chosenProjectsCheckedClick" style="margin: 20px 0;">{{chosenProjectsChecked ? $t('Deselectallitems') : $t('Selectallitems')}}</el-checkbox>
  499. <div slot="footer" class="dialog-footer">
  500. <el-button type="default" @click="projectsDialog = false" >{{ $t('Shutdown') }}</el-button>
  501. <el-button type="primary" @click="saveProjectSetting()" >{{ $t('btn.determine') }}</el-button>
  502. </div>
  503. </el-dialog>
  504. <el-dialog :title="proSetting.ymonth + $t('projectstobe assessed')" show-header="false" v-if="projSettingDialog" :visible.sync="projSettingDialog"
  505. :close-on-click-modal="false" customClass="customWidth" width="1000px">
  506. <el-radio-group v-model="proSetting.settingType" style="margin-top:15px;">
  507. <el-radio :label=0 >{{ $t('quanBuYiTianBaoXiangMu') }}</el-radio>
  508. <el-radio :label=1 >{{ $t('xuanZeBuFenXiangMu') }}</el-radio>
  509. <el-radio :label=2 >{{ $t('paiChuBuFenXiangMu') }}</el-radio>
  510. </el-radio-group>
  511. <el-select v-model="proSettingChosenProjects" multiple filterable clearable style="width:100%;margin-top:10px;" v-show="proSetting.settingType > 0" @change="updateChosenView()">
  512. <el-option v-for="item in allProjectList" :key="item.id" :label="item.projectName + '/'+ item.projectCode" :value="item.id">
  513. <span style="float: left;color: #8492a6;">{{ item.projectCode }}</span>
  514. <span style="float: right;font-size: 13px;">{{ item.projectName }}</span>
  515. </el-option>
  516. </el-select>
  517. <div slot="footer" class="dialog-footer">
  518. <el-button type="default" @click="projSettingDialog = false" >{{ $t('Shutdown') }}</el-button>
  519. <el-button type="primary" @click="saveCostProjectSetting()" >{{ $t('btn.determine') }}</el-button>
  520. </div>
  521. </el-dialog>
  522. <el-dialog :title="$t('allocationdata')" v-if="intoAmortizationDialog" :visible.sync="intoAmortizationDialog" customClass="customWidth" width="500px">
  523. <p>{{'1.' + $t('other.download')}}
  524. <el-link v-if="financialFlg" type="primary" style="margin-left:5px;" :underline="false" :href="'./upload/'+$t('allocationImporttemplates')+'.xlsx'" :download="$t('allocationImporttemplates') + '.xlsx'">{{$t('allocationImporttemplates')+'.xlsx'}}</el-link>
  525. <el-link v-else type="primary" style="margin-left:5px;" :underline="false" @click="financialClick()">{{$t('allocationImporttemplates')+'.xlsx'}}</el-link>
  526. </p>
  527. <p>{{'2.' + $t('other.projectsAndPeopleInThetemplate') }}</p>
  528. <p style="display: flex;justify-content: center;padding:1em 0">
  529. <el-upload ref="upload" action="#" :limit="1" :http-request="batchImportData" :show-file-list="false">
  530. <el-button type="primary" :underline="false" :loading="importingData">{{ $t('other.startImporting') }}</el-button>
  531. </el-upload>
  532. </p>
  533. </el-dialog>
  534. <el-dialog :title="$t('eachitemofemployeecost')" show-header="false" v-if="setPercentDialog" :visible.sync="setPercentDialog"
  535. :close-on-click-modal="false" customClass="customWidth" width="600px" >
  536. <div style="margin:0px 10px 10px 10px;">
  537. <span>{{ $t('Selecttheemployee') }}</span>
  538. <el-select v-if="user.userNameNeedTranslate != '1'" v-model="chosenNoReportUserIds" multiple filterable clearable style="width:330px;" collapse-tags>
  539. <el-option v-for="item in noReportUserList" :label="item.name" :key="item.id" :value="item.userId"></el-option>
  540. </el-select>
  541. <selectCat v-if="user.userNameNeedTranslate == '1'" @selectCal="selectCal" :subject="noReportUserList" :subjectId="chosenNoReportUserIds" :distinction="'2'" :size="'small'"></selectCat>
  542. <el-button @click="averageCost" >{{ $t('Automaticallocation') }}</el-button>
  543. </div>
  544. <el-divider ></el-divider>
  545. <!--项目列表 -->
  546. <el-form v-model="curPercentVal" label-width="365px" style="margin-top:10px;">
  547. <div class="nameList">
  548. <el-form-item v-for="item in projectCols" :label="item.projectName" :key="item.projectId" >
  549. {{ $t('Accountedfor') + ':' }}<el-input v-model="curPercentVal[item.projectId]" style="width:100px;" @input="updatePercentValue"></el-input>&nbsp;%
  550. </el-form-item>
  551. </div>
  552. <el-form-item >
  553. {{ $t('totalpercentage') + ':' }}{{totalPercent}}&nbsp;%
  554. </el-form-item>
  555. </el-form>
  556. <div slot="footer" class="dialog-footer">
  557. <el-button type="default" @click="setPercentDialog = false" >{{ $t('Shutdown') }}</el-button>
  558. <el-button type="primary" @click="setPercentSetting()" >{{ $t('btn.determine') }}</el-button>
  559. </div>
  560. </el-dialog>
  561. <!-- 导入结果说明 -->
  562. <el-dialog :title="$t('importingtheallocationratio')" v-if="showImportResult" :visible.sync="showImportResult" customClass="customWidth" width="500px">
  563. <div>
  564. <span>{{importResultMsg}}</span>
  565. </div>
  566. <span slot="footer" class="dialog-footer">
  567. <el-button type="primary" @click="showImportResult=false">{{ $t('btn.determine') }}</el-button>
  568. </span>
  569. </el-dialog>
  570. <el-dialog :title="$t('AmortizedDataExport')" v-if="exportFinanceDialog" :visible.sync="exportFinanceDialog" :close-on-click-modal="false" customClass="customWidth" width="500px">
  571. <div style="margin:30px;">
  572. <el-radio-group v-model="groupByCategory" >
  573. <el-radio :label="0">{{ $t('Exportbyproject') }}</el-radio>
  574. <el-radio :label="1">{{ $t('Exportbprojectcategory') }}</el-radio>
  575. </el-radio-group>
  576. <div style="margin-top: 20px;">
  577. <el-checkbox v-model="personnelAllocation">含人员分摊明细</el-checkbox>
  578. </div>
  579. </div>
  580. <div slot="footer" class="dialog-footer">
  581. <el-button @click="exportData" :loading="exportDataProcessing" type="primary">{{ $t('export.export') }}</el-button>
  582. </div>
  583. </el-dialog>
  584. </section>
  585. </template>
  586. <style scoped>
  587. .line {
  588. padding:10px;
  589. }
  590. .line span{
  591. font-size:18px;
  592. }
  593. .line span:nth-child(even){
  594. float:right;
  595. }
  596. </style>
  597. <style>
  598. .customWidth .el-dialog__body{
  599. padding-top: 0;
  600. padding-bottom: 0;
  601. }
  602. </style>
  603. <script>
  604. import { error } from 'dingtalk-jsapi';
  605. import util from "../../common/js/util";
  606. // 自定义select组件
  607. import selectCat from "@/components/select.vue"
  608. export default {
  609. components: {
  610. selectCat
  611. },
  612. data() {
  613. return {
  614. proSettingChosenProjects:[],
  615. proSetting: {
  616. ymonth:null,settingType:0,
  617. },
  618. projSettingDialog: false,
  619. operating: false,
  620. showMissingDialog: false,
  621. missingFinanceUserList: [],
  622. groupByCategory:0,
  623. personnelAllocation: true,
  624. exportFinanceDialog:false,
  625. exportMonth:null,
  626. exportDialog:false,
  627. headerCols:['monthCost','bonus', 'allowance', 'insuranceOld', 'insuranceMedical', 'insuranceLosejob', 'insuranceInjury', 'houseFund', 'customField1','customField2','customField3','customField4','customField5','customField6','customField7'],
  628. tblCols:[],
  629. costListRadio: 1,
  630. costSettingLoading: false,
  631. chosenNoReportUserIds:[],
  632. curPercentVal:{},
  633. setPercentDialog: false,
  634. chosenProjects:[],
  635. projectsDialog: false,
  636. projectCols:[],
  637. allProjectList:[],
  638. multipleSelection:[],
  639. userCostSettingList: [],
  640. settingDialog: false,
  641. radio:this.$t('lable.allStaff'),
  642. noReportUserList:[],
  643. allFinanceList:[],
  644. assignNoProUser: false,
  645. customFieldList:[],
  646. itemDialog: false,
  647. customCols:{},
  648. customColsi:{},
  649. // showNPDialog: false,
  650. npUserList:[],
  651. hasNoProjectUsers: false,
  652. isUploading:false,
  653. importDialog: false,
  654. importParam:{syncUserCost:true, syncHistoryReport:true},
  655. user: JSON.parse(sessionStorage.getItem("user")),
  656. permissions: JSON.parse(sessionStorage.getItem("permissions")),
  657. userDetailVisible: false,
  658. userDetail:{},
  659. date: null,
  660. tableHeight: 0,
  661. listLoading: false,
  662. list: [],
  663. addLoading: false,
  664. myChart: null,
  665. params: null,
  666. totalPercent:0,
  667. importVisible: false,
  668. shenhe: '',
  669. tabPosition: '0',
  670. reviewerVisible: false,
  671. reviewerRuleForm: {
  672. auditorId: ''
  673. },
  674. people: [],
  675. revaelse: '',
  676. reviewLis: [],
  677. ovReviewLis: [],
  678. xzImportVisible: false,
  679. xzList: [],
  680. intoAmortizationDialog : false ,
  681. importingData: false,
  682. importResultMsg:null,
  683. showImportResult:false,
  684. widthHtval: document.body.clientWidth - 230,
  685. deleteSelList: [],
  686. chosenProjectsChecked: false,
  687. exportDataProcessing: false,
  688. financialFlg: false,
  689. projectAllList: [], // 全部项目
  690. selectProjectList: [], // 分摊选中的项目
  691. notParticipatingInSharedProjectsValue: [],
  692. notParticipatingInSharedProjectsVisable: false,
  693. notParticipatingInSharedProjectsTitle: '',
  694. notParticipatingInSharedProjectsLoading: false,
  695. notParticipatingInSharedAllProject: false,
  696. notParticipatingInSharedProjectDisabled: false,
  697. };
  698. },
  699. methods: {
  700. selectAllItems() {
  701. if(this.notParticipatingInSharedAllProject) {
  702. this.notParticipatingInSharedProjectDisabled = true
  703. } else {
  704. this.notParticipatingInSharedProjectDisabled = false
  705. }
  706. },
  707. getTheCurrentMonth() {
  708. const d = new Date();
  709. const data = d.getFullYear() +'-'+ ((d.getMonth()+1) < 10? '0'+(d.getMonth()+1):d.getMonth()+1);
  710. return data
  711. },
  712. getAllocateSelectedItems() {
  713. this.http.get(`/financeExcludeProject/getProjects?useYM=${this.date || this.getTheCurrentMonth()}`,res => {
  714. const { isAll = 0, projectList } = res.data
  715. this.selectProjectList = projectList || []
  716. this.notParticipatingInSharedAllProject = isAll ? true : false
  717. })
  718. },
  719. getAllProjectList() {
  720. this.http.post('/project/getProjectList',{
  721. pageIndex: -1,
  722. pageSize: -1
  723. },res => {
  724. this.projectAllList = res.data
  725. })
  726. },
  727. submitNotParticipatingInSharedProject() {
  728. // if((!this.notParticipatingInSharedProjectsValue || this.notParticipatingInSharedProjectsValue.length <= 0) && !this.notParticipatingInSharedAllProject) {
  729. // this.$message({
  730. // message: '请选择项目',
  731. // type: 'warning'
  732. // })
  733. // return
  734. // }
  735. this.notParticipatingInSharedProjectsLoading = true
  736. this.http.post('/financeExcludeProject/addOrUpdateProjects',{
  737. projects: this.notParticipatingInSharedProjectsValue,
  738. useYM: this.date,
  739. isAll: this.notParticipatingInSharedAllProject ? 1 : 0
  740. },res => {
  741. this.notParticipatingInSharedProjectsLoading = false
  742. if(res.code == 'ok'){
  743. this.$message({
  744. message: '操作成功',
  745. type: 'success'
  746. })
  747. this.notParticipatingInSharedProjectsVisable = false
  748. this.loadMonthData()
  749. // this.getAllocateSelectedItems()
  750. }else{
  751. this.$message({
  752. message: res.msg,
  753. type: 'error'
  754. })
  755. }
  756. },err => {
  757. this.notParticipatingInSharedProjectsLoading = false
  758. this.$message({
  759. message: err,
  760. type: 'error'
  761. })
  762. })
  763. },
  764. getMonthProjSetting() {
  765. this.http.post('/cost-project-setting/get',{companyId: this.user.companyId, ymonth: this.date},res => {
  766. if(res.code == 'ok'){
  767. if (res.data.setting != null) {
  768. this.proSetting = res.data.setting;
  769. this.proSettingChosenProjects = JSON.parse(this.proSetting.projectJson);
  770. }
  771. if (this.allProjectList == null || this.allProjectList.length == 0) {
  772. this.allProjectList = res.data.allProjectList;
  773. }
  774. }else{
  775. this.$message({
  776. message: res.msg,
  777. type: 'error'
  778. })
  779. }
  780. },err => {
  781. this.$message({
  782. message: err,
  783. type: 'error'
  784. })
  785. })
  786. },
  787. saveCostProjectSetting() {
  788. //处理选中的项目
  789. if (this.proSetting.settingType == 0) {
  790. this.proSetting.projectJson = '[]';
  791. } else {
  792. this.proSetting.projectJson = JSON.stringify(this.proSettingChosenProjects);
  793. }
  794. this.http.post('/cost-project-setting/save',this.proSetting,res => {
  795. if(res.code == 'ok'){
  796. this.$message({
  797. message: this.$t('savesuccess'),
  798. type: 'success'
  799. })
  800. this.projSettingDialog = false;
  801. //刷新分摊数据显示
  802. this.assignToProject();
  803. }else{
  804. this.$message({
  805. message: res.msg,
  806. type: 'error'
  807. })
  808. }
  809. },err => {
  810. this.$message({
  811. message: er,
  812. type: 'error'
  813. })
  814. })
  815. },
  816. uploadTest(){
  817. this.http.post('/report/uploadThirdReportData',{
  818. yearMonth: this.date
  819. },res => {
  820. if(res.code == 'ok'){
  821. this.$message({
  822. message: this.$t('uploadedsuccessfully'),
  823. type: 'success'
  824. })
  825. }else{
  826. this.$message({
  827. message: res.msg,
  828. type: 'error'
  829. })
  830. }
  831. },err => {
  832. this.$message({
  833. message: er,
  834. type: 'error'
  835. })
  836. })
  837. },
  838. chosenProjectsCheckedClick() {
  839. if(this.chosenProjectsChecked) {
  840. let arr = []
  841. for(let i in this.allProjectList) {
  842. arr.push(this.allProjectList[i].id)
  843. }
  844. this.chosenProjects = arr
  845. } else {
  846. this.chosenProjects = []
  847. }
  848. },
  849. deleteSel(sel){
  850. this.deleteSelList = sel
  851. // console.log(sel);
  852. },
  853. deleteUsers(){
  854. this.$confirm(this.$t(this.$t('doyouwanttodeleteit')),this.$t('other.prompts'),{
  855. confirmButtonText: this.$t('btn.determine'),
  856. cancelButtonText: this.$t('btn.cancel'),
  857. type: 'warning'
  858. }).then(()=>{
  859. let ids = ''
  860. for(let i in this.deleteSelList){
  861. ids += this.deleteSelList[i].id + ','
  862. }
  863. ids = ids.substring(0,ids.length - 1)
  864. this.http.post('/finance/batchRemove',{
  865. ids: ids
  866. },res => {
  867. if(res.code == 'ok'){
  868. this.getList()
  869. this.$message({
  870. message: this.$t('message.successfullyDeleted'),
  871. type: 'success'
  872. })
  873. }else {
  874. this.$message({
  875. message: res.msg,
  876. type: 'error'
  877. })
  878. }
  879. },err => {
  880. this.$message({
  881. message: err,
  882. type: 'error'
  883. })
  884. })
  885. }).catch(()=>{
  886. this.$message({
  887. type: 'info',
  888. message: this.$t('thedeletionhasbeencancelled')
  889. })
  890. })
  891. },
  892. exportFinance() {
  893. this.isUploading = true;
  894. this.http.post('/finance/exportFinance', {
  895. date: this.exportMonth
  896. },res =>{
  897. this.isUploading = false;
  898. if(res.code == 'ok') {
  899. this.downloadByA({name:this.exportMonth+this.$t('financialdata') + '.xlsx', url: res.data});
  900. }
  901. },error => {
  902. this.$message({
  903. message: error,
  904. type: "error"
  905. });
  906. })
  907. },
  908. arrter() {
  909. this.http.post('/user/getEmployeeList', {
  910. departmentId: '-1',
  911. pageIndex: 1,
  912. // pageSize: 99999
  913. pageSize: -1
  914. },res =>{
  915. if(res.code == 'ok') {
  916. this.people = res.data.records
  917. }
  918. },error => {
  919. this.$message({
  920. message: error,
  921. type: "error"
  922. });
  923. })
  924. },
  925. addreviewer() {
  926. this.http.post('/finance-auditor/get', {
  927. companyId: this.user.companyId
  928. },
  929. res => {
  930. if (res.code == "ok") {
  931. // console.log(res.data, '数据')
  932. if(res.data) {
  933. this.reviewerRuleForm.auditorId = res.data.auditorId
  934. } else {
  935. this.reviewerRuleForm.auditorId = ''
  936. }
  937. }
  938. },error => {
  939. this.$message({
  940. message: error,
  941. type: "error"
  942. });
  943. }
  944. );
  945. },
  946. // 提交审核人
  947. submitreviewerRuleForm(formName) {
  948. this.$refs[formName].validate((valid) => {
  949. if (valid) {
  950. this.reviewerRuleForm.companyId = this.user.companyId
  951. this.http.post('/finance-auditor/save', this.reviewerRuleForm,
  952. res =>{
  953. if(res.code == 'ok') {
  954. this.$message({
  955. message: this.$t('operationissuccessful'),
  956. type: "success"
  957. });
  958. this.addreviewer()
  959. } else {
  960. this.$message({
  961. message: this.$t('operationfailure'),
  962. type: "error"
  963. });
  964. }
  965. },error => {
  966. this.$message({
  967. message: error,
  968. type: "error"
  969. });
  970. })
  971. this.reviewerVisible = false
  972. } else {
  973. return false;
  974. }
  975. });
  976. },
  977. handleCloses(done) {
  978. var formName = 'reviewerRuleForm'
  979. this.$refs[formName].resetFields();
  980. done()
  981. },
  982. // 审核
  983. audits() {
  984. this.shenhe = this.$t('importtheaudits')
  985. this.importVisible = true
  986. },
  987. switchCostList() {
  988. //已填日报的人员成本
  989. if (this.costListRadio == 1) {
  990. this.assignNoProUser=false;
  991. this.assignToProject();
  992. } else if (this.costListRadio == 2) {
  993. //全部人员成本
  994. this.assignNoProUser=true;
  995. this.assignToProject();
  996. }
  997. },
  998. getLastMonthSetting() {
  999. this.costSettingLoading = true;
  1000. var dataArr = this.date.split('-');
  1001. var year = dataArr[0];
  1002. var month = dataArr[1];
  1003. if (parseInt(month) == 1) {
  1004. year = parseInt(year) -1;
  1005. month = 12;
  1006. } else {
  1007. month = parseInt(month) -1;
  1008. if (month < 10) {
  1009. month = '0'+month;
  1010. }
  1011. }
  1012. var lastMonth = year + '-' + month;
  1013. this.http.post('/project-percentage/getMonthSetting', {ymonth: lastMonth},
  1014. res => {
  1015. this.costSettingLoading = false;
  1016. if (res.code == "ok") {
  1017. this.projectCols = res.data.financeProjects;
  1018. this.allProjectList = res.data.allProjectList;
  1019. this.userCostSettingList = res.data.userCostSetting;
  1020. //上次如果没有配置过,需要初始化
  1021. for (var i=0;i<this.noReportUserList.length; i++) {
  1022. var rUser = this.noReportUserList[i];
  1023. //检查当前列表中的无项目人员是否在之前的里面存在,如果不在需要加上去
  1024. if (this.userCostSettingList.filter(c=>c.id == rUser.userId).length == 0) {
  1025. var item = {name: rUser.name, id: rUser.userId};
  1026. this.projectCols.forEach(p=>{
  1027. item[p.projectId] = 0;
  1028. });
  1029. this.userCostSettingList.push(item);
  1030. }
  1031. }
  1032. this.$nextTick(()=>{
  1033. this.$refs.settingTable.doLayout();
  1034. })
  1035. } });
  1036. },
  1037. // 补齐注释,一月三十号
  1038. financialClick() {
  1039. this.http.post('/project-percentage/getTemplate', {ymonth: this.date},
  1040. res => {
  1041. if (res.code == "ok") {
  1042. let fName = this.$t('allocationImporttemplates' ) + '.xlsx'
  1043. var filePath = res.data;
  1044. const a = document.createElement('a'); // 创建a标签
  1045. a.setAttribute('download', fName);// download属性
  1046. a.setAttribute('href', filePath);// href链接
  1047. a.click(); //自执行点击事件
  1048. a.remove();
  1049. } else {
  1050. this.$message({
  1051. message: res.msg,
  1052. type: "error"
  1053. });
  1054. }
  1055. });
  1056. },
  1057. //获取当月的无项目工时人员的分配比例设置
  1058. getMonthSetting() {
  1059. this.costSettingLoading = true;
  1060. this.http.post('/project-percentage/getMonthSetting', {ymonth: this.date},
  1061. res => {
  1062. this.costSettingLoading = false;
  1063. if (res.code == "ok") {
  1064. this.projectCols = res.data.financeProjects;
  1065. this.allProjectList = res.data.allProjectList;
  1066. this.userCostSettingList = res.data.userCostSetting;
  1067. if(res.data.financeProjects.length <= 0 && res.data.userCostSetting <= 0) {
  1068. this.financialFlg = true
  1069. } else {
  1070. this.financialFlg = false
  1071. }
  1072. //上次如果没有配置过,需要初始化
  1073. for (var i=0;i<this.noReportUserList.length; i++) {
  1074. var rUser = this.noReportUserList[i];
  1075. //检查当前列表中的无项目人员是否在之前的里面存在,如果不在需要加上去
  1076. if (this.userCostSettingList.filter(c=>c.id == rUser.userId).length == 0) {
  1077. var item = {name: rUser.name, id: rUser.userId};
  1078. this.projectCols.forEach(p=>{
  1079. item[p.projectId] = 0;
  1080. });
  1081. this.userCostSettingList.push(item);
  1082. }
  1083. }
  1084. this.$nextTick(()=>{
  1085. this.$refs.settingTable.doLayout();
  1086. })
  1087. } });
  1088. },
  1089. //提交无工时人员的分配设置
  1090. saveMonthSetting() {
  1091. //检查数据是否都分配到100%了,防止由于修改了项目列而导致之前的数据不正确的情况
  1092. var errorList = this.userCostSettingList.filter(u=>{
  1093. let totalPercent = 0.00;
  1094. this.projectCols.forEach(p=>{
  1095. totalPercent += parseFloat(u[p.projectId]);
  1096. });
  1097. totalPercent = totalPercent.toFixed(2);
  1098. if (totalPercent != 100) {
  1099. return true;
  1100. } else {
  1101. return false;
  1102. }
  1103. });
  1104. if (errorList.length > 0) {
  1105. var nameList = errorList.map(e=>e.name);
  1106. this.$message({type:'error', message:this.$t('proportionofassignedpersonnelisnot ')+'100%:'+nameList});
  1107. return;
  1108. }
  1109. this.http.post('/project-percentage/saveMonthSetting', {projectCols: JSON.stringify(this.projectCols),
  1110. ymonth: this.date, userSettings: JSON.stringify(this.userCostSettingList)},
  1111. res => {
  1112. if (res.code == "ok") {
  1113. this.$message({type:'success', message:this.$t('savesuccess')});
  1114. this.settingDialog = false;
  1115. } else {
  1116. this.$message({type:'error', message:this.$t('erroroccurred')+':'+res.msg});
  1117. }});
  1118. },
  1119. updatePercentValue() {
  1120. var total = 0.0;
  1121. this.projectCols.forEach(p=>{
  1122. total += parseFloat(this.curPercentVal[p.projectId]);
  1123. })
  1124. this.totalPercent = total.toFixed(2);
  1125. this.$forceUpdate();
  1126. },
  1127. averageCost() {
  1128. var avg = (100/this.projectCols.length).toFixed(1);
  1129. //最后一个用100减去前面的总和,保证最终合计为100
  1130. for (var i=0;i<this.projectCols.length; i++) {
  1131. if (i < this.projectCols.length -1) {
  1132. this.curPercentVal[this.projectCols[i].projectId] = avg;
  1133. } else {
  1134. this.curPercentVal[this.projectCols[i].projectId] = (100-avg*(this.projectCols.length-1)).toFixed(1);
  1135. }
  1136. }
  1137. this.updatePercentValue();
  1138. this.$forceUpdate();
  1139. },
  1140. setPercent(isBatch, row) {
  1141. this.setPercentDialog = true;
  1142. this.chosenNoReportUserIds = [];
  1143. if (!isBatch) {
  1144. this.chosenNoReportUserIds.push(row.id);
  1145. //获取当前比例
  1146. this.projectCols.forEach(p=>{
  1147. this.curPercentVal[p.projectId] = row[p.projectId];
  1148. });
  1149. } else {
  1150. //批量处理
  1151. this.multipleSelection.forEach(m=>{
  1152. this.chosenNoReportUserIds.push(m.id);
  1153. })
  1154. //批量时获取第一条的比例进行加载
  1155. this.projectCols.forEach(p=>{
  1156. this.curPercentVal[p.projectId] = this.multipleSelection[0][p.projectId];
  1157. });
  1158. }
  1159. this.updatePercentValue();
  1160. },
  1161. //确认设置的项目列
  1162. saveProjectSetting() {
  1163. this.projectsDialog = false;
  1164. this.projectCols = [];
  1165. this.chosenProjects.forEach(c=>{
  1166. var item = this.allProjectList.filter(a=>a.id == c)[0];
  1167. this.projectCols.push({projectId: item.id, projectName: item.projectName, projectCode: item.projectCode});
  1168. });
  1169. this.$nextTick(()=>{
  1170. this.$refs.settingTable.doLayout();
  1171. })
  1172. },
  1173. handleProjectSelectionChange(val) {
  1174. this.projectSelection = val;
  1175. },
  1176. showSelectProjectDialog() {
  1177. //设置选中状态
  1178. this.chosenProjects = [];
  1179. this.chosenProjectsChecked = false
  1180. this.projectCols.forEach(item=>{
  1181. this.chosenProjects.push(item.projectId);
  1182. })
  1183. this.projectsDialog = true;
  1184. },
  1185. setPercentSetting() {
  1186. //检测是否填写的情况下,是否达到100%
  1187. if (this.totalPercent != 100) {
  1188. this.$message({
  1189. message: this.$t('sumoftheallocationsmustbe'),
  1190. type: "error"
  1191. });
  1192. return;
  1193. }
  1194. this.setPercentDialog = false;
  1195. this.chosenNoReportUserIds.forEach(u=>{
  1196. var targetU = this.userCostSettingList.filter(a=>a.id == u)[0];
  1197. //遍历项目
  1198. this.projectCols.forEach(p=>{
  1199. // targetU[p.projectId] = this.curPercentVal[p.projectId];
  1200. this.$set(targetU, p.projectId, this.curPercentVal[p.projectId]);
  1201. })
  1202. });
  1203. this.userCostSettingList.splice(1,0);
  1204. },
  1205. showSettingDialog() {
  1206. this.settingDialog = true;
  1207. this.getMonthSetting();
  1208. },
  1209. showProjSettingDialog() {
  1210. this.projSettingDialog = true;
  1211. this.proSetting.ymonth = this.date;
  1212. this.proSetting.companyId = this.user.companyId;
  1213. this.getMonthProjSetting();
  1214. },
  1215. handleSelectionChange(val) {
  1216. this.multipleSelection = val;
  1217. },
  1218. switchList() {
  1219. if (this.radio == this.$t('lable.allStaff')) {
  1220. this.list = this.allFinanceList;
  1221. } else {
  1222. this.list = this.noReportUserList;
  1223. }
  1224. },
  1225. downloadByA(row) {
  1226. const a = document.createElement('a'); // 创建a标签
  1227. a.setAttribute('download', row.name);// download属性
  1228. if (row.url.indexOf('upload/') == -1) {
  1229. row.url = '/upload/' +row.url;
  1230. }
  1231. a.setAttribute('href', row.url);// href链接
  1232. a.click();// 自执行点击事件
  1233. a.remove();
  1234. },
  1235. getTemplate() {
  1236. this.http.post('/finance/getTemplate', {companyId: this.user.companyId},
  1237. res => {
  1238. if (res.code == "ok") {
  1239. if (res.data.indexOf('xlsx') > 0) {
  1240. this.downloadByA({name:this.$t('financialcoststatement')+ '.xlsx', url:res.data});
  1241. } else {
  1242. this.downloadByA({name:this.$t('financialcoststatement')+ '.xls', url:res.data});
  1243. }
  1244. }});
  1245. },
  1246. saveItems() {
  1247. // let savefields = {
  1248. // monthCost : this.customCols.monthCost,
  1249. // bonus : this.customCols.bonus,
  1250. // allowance : this.customCols.allowance,
  1251. // insuranceOld : this.customCols.insuranceOld,
  1252. // insuranceMedical : this.customCols.insuranceMedical,
  1253. // insuranceLosejob : this.customCols.insuranceLosejob,
  1254. // insuranceInjury : this.customCols.insuranceInjury,
  1255. // houseFund : this.customCols.houseFund,
  1256. // field1 : this.customCols.field1,
  1257. // field2 : this.customCols.field2,
  1258. // field3 : this.customCols.field3
  1259. // }
  1260. if(this.customCols.field1 != null && this.customCols.field1 != ''){
  1261. if(this.customCols.field1Calculate == null){
  1262. this.$message({
  1263. message: this.$t('choosewhethertoincludethetotalcost'),
  1264. type: 'warning'
  1265. })
  1266. return
  1267. }
  1268. }
  1269. if(this.customCols.field2 != null && this.customCols.field2 != ''){
  1270. if(this.customCols.field1Calculate == null){
  1271. this.$message({
  1272. message: this.$t('choosewhethertoincludethetotalcost'),
  1273. type: 'warning'
  1274. })
  1275. return
  1276. }
  1277. }
  1278. if(this.customCols.field3 != null && this.customCols.field3 != ''){
  1279. if(this.customCols.field1Calculate == null){
  1280. this.$message({
  1281. message: this.$t('choosewhethertoincludethetotalcost'),
  1282. type: 'warning'
  1283. })
  1284. return
  1285. }
  1286. }
  1287. this.http.post('/finance-tblcuscol/save', this.customCols,
  1288. res => {
  1289. if (res.code == "ok") {
  1290. this.itemDialog = false;
  1291. this.getCustomColumn();
  1292. }});
  1293. this.$forceUpdate();
  1294. },
  1295. showItemDialog() {
  1296. this.customCols = JSON.parse(JSON.stringify(this.customColsi))
  1297. this.itemDialog = true;
  1298. },
  1299. notParticipatingInSharedProjects() {
  1300. this.notParticipatingInSharedProjectsValue = (this.selectProjectList || []).map(item => item.projectId)
  1301. this.notParticipatingInSharedProjectsTitle = this.date
  1302. this.selectAllItems()
  1303. this.notParticipatingInSharedProjectsVisable = true
  1304. },
  1305. //获取自定义的字段
  1306. getCustomColumn() {
  1307. this.http.post('/finance-tblcuscol/getAll', {companyId: this.user.companyId},
  1308. res => {
  1309. if (res.code == "ok") {
  1310. this.customColsi = res.data;
  1311. this.tblCols = [];
  1312. this.tblCols.push(this.customColsi.monthCost);
  1313. this.tblCols.push(this.customColsi.bonus);
  1314. this.tblCols.push(this.customColsi.allowance);
  1315. this.tblCols.push(this.customColsi.insuranceOld);
  1316. this.tblCols.push(this.customColsi.insuranceMedical);
  1317. this.tblCols.push(this.customColsi.insuranceLosejob);
  1318. this.tblCols.push(this.customColsi.insuranceInjury);
  1319. this.tblCols.push(this.customColsi.houseFund);
  1320. if (this.customColsi.field1 != null) {
  1321. this.tblCols.push(this.customColsi.field1);
  1322. }
  1323. if (this.customColsi.field2 != null) {
  1324. this.tblCols.push(this.customColsi.field2);
  1325. }
  1326. if (this.customColsi.field3 != null) {
  1327. this.tblCols.push(this.customColsi.field3);
  1328. }
  1329. if (this.customColsi.field4 != null) {
  1330. this.tblCols.push(this.customColsi.field4);
  1331. }
  1332. if (this.customColsi.field5 != null) {
  1333. this.tblCols.push(this.customColsi.field5);
  1334. }
  1335. if (this.customColsi.field6 != null) {
  1336. this.tblCols.push(this.customColsi.field6);
  1337. }
  1338. if (this.customColsi.field7 != null) {
  1339. this.tblCols.push(this.customColsi.field7);
  1340. }
  1341. }});
  1342. },
  1343. // },
  1344. getProjects() {
  1345. this.http.post('/project/getSimpleProjectList', {companyId: this.user.companyId},
  1346. res => {
  1347. if (res.code == "ok") {
  1348. this.allProjectList = res.data.allProjectList;
  1349. }});
  1350. },
  1351. // showNoProjectUsers() {
  1352. // this.showNPDialog = true;
  1353. // this.http.post('/finance/getNoProjectUsers', {yearMonth: this.date},
  1354. // res => {
  1355. // if (res.code == "ok") {
  1356. // this.npUserList = res.data;
  1357. // }});
  1358. // },
  1359. assignToProject(){
  1360. var _this = this;
  1361. this.http.post('/finance/getTimeCost', {yearMonth: this.date, assignNoProUser: this.assignNoProUser},
  1362. res => {
  1363. if (res.code == "ok") {
  1364. for(var i in res.data.costList) {
  1365. if(i>20) {
  1366. this.widthHtval = +this.widthHtval + 40
  1367. } else {
  1368. this.widthHtval = document.body.clientWidth - 230
  1369. }
  1370. }
  1371. // console.log(res.data, '图表数据', this.widthHtval)
  1372. var xList = [], yList = [], list = res.data.costList, totalMoneyCost = res.data.totalMoneyCost;
  1373. //计算costList合计的成本
  1374. var totalC = 0;
  1375. for (var i=0;i<list.length; i++) {
  1376. totalC += list[i].cost;
  1377. }
  1378. this.missingFinanceUserList = res.data.missingFinanceUserList;
  1379. var nopCost = 0;
  1380. if (res.data.noProjectItem.project != null) {
  1381. this.hasNoProjectUsers = true;
  1382. nopCost = res.data.noProjectItem.cost;
  1383. } else {
  1384. this.hasNoProjectUsers = false;
  1385. }
  1386. for(var i in list) {
  1387. xList.push(list[i].project);
  1388. yList.push({
  1389. "value": list[i].cost,
  1390. "id": list[i].id,
  1391. "time": list[i].workingTime
  1392. });
  1393. }
  1394. var myChart = echarts.init(document.getElementById("container"));
  1395. // 设置图表
  1396. myChart.resize({
  1397. width: this.widthHtval
  1398. })
  1399. _this.myChart = myChart;
  1400. var option = {
  1401. title: {
  1402. text: _this.assignNoProUser ? _this.$t('costintotal') + totalMoneyCost + _this.$t('yuan')
  1403. +(_this.hasNoProjectUsers?","+ _this.$t('projectpersonnelcostincluded') + nopCost + _this.$t('yuan'):"")
  1404. : _this.$t('costintotal') + totalMoneyCost + _this.$t('yuan'),
  1405. left:'left',
  1406. },
  1407. grid : {
  1408. top : 40, //距离容器上边界40像素
  1409. // bottom: 100, //距离容器下边界30像素
  1410. bottom: 40, //距离容器下边界30像素
  1411. left: 100,
  1412. right: 100
  1413. },
  1414. // 工具箱
  1415. toolbox: {
  1416. show: true,
  1417. feature:{
  1418. saveAsImage:{
  1419. show:true
  1420. },
  1421. restore:{
  1422. show:true
  1423. },
  1424. magicType:{
  1425. type:['line','bar']
  1426. },
  1427. }
  1428. },
  1429. tooltip:{
  1430. trigger:'axis',
  1431. formatter: function (params,ticket,callback) {
  1432. var res = params[0].name + "<br/>"+ _this.$t('workcost')+" : " + params[0].data.value
  1433. + _this.$t('yuan')+"<br/>"+ _this.$t('screening.workTime')+" : " + params[0].data.time + _this.$t('time.hour');
  1434. _this.params = params;
  1435. return res;
  1436. }
  1437. },
  1438. xAxis: {
  1439. data: xList,
  1440. axisLabel: {
  1441. interval:0,rotate:20
  1442. }
  1443. },
  1444. yAxis: [{
  1445. type : 'value',
  1446. axisLabel: {
  1447. formatter:'{value} ('+ _this.$t('yuan')+')'
  1448. }
  1449. }],
  1450. series: [{
  1451. name: _this.$t('screening.workTime')+'(h)',
  1452. type: 'bar',
  1453. barMaxWidth: 30,
  1454. data: yList,
  1455. }]
  1456. };
  1457. option && myChart.setOption(option,{notMerge: true});
  1458. // myChart.getZr().on('click', params => {
  1459. // const pointInPixel = [params.offsetX, params.offsetY];
  1460. // if (myChart.containPixel('grid', pointInPixel)) {
  1461. // console.log(_this.params)
  1462. // if(_this.radio=='项目') {
  1463. // _this.$router.push("/cost/" + _this.params[0].data.id + "/" + _this.params[0].name);
  1464. // }
  1465. // }
  1466. // });
  1467. } else {
  1468. this.$message({
  1469. message: res.msg,
  1470. type: "error"
  1471. });
  1472. }
  1473. },
  1474. error => {
  1475. this.$message({
  1476. message: error,
  1477. type: "error"
  1478. });
  1479. });
  1480. },
  1481. //导出财务数据
  1482. exportData() {
  1483. this.exportDataProcessing = true;
  1484. this.http.post('/finance/exportData', {
  1485. date: this.date,
  1486. assignNoProUser: this.assignNoProUser,
  1487. groupByCategory: this.groupByCategory,
  1488. onlyTotal: this.personnelAllocation ? 1 : 0
  1489. },
  1490. res => {
  1491. this.exportDataProcessing = false;
  1492. if (res.code == "ok") {
  1493. this.exportFinanceDialog = false;
  1494. var aTag = document.createElement('a');
  1495. aTag.download = this.$t('financialcoststatisticss')+".xlsx";
  1496. aTag.href = res.data;
  1497. aTag.click();
  1498. } else {
  1499. this.$message({
  1500. message: res.msg,
  1501. type: "error"
  1502. });
  1503. }
  1504. },
  1505. error => {
  1506. this.exportDataProcessing = false;
  1507. this.$message({
  1508. message: error,
  1509. type: "error"
  1510. });
  1511. });
  1512. },
  1513. getSummaries(param) {
  1514. const { columns, data } = param;
  1515. const sums = [];
  1516. columns.forEach((column, index) => {
  1517. if (index === 0) {
  1518. sums[index] = this.$t('zongjia');
  1519. return;
  1520. }
  1521. if (index === 1){
  1522. sums[index] = '';
  1523. return
  1524. }
  1525. if (index === 2 && this.user.timeType.financeJobnumEnabled == 1) {
  1526. sums[index] = '';
  1527. return;
  1528. }
  1529. const values = data.map(item => Number(item[column.property]));
  1530. if (!values.every(value => isNaN(value))) {
  1531. sums[index] = values.reduce((prev, curr) => {
  1532. const value = Number(curr);
  1533. if (!isNaN(value)) {
  1534. return prev + curr;
  1535. } else {
  1536. return prev;
  1537. }
  1538. }, 0);
  1539. sums[index] = sums[index].toFixed(2) + this.$t('yuan');
  1540. } else {
  1541. sums[index] = 'N/A';
  1542. }
  1543. });
  1544. return sums;
  1545. },
  1546. loadMonthData() {
  1547. //改变月份
  1548. this.getList();
  1549. this.assignToProject();
  1550. this.getMonths()
  1551. this.getAllocateSelectedItems()
  1552. },
  1553. // 批量导入人员薪资
  1554. importFinance(item) {
  1555. //首先判断文件类型
  1556. let str = item.file.name.split(".");
  1557. let format = str[str.length - 1];
  1558. if (format != "xls" && format != "xlsx") {
  1559. this.$message({
  1560. message: this.$t('other.PleaseselecttheXLSorXLSXfile'),
  1561. type: "error"
  1562. });
  1563. } else {
  1564. this.listLoading = true;
  1565. let formData = new FormData();
  1566. formData.append("file", item.file);
  1567. formData.append("companyId", this.user.companyId);
  1568. formData.append("yearMonth", this.date);
  1569. formData.append("syncUserCost", this.importParam.syncUserCost);
  1570. formData.append("syncHistoryReport", this.importParam.syncHistoryReport);
  1571. this.isUploading = true;
  1572. let urls = ''
  1573. if(this.user.timeType.financeAudit == '1') {
  1574. urls = '/finance-import/submitImport'
  1575. } else {
  1576. urls = '/finance/importData'
  1577. }
  1578. // this.http.uploadFile('/finance/importData', formData,
  1579. this.http.uploadFile(urls, formData,
  1580. res => {
  1581. // console.log(this.user.timeType.financeAudit, '看看数据')
  1582. this.$refs.upload.clearFiles();
  1583. this.listLoading = false;
  1584. this.isUploading = false;
  1585. if (res.code == "ok") {
  1586. if (this.user.timeType.financeAudit == 1 ) {
  1587. this.$message({
  1588. message: this.$t('waiforverification'),
  1589. type: "warning"
  1590. });
  1591. this.loadMonthData();
  1592. } else {
  1593. this.$message({
  1594. message: this.$t('other.importSuccess'),
  1595. type: "success"
  1596. });
  1597. }
  1598. this.importDialog = false;
  1599. //重新读取列表
  1600. this.getList();
  1601. } else {
  1602. this.$message({
  1603. message: res.msg,
  1604. type: "error"
  1605. });
  1606. }
  1607. },
  1608. error => {
  1609. this.$refs.upload.clearFiles();
  1610. this.listLoading = false;
  1611. this.$message({
  1612. message: error,
  1613. type: "error"
  1614. });
  1615. });
  1616. }
  1617. },
  1618. // 导入提交审核
  1619. // submitReview(formData) {
  1620. // this.http.uploadFile(' /finance-import/submitImport', formData,
  1621. // res => {
  1622. // if (res.code == "ok") {
  1623. // console.log(res.data, '来的数据')
  1624. // } else {
  1625. // this.$message({
  1626. // message: res.msg,
  1627. // type: "error"
  1628. // });
  1629. // }
  1630. // },
  1631. // error => {
  1632. // this.$refs.upload.clearFiles();
  1633. // this.listLoading = false;
  1634. // this.$message({
  1635. // message: error,
  1636. // type: "error"
  1637. // });
  1638. // });
  1639. // },
  1640. //获取项目列表
  1641. getList() {
  1642. this.listLoading = true;
  1643. this.http.post('/finance/getByMonth', {
  1644. companyId: this.user.companyId,
  1645. yearMonth: this.date
  1646. },
  1647. res => {
  1648. this.listLoading = false;
  1649. if (res.code == "ok") {
  1650. var list = res.data;
  1651. this.allFinanceList = list;
  1652. this.noReportUserList = list.filter(r=>r.hasReport == 0);
  1653. if(this.radio == this.$t('lable.allStaff')){
  1654. this.list = this.allFinanceList;
  1655. }else{
  1656. this.list = this.noReportUserList
  1657. }
  1658. } else {
  1659. this.$message({
  1660. message: res.msg,
  1661. type: "error"
  1662. });
  1663. }
  1664. },
  1665. error => {
  1666. this.listLoading = false;
  1667. this.$message({
  1668. message: error,
  1669. type: "error"
  1670. });
  1671. });
  1672. },
  1673. // 获取当月的审核状态
  1674. getMonths() {
  1675. this.http.post('/finance-import/getStatus', {
  1676. companyId: this.user.companyId,
  1677. yearMonth: this.date
  1678. },
  1679. res => {
  1680. this.listLoading = false;
  1681. if (res.code == "ok") {
  1682. // console.log(res.data, '审核状态')
  1683. if(res.data) {
  1684. if(res.data.state == '0') {
  1685. this.revaelse = this.$t('state.WaitingAudit')
  1686. this.tabPosition = '0'
  1687. } else if(res.data.state == '1') {
  1688. this.revaelse = this.$t('Auditrecords')
  1689. this.tabPosition = '1'
  1690. }else if (res.data.state == '2') {
  1691. this.revaelse = this.$t('state.rejected')
  1692. this.tabPosition = '2'
  1693. } else if (res.data.state == '3') {
  1694. this.revaelse = this.$t('state.undone')
  1695. this.tabPosition = '-1'
  1696. }
  1697. this.getReviewList()
  1698. } else {
  1699. this.revaelse = ''
  1700. }
  1701. } else {
  1702. this.$message({
  1703. message: res.msg,
  1704. type: "error"
  1705. });
  1706. }
  1707. },
  1708. error => {
  1709. this.listLoading = false;
  1710. this.$message({
  1711. message: error,
  1712. type: "error"
  1713. });
  1714. });
  1715. },
  1716. // 获取审核列表
  1717. getReviewList() {
  1718. this.http.post('/finance-import/list', {
  1719. companyId: this.user.companyId,
  1720. },
  1721. res => {
  1722. if (res.code == "ok") {
  1723. // console.log(res.data, '拿到的数据')
  1724. this.ovReviewLis = res.data
  1725. if(this.tabPosition == 0) {
  1726. this.reviewLis = res.data.pendingList
  1727. } else if(this.tabPosition == 1) {
  1728. this.reviewLis = res.data.passList
  1729. } else if(this.tabPosition == 2) {
  1730. this.reviewLis = res.data.rejectList
  1731. } else {
  1732. this.reviewLis = res.data.cancelList
  1733. }
  1734. // console.log(this.reviewLis, '数据')
  1735. } else {
  1736. this.$message({
  1737. message: res.msg,
  1738. type: "error"
  1739. });
  1740. }
  1741. },
  1742. error => {
  1743. this.$message({
  1744. message: error,
  1745. type: "error"
  1746. });
  1747. });
  1748. },
  1749. // 操作数据
  1750. operationalData () {
  1751. var sss = this.ovReviewLis
  1752. if(this.tabPosition == 0) {
  1753. this.reviewLis = sss.pendingList
  1754. } else if(this.tabPosition == 1) {
  1755. this.reviewLis = sss.passList
  1756. } else if(this.tabPosition == 2) {
  1757. this.reviewLis = sss.rejectList
  1758. } else {
  1759. this.reviewLis = sss.cancelList
  1760. }
  1761. // console.log(this.reviewLis, '数据')
  1762. },
  1763. // 审核操作
  1764. operationList(zhi, id) {
  1765. if (this.operating) return;
  1766. let urls
  1767. if(zhi == 0) {
  1768. urls = '/finance-import/agree'
  1769. } else if(zhi == 1){
  1770. urls = '/finance-import/deny'
  1771. } else {
  1772. urls = '/finance-import/cancel'
  1773. }
  1774. this.operating = true;
  1775. this.http.post(urls, {
  1776. id: id,
  1777. },
  1778. res => {
  1779. if (res.code == "ok") {
  1780. this.operating = false;
  1781. this.$message({
  1782. message: this.$t('operationissuccessful'),
  1783. type: "success"
  1784. });
  1785. this.getReviewList();
  1786. this.loadMonthData();
  1787. } else {
  1788. this.$message({
  1789. message: res.msg,
  1790. type: "error"
  1791. });
  1792. }
  1793. },
  1794. error => {
  1795. this.$message({
  1796. message: error,
  1797. type: "error"
  1798. });
  1799. });
  1800. },
  1801. // 获取薪资上传记录
  1802. xzjl() {
  1803. this.http.post('/finance-import/list', {
  1804. companyId: this.user.companyId,
  1805. // pageIndex:1,
  1806. // pageSize: 9999
  1807. },
  1808. res => {
  1809. if (res.code == "ok") {
  1810. // console.log('123',res.data)
  1811. this.xzList = res.data.passList
  1812. } else {
  1813. this.$message({
  1814. message: res.msg,
  1815. type: "error"
  1816. });
  1817. }
  1818. },
  1819. error => {
  1820. this.$message({
  1821. message: error,
  1822. type: "error"
  1823. });
  1824. });
  1825. },
  1826. //导入分摊比例
  1827. intoAmortizationRatio(){
  1828. this.intoAmortizationDialog = true;
  1829. },
  1830. batchImportData(item) {
  1831. //首先判断文件类型
  1832. let str = item.file.name.split(".");
  1833. let format = str[str.length - 1];
  1834. if (format != "xls" && format != "xlsx") {
  1835. this.$message({
  1836. message: this.$t('other.PleaseselecttheXLSorXLSXfile'),
  1837. type: "error"
  1838. });
  1839. } else {
  1840. this.importingData = true;
  1841. let formData = new FormData();
  1842. formData.append("file", item.file);
  1843. formData.append("companyId", this.user.companyId);
  1844. formData.append('ymonth',this.date)
  1845. this.http.uploadFile('/project-percentage/importData', formData,
  1846. res => {
  1847. this.$refs.upload.clearFiles();
  1848. this.importingData = false;
  1849. this.showImportResult = true;
  1850. if (res.code == "ok") {
  1851. //换成弹出框,以免有人等了半天回来啥也没看到
  1852. this.importResultMsg = this.$t('other.importSuccess')+res.data+this.$t('apportionmentratiodata')+'。'+(res.msg?res.msg:"");
  1853. this.showSettingDialog();
  1854. } else {
  1855. this.importResultMsg = this.$t('export.Importfailure')+":"+res.msg;
  1856. }
  1857. },
  1858. error => {
  1859. this.$refs.upload.clearFiles();
  1860. this.importingData = false;
  1861. this.$message({
  1862. message: error,
  1863. type: "error"
  1864. });
  1865. });
  1866. }
  1867. },
  1868. // 左右滚动
  1869. scrollFunction () {
  1870. this.domObj = document.getElementById('clearfix') // 通过id获取要设置的div
  1871. if (this.domObj.attachEvent) { // IE
  1872. this.domObj.attachEvent('onmousewheel', this.mouseScroll)
  1873. } else if (this.domObj.addEventListener) {
  1874. this.domObj.addEventListener('DOMMouseScroll', this.mouseScroll, false)
  1875. }
  1876. this.domObj.onmousewheel = this.domObj.onmousewheel = this.mouseScroll
  1877. },
  1878. mouseScroll(event) { // google 浏览器下
  1879. let detail = event.wheelDelta || event.detail
  1880. let moveForwardStep = -1
  1881. let moveBackStep = 1
  1882. let step = 0
  1883. step = detail > 0 ? moveForwardStep * 100 : moveBackStep * 100
  1884. event.preventDefault() // 阻止浏览器默认事件
  1885. this.domObj.scrollLeft = this.domObj.scrollLeft + step
  1886. },
  1887. // 自定义组件事件
  1888. selectCal(obj) {
  1889. if(obj.distinction == '1') {
  1890. this.reviewerRuleForm.auditorId = obj.id
  1891. } else if(obj.distinction == '2') {
  1892. this.chosenNoReportUserIds = obj.id
  1893. }
  1894. }
  1895. },
  1896. created() {
  1897. var d = new Date();
  1898. this.date = d.getFullYear() +'-'+ ((d.getMonth()+1) < 10? '0'+(d.getMonth()+1):d.getMonth()+1);
  1899. },
  1900. mounted() {
  1901. let height = window.innerHeight;
  1902. this.tableHeight = height - 245;
  1903. const that = this;
  1904. window.onresize = function temp() {
  1905. that.tableHeight = window.innerHeight - 245;
  1906. };
  1907. this.getCustomColumn();
  1908. this.addreviewer();
  1909. this.arrter()
  1910. this.loadMonthData()
  1911. this.scrollFunction()
  1912. this.getAllProjectList()
  1913. this.getAllocateSelectedItems()
  1914. },
  1915. updated() {
  1916. this.$nextTick(() => {
  1917. this.$refs['table'].doLayout();
  1918. })
  1919. }
  1920. };
  1921. </script>
  1922. <style lang="scss" scoped>
  1923. .nameList {
  1924. height: 400px;
  1925. overflow: auto;
  1926. }
  1927. </style>