finance.vue 97 KB

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