list.vue 98 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136
  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="项目列表" class="toolbar_formitem_n1">
  7. </el-form-item>
  8. <el-form-item >
  9. <div>
  10. <el-input style="float:left;" v-model="keyword" class="input-with-select" placeholder="请输入项目名称关键字" clearable="true">
  11. <el-select v-model="searchField" style="width:120px;" slot="prepend" placeholder="请选择">
  12. <el-option label="项目名称" value=1 ></el-option>
  13. <el-option label="项目编号" value=2></el-option>
  14. </el-select>
  15. <el-button slot="append" @click="searchList" icon="el-icon-search"></el-button>
  16. </el-input>
  17. </div>
  18. </el-form-item>
  19. <el-form-item >
  20. <span style="margin-left:5px;margin-right:5px;color:#606266;">状态</span>
  21. <el-select v-model="status" style="width:110px;" placeholder="请选择" @change="searchList">
  22. <el-option label="全部" value=0 ></el-option>
  23. <el-option label="进行中" value=1 ></el-option>
  24. <el-option label="已完成" value=2 ></el-option>
  25. <el-option label="已撤销" value=3 ></el-option>
  26. </el-select>
  27. </el-form-item>
  28. <!-- 分类筛选 -->
  29. <el-form-item >
  30. <span style="margin-left:5px;margin-right:5px;color:#606266;">分类</span>
  31. <el-select v-model="statusClf" style="width:110px;" placeholder="请选择" clearable @change="searchClfList">
  32. <el-option v-for="item in baseClfList" :key="item.id" :label="item.name" :value="item.id" ></el-option>
  33. </el-select>
  34. </el-form-item>
  35. <!-- 分类条目 -->
  36. <el-form-item style="float:right;" v-if="permissions.projectClassification">
  37. <el-link type="primary" :underline="false" @click="showClfDialog = true">分类管理</el-link>
  38. </el-form-item>
  39. <!-- 项目成本基线条目 -->
  40. <el-form-item style="float:right;" v-if="user.company.packageProject == 1 && permissions.projectCostOfItems">
  41. <el-link type="primary" :underline="false" @click="showBaseCostItemDialog">基线成本项</el-link>
  42. </el-form-item>
  43. <el-form-item style="float:right;" v-if="permissions.projectExport">
  44. <el-link type="primary" style="margin-left:5px;" :underline="false" @click="exportProjectData" download="项目导出.xlsx">导出项目</el-link>
  45. </el-form-item>
  46. <el-form-item style="float:right;" v-if="permissions.projectImport">
  47. <el-link type="primary" style="margin-left:5px;" :underline="false" href="./upload/项目导入模板.xlsx" download="项目导入模板.xlsx">模板下载</el-link>
  48. </el-form-item>
  49. <el-form-item style="float:right;" v-if="permissions.projectImport">
  50. <el-upload ref="upload" style="margin-left:5px;" action="#" :limit="1" :http-request="importProject" :show-file-list="false">
  51. <el-link type="primary" :underline="false" >导入项目</el-link>
  52. </el-upload>
  53. </el-form-item>
  54. <!-- <el-form-item style="float:right;" v-if="user.role == 1||user.role == 2||user.role == 5"> -->
  55. <el-form-item style="float:right;" v-if="permissions.projectNew">
  56. <el-link type="primary" :underline="false" @click="handleAdd(-1,null)">新增项目</el-link>
  57. </el-form-item>
  58. <el-form-item style="float:right;" v-if="permissions.projectResources">
  59. <!-- <router-link to="/projectGantt"> -->
  60. <el-link type="primary" :underline="false" @click="isganttshow = true">资源分配</el-link>
  61. <!-- </router-link> -->
  62. <el-dialog v-if="isganttshow" :visible.sync="isganttshow" width="1480px" top="3vh" style="height:96%" class="ganttdialog">
  63. <projectgantt></projectgantt>
  64. </el-dialog>
  65. </el-form-item>
  66. </el-form>
  67. </el-col>
  68. <!--列表-->
  69. <el-table :data="list" highlight-current-row v-loading="listLoading" :height="tableHeight" style="width: 100%;">
  70. <el-table-column type="index" width="60">
  71. <template slot-scope="scope" >
  72. {{scope.$index+1+(page-1)*size}}
  73. </template>
  74. </el-table-column>
  75. <el-table-column prop="projectCode" label="项目编号" sortable width="120"></el-table-column>
  76. <el-table-column prop="categoryName" label="项目分类" sortable width="120"></el-table-column>
  77. <el-table-column prop="projectName" label="项目名称" width="250" sortable>
  78. <template slot-scope="scope">
  79. <!-- <div class="kans">
  80. <el-link type="primary" v-if="user.company.packageProject==1" :href="'#/projectInside/'+scope.row.id">{{scope.row.projectName}}</el-link>
  81. <span v-if="user.company.packageProject==0" >{{scope.row.projectName}}</span>
  82. </div> -->
  83. <el-popover placement="top" width="400" trigger="hover" v-if="scope.row.projectName.length > 15">
  84. <div>
  85. <el-link type="primary" v-if="user.company.packageProject==1" :underline="false" :href="'#/projectInside/'+scope.row.id">{{scope.row.projectName}}</el-link>
  86. <span v-if="user.company.packageProject==0" >{{scope.row.projectName}}</span>
  87. </div>
  88. <div slot="reference" class="kans">
  89. <el-link type="primary" v-if="user.company.packageProject==1" :underline="false" :href="'#/projectInside/'+scope.row.id">{{scope.row.projectName}}</el-link>
  90. <span v-if="user.company.packageProject==0" >{{scope.row.projectName}}</span>
  91. </div>
  92. </el-popover>
  93. <div v-else>
  94. <el-link type="primary" v-if="user.company.packageProject==1" :underline="false" :href="'#/projectInside/'+scope.row.id">{{scope.row.projectName}}</el-link>
  95. <span v-if="user.company.packageProject==0" >{{scope.row.projectName}}</span>
  96. </div>
  97. </template>
  98. </el-table-column>
  99. <el-table-column prop="inchargerName" label="负责人" sortable width="150">
  100. <template slot-scope="scope">
  101. <el-link type="primary" :underline="false" @click="showUser(scope.row.inchargerId)">{{scope.row.inchargerName}}</el-link>
  102. </template>
  103. </el-table-column>
  104. <el-table-column prop="participator" label="参与者" :width="user.company.packageCustomer != 1 ? '' : '300'" sortable v-if="user.company.packageProject==0">
  105. <template slot-scope="scope">
  106. <!-- <v-for v-for="par in scope.row.participator" :key="par.id" >
  107. <el-link style="margin-right:10px;" type="primary" @click="showUser(par.id)">{{par.name}}</el-link>
  108. </v-for> -->
  109. <div v-if="scope.row.participator.length > 5">
  110. <el-popover placement="top" width="500" trigger="hover" v-if="scope.row.participator.length > 0">
  111. <span v-for="par in scope.row.participator" :key="par.id">
  112. <el-link style="margin-right:10px;" :underline="false" type="primary" @click="showUser(par.id)">{{par.name}}</el-link>
  113. </span>
  114. <div slot="reference" class="addss">
  115. <span v-for="par in scope.row.participator" :key="par.id">
  116. <el-link style="margin-right:10px;" :underline="false" type="primary" @click="showUser(par.id)">{{par.name}}</el-link>
  117. </span>
  118. </div>
  119. </el-popover>
  120. </div>
  121. <div v-else>
  122. <span v-for="par in scope.row.participator" :key="par.id" >
  123. <el-link style="margin-right:10px;" type="primary" :underline="false" @click="showUser(par.id)">{{par.name}}</el-link>
  124. </span>
  125. </div>
  126. </template>
  127. </el-table-column>
  128. <!-- 客户管理 -->
  129. <el-table-column prop="customerName" label="客户" v-if="user.company.packageCustomer == 1">
  130. </el-table-column>
  131. <el-table-column prop="status" label="状态" width="100" >
  132. <template slot-scope="scope">
  133. {{scope.row.status == null?"-":statusTxt[scope.row.status]}}
  134. </template>
  135. </el-table-column>
  136. <!--专业项目协作-->
  137. <el-table-column prop="planStartDate" label="开始日期" width="96" >
  138. </el-table-column>
  139. <el-table-column prop="planEndDate" label="截止日期" width="96" >
  140. </el-table-column>
  141. <el-table-column prop="progress" label="完成度" width="100" v-if="user.company.packageProject == 1">
  142. <template slot-scope="scope">
  143. {{scope.row.progress==null?"-":scope.row.progress}}%
  144. </template>
  145. </el-table-column>
  146. <el-table-column label="操作" width="390" align="left" v-if="permissions.projectManagement">
  147. <template slot-scope="scope">
  148. <el-button v-if="user.role>0" size="mini" @click="subProject(scope.row)">子项目</el-button>
  149. <el-button size="mini" v-if="user.role>0 || user.id==scope.row.inchargerId" type="primary" @click="handleAdd(scope.$index, scope.row)">编辑</el-button>
  150. <el-button v-if="user.role>0" size="mini" @click="deletePro(scope.$index, scope.row)">删除</el-button>
  151. <!-- 111 -->
  152. <el-dropdown class="customdropdown" split-button size="mini" @click="finishPro(scope.row)" v-if="user.role>0 && scope.row.status == 1" placement="bottom-start">
  153. 完成
  154. <el-dropdown-menu slot="dropdown" class="customdropdown_menu">
  155. <el-button size="mini" @click="cancelPro(scope.row)" class="customdropdown_menu_btn">撤销</el-button>
  156. </el-dropdown-menu>
  157. </el-dropdown>
  158. <!-- <el-button v-if="user.role>0 && scope.row.status == 1" size="mini" @click="cancelPro(scope.row)">撤销</el-button>
  159. <el-button v-if="user.role>0 && scope.row.status == 1" size="mini" @click="finishPro(scope.row)">完成</el-button> -->
  160. <el-button v-if="user.role>0 && scope.row.status >= 2" size="mini" @click="restartPro(scope.row)">重启</el-button>
  161. </template>
  162. </el-table-column>
  163. </el-table>
  164. <!--工具条-->
  165. <el-col :span="24" class="toolbar">
  166. <el-pagination
  167. @size-change="handleSizeChange"
  168. @current-change="handleCurrentChange"
  169. :page-sizes="[20 , 50 , 80 , 100]"
  170. :page-size="20"
  171. layout="total, sizes, prev, pager, next"
  172. :total="total"
  173. style="float:right;"
  174. ></el-pagination>
  175. </el-col>
  176. <!--新增界面-->
  177. <el-dialog :title="title" v-if="addFormVisible" :visible.sync="addFormVisible" :close-on-click-modal="false" customClass="customWidth" width="960px">
  178. <el-form ref="form1" :model="addForm" :rules="rules" label-width="120px">
  179. <el-form-item label="项目编号" >
  180. <el-input v-model="addForm.code" :disabled="user.role==0" placeholder="请输入项目编号" clearable></el-input>
  181. </el-form-item>
  182. <el-form-item label="项目分类">
  183. <el-select v-model="addForm.category" clearable>
  184. <el-option v-for="(item) in baseClfList" :key="item.id" :value="item.id" :label="item.name"></el-option>
  185. </el-select>
  186. </el-form-item>
  187. <el-form-item label="项目名称" prop="name">
  188. <el-input v-model="addForm.name" :disabled="user.role==0" placeholder="请输入项目名称" clearable></el-input>
  189. </el-form-item>
  190. <el-form-item label="项目类型" prop="isPublic">
  191. <el-select v-model="addForm.isPublic" style="width:32%;" @change="selectPublic">
  192. <el-option :value="0" label="普通项目"></el-option>
  193. <el-option :value="1" label="公共项目"></el-option>
  194. </el-select>
  195. <el-tooltip effect="dark" content="普通项目只对参与人员开放,公共项目对所有成员开放" placement="top-start">
  196. <i class="el-icon-question"></i>
  197. </el-tooltip>
  198. <div v-if="user.company.packageProject==1" style="display: inline-block;width: 50%">
  199. <span style="margin-left:63px;margin-right:10px;" v-if="user.company.packageCustomer == 1">客户</span>
  200. <el-select v-model="addForm.customerId" clearable="true" filterable placeholder="请选择客户" style="width:70%;" >
  201. <el-option v-for="item in customerList" :key="item.id" :label="item.customerName" :value="item.id"></el-option>
  202. </el-select>
  203. </div>
  204. </el-form-item>
  205. <el-form-item :label="yonghuUser.customDegreeName" v-if="yonghuUser.customDegreeActive == 1">
  206. <el-select v-model="auseList" multiple placeholder="请选择" filterable="true" style="width: 100%">
  207. <span v-for="(item, index) in ause" :key="index">
  208. <el-option :label="item.name" :value="item.id"></el-option>
  209. </span>
  210. </el-select>
  211. </el-form-item>
  212. <!-- <el-form-item label="客户" v-if="user.company.packageCustomer == 1">
  213. <el-select v-model="addForm.customerId" clearable="true" filterable placeholder="请选择客户" style="width:100%;" >
  214. <el-option v-for="item in customerList" :key="item.id" :label="item.customerName" :value="item.id"></el-option>
  215. </el-select>
  216. </el-form-item> -->
  217. <el-form-item label="全部参与者" v-show="addForm.isPublic == 0">
  218. <el-input @focus="showChooseMembTree" v-model="addForm.userNames"></el-input>
  219. </el-form-item>
  220. <el-form-item label="负责人" >
  221. <el-select v-model="addForm.inchargerId" :disabled="(addForm.userId.length==0 || user.role==0) && addForm.isPublic == 0" filterable placeholder="请选择负责人" style="width:32%;" >
  222. <el-option v-for="item in participator" :key="item.id" :label="item.name" :value="item.id"></el-option>
  223. </el-select>
  224. </el-form-item>
  225. <el-form-item label="日报审核人" >
  226. <el-select v-model="addForm.auditUserIds" multiple="true" :disabled=" !(user.role==1 ||user.role==2|| user.id == addForm.inchargerId || user.id == addForm.creatorId)" filterable placeholder="默认为项目负责人" style="width:100%;" >
  227. <el-option v-for="item in participator" :key="item.id" :label="item.name" :value="item.id"></el-option>
  228. </el-select>
  229. </el-form-item>
  230. <!--专业项目协作版本功能 -->
  231. <el-form-item label="级别" v-if="user.company.packageProject==1">
  232. <el-select v-model="addForm.level" placeholder="请选择级别" style="width:32%;" >
  233. <el-option v-for="item in importanceList" :key="item.id" :label="item.label" :value="item.id"></el-option>
  234. </el-select>
  235. <!-- 增加合同金额字段 -->
  236. <span style="margin-left:63px;margin-right:10px;" v-if="user.company.packageProject==1">合同金额</span>
  237. <el-input id="contractAmount" v-model="addForm.contractAmount" style="width:33%;"
  238. placeholder="整数" clearable @keyup.native="restrictNumber('contractAmount')" ></el-input><span style="margin-left:10px;">元</span>
  239. <!-- 增加合同金额字段 -->
  240. </el-form-item>
  241. <el-form-item label="开始日期" prop="planStartDate" >
  242. <el-date-picker v-model="addForm.planStartDate"
  243. :editable="false" style="width:32%;"
  244. format="yyyy-MM-dd"
  245. value-format="yyyy-MM-dd"
  246. :clearable="false" type="date"
  247. placeholder="选择日期"></el-date-picker>
  248. <span style="margin-left:63px;margin-right:10px;" >截止日期</span>
  249. <el-date-picker v-model="addForm.planEndDate" style="width:33%;"
  250. :editable="false"
  251. format="yyyy-MM-dd"
  252. value-format="yyyy-MM-dd"
  253. :clearable="false" type="date"
  254. placeholder="选择日期"></el-date-picker>
  255. </el-form-item>
  256. <!--非建筑工程专业版设置 -->
  257. <!-- <el-form-item label="日报审核权限" v-if="user.company.packageProject==1 && user.company.packageEngineering == 0">
  258. <el-radio-group v-model="addForm.taskGpIncharge" >
  259. <el-radio :label="0">由项目负责人审核</el-radio>
  260. <el-radio :label="1">由各任务分组负责人审核</el-radio>
  261. </el-radio-group>
  262. </el-form-item> -->
  263. <!-- 项目基线 -->
  264. <div style="margin: 10px 0 30px 0;min-height:200px;" v-if="user.company.packageProject == 1">
  265. <el-tabs v-model="activeName" @tab-click="handleClick">
  266. <el-tab-pane label="成本基线" name="baseCostPanel" >
  267. <div style="padding-top:10px;">
  268. <!--新版 -->
  269. <span class="rg_span" v-for="(item, index) in projectBaseCostData" :key="item.id">
  270. <span style="width:120px;display: inline-block;" v-if="user.company.packageProject==1">{{item.baseName}}</span>
  271. <el-input :id="'baseCost'+index" @input="addUpfun()" v-model="item.baseAmount" style="width:200px; margin-bottom: 20px"
  272. placeholder="整数" clearable @keyup.native="restrictNumber('baseCost'+index)"></el-input><span style="margin-left:10px;">元</span>
  273. </span>
  274. <!-- 合计 -->
  275. <div style="margin-top: 10px;float:right;">
  276. <span style="margin-right:50px;margin-right:10px;" v-if="user.company.packageProject==1">合计</span>
  277. <span v-if="addForm.budget <= 0 || addForm.budget == undefined">0</span>
  278. <span v-else>{{addForm.budget | numberToCurrency}}</span>
  279. <span style="margin-right:50px;margin-left:10px;">元</span>
  280. </div>
  281. </div>
  282. </el-tab-pane>
  283. <el-tab-pane label="工程专业" name="engineeringProfession" v-if="user.company.packageEngineering == 1">
  284. <div style="padding-top:10px;">
  285. <el-table :data="projectProfessionList" size="small" :key="Math.random()">
  286. <el-table-column prop="professionId" width="200">
  287. <template slot-scope="scope">
  288. <el-select v-model="scope.row.professionId" >
  289. <el-option v-for="item in professionList" :key="item.id" :label="item.name" :value="item.id"/>
  290. </el-select>
  291. </template>
  292. <template slot="header" >
  293. <span style="font-size:14px;font-weight:normal;">专业名称</span>
  294. </template>
  295. </el-table-column>
  296. <el-table-column prop="percentage" width="120" label="占比(%)">
  297. <template slot-scope="scope">
  298. <div><el-input type="number" v-model="scope.row.percentage"></el-input></div>
  299. </template>
  300. </el-table-column>
  301. <el-table-column prop="membNames" label="相关人员及占比">
  302. <template slot-scope="scope">
  303. <span style="margin:0 5px;" v-for="item in scope.row.membList" :key="item.membId">{{item.membName}}({{item.percentage}}%)</span>
  304. <el-link @click="showEditPpMembs(scope.row)">{{(scope.row.membList == null || scope.row.membList.length == 0)?'设置专业参与人员':'设置'}}</el-link>
  305. </template>
  306. </el-table-column>
  307. <el-table-column prop="inchargerName" width="120" label="负责人">
  308. <template slot-scope="scope">
  309. <el-select v-model="scope.row.inchargerId" >
  310. <el-option v-for="item in participator" :key="item.id" :label="item.name" :value="item.id">
  311. </el-option>
  312. </el-select>
  313. </template>
  314. </el-table-column>
  315. <el-table-column width="80">
  316. <template slot-scope="scope">
  317. <el-button icon="el-icon-delete" size="mini" style="margin-left:10px;" @click.stop.native="deleteItem(scope.$index)"></el-button>
  318. </template>
  319. <template slot="header" >
  320. <el-link type="primary" :underline="false" @click="addItem">添加</el-link>
  321. </template>
  322. </el-table-column>
  323. </el-table>
  324. </div>
  325. </el-tab-pane>
  326. <el-tab-pane label="相关领导" name="leaders" >
  327. <div style="padding-top:10px;">
  328. <el-input @focus="showChooseLeaderTree" v-model="addForm.notifyUserNames" placeholder="请选择需要接收审核通知的相关领导"></el-input>
  329. </div>
  330. </el-tab-pane>
  331. </el-tabs>
  332. </div>
  333. </el-form>
  334. <div slot="footer" class="dialog-footer;">
  335. <el-button @click.native="addFormVisible = false">取消</el-button>
  336. <el-button type="primary" @click="submitInsert" :loading="addLoading">提交</el-button>
  337. </div>
  338. </el-dialog>
  339. <!--用户详细信息弹出框-->
  340. <el-dialog title="查看详情" v-if="userDetailVisible" :visible.sync="userDetailVisible" :close-on-click-modal="false" customClass="customWidth" width="400px">
  341. <div class="line"><span>姓名</span><span>{{userDetail.name}}</span></div>
  342. <div class="line"><span>手机号码</span><span>{{userDetail.phone}}</span></div>
  343. <div class="line"><span>角色</span><span>{{roleArray[userDetail.role]}}</span></div>
  344. <div class="line"><span>部门</span><span>{{userDetail.departmentName}}</span></div>
  345. <div class="line" v-if="user.role == 1 || user.role == 2 || user.role == 6"><span>成本</span><span>{{userDetail.cost}}元/小时</span></div>
  346. <div slot="footer" class="dialog-footer">
  347. <el-button type="primary" @click="userDetailVisible = false" >确定</el-button>
  348. </div>
  349. </el-dialog>
  350. <!-- 子项目列表 -->
  351. <el-dialog title="子项目列表" show-header="false" v-if="subProjectVisible" :visible.sync="subProjectVisible" :close-on-click-modal="false" customClass="customWidth" width="500px">
  352. <el-table :data="subProjectList" highlight-current-row height="400" style="width: 100%;">
  353. <!-- <el-table-column type="index" width="60" label="序号">
  354. <template slot-scope="scope" >
  355. {{scope.$index+1+(page-1)*size}}
  356. </template>
  357. </el-table-column> -->
  358. <el-table-column width="120" label="子项目编号" prop="code"></el-table-column>
  359. <el-table-column prop="name" label="名称" ></el-table-column>
  360. <el-table-column label="操作" width="150">
  361. <template slot-scope="scope" >
  362. <el-button size="small" type="primary" @click="addNewSubProject(scope.row)">编辑</el-button>
  363. <el-button size="small" type="danger" @click="deleteSubPro(scope.row)">删除</el-button>
  364. </template>
  365. </el-table-column>
  366. </el-table>
  367. <div slot="footer" class="dialog-footer">
  368. <el-button type="primary" @click="subProjectVisible = false" >关闭</el-button>
  369. <el-button type="primary" @click="addNewSubProject()" >新增子项目</el-button>
  370. </div>
  371. </el-dialog>
  372. <!-- 新增子项目弹出框 -->
  373. <el-dialog title="新增/修改子项目" v-if="addSubProject" :visible.sync="addSubProject" :close-on-click-modal="false" customClass="customWidth" width="500px">
  374. <el-form ref="form2" :model="temaddForm" :rules="rules" label-width="100px">
  375. <el-form-item label="项目编号" prop="code">
  376. <el-input v-model="temaddForm.code" placeholder="请输入项目编号" clearable></el-input>
  377. </el-form-item>
  378. <el-form-item label="项目名称" prop="name">
  379. <el-input v-model="temaddForm.name" placeholder="请输入项目名称" clearable></el-input>
  380. </el-form-item>
  381. </el-form>
  382. <div slot="footer" class="dialog-footer">
  383. <el-button @click.native="addSubProject = false">取消</el-button>
  384. <el-button type="primary" @click="submitInsertSubProject" :loading="addLoading">提交</el-button>
  385. </div>
  386. </el-dialog>
  387. <!-- 项目基线成本项配置弹出框 -->
  388. <el-dialog title="项目基线成本项管理" show-header="false" v-if="showBaseConfig" :visible.sync="showBaseConfig" :close-on-click-modal="false" customClass="customWidth" width="500px">
  389. <el-table :data="baseCostItemList" highlight-current-row height="400" style="width: 100%;">
  390. <el-table-column type="index" width="60" label="序号">
  391. <template slot-scope="scope" >
  392. {{scope.$index+1+(page-1)*size}}
  393. </template>
  394. </el-table-column>
  395. <el-table-column prop="name" label="名称" ></el-table-column>
  396. <el-table-column label="操作" width="150">
  397. <template slot-scope="scope" >
  398. <el-button size="small" type="primary" @click="addNewBaseItem(scope.row)">编辑</el-button>
  399. <el-button size="small" type="danger" @click="deleteBaseItem(scope.row)">删除</el-button>
  400. </template>
  401. </el-table-column>
  402. </el-table>
  403. <div slot="footer" class="dialog-footer">
  404. <el-button type="primary" @click="showBaseConfig = false" >关闭</el-button>
  405. <el-button type="primary" @click="addNewBaseItem()" >新增成本项</el-button>
  406. </div>
  407. </el-dialog>
  408. <!-- 分类条目配置 -->
  409. <el-dialog title="项目分类条目管理" show-header="false" v-if="showClfDialog" :visible.sync="showClfDialog" :close-on-click-modal="false" customClass="customWidth" width="500px">
  410. <el-table :data="baseClfList" highlight-current-row height="400" style="width: 100%;">
  411. <el-table-column type="index" width="60" label="序号">
  412. <template slot-scope="scope" >
  413. {{scope.$index+1+(page-1)*size}}
  414. </template>
  415. </el-table-column>
  416. <el-table-column prop="name" label="名称" ></el-table-column>
  417. <el-table-column label="操作" width="150">
  418. <template slot-scope="scope" >
  419. <el-button size="small" type="primary" @click="addNewClf(scope.row)">编辑</el-button>
  420. <el-button size="small" type="danger" @click="deleteClf(scope.row)">删除</el-button>
  421. </template>
  422. </el-table-column>
  423. </el-table>
  424. <div slot="footer" class="dialog-footer">
  425. <el-button type="primary" @click="showClfDialog = false" >关闭</el-button>
  426. <el-button type="primary" @click="addNewClf()" >新增分类项</el-button>
  427. </div>
  428. </el-dialog>
  429. <!-- 新增/编辑 分类条目 -->
  430. <el-dialog title="新增/修改分类条目" v-if="addClfDialog" :visible.sync="addClfDialog" :close-on-click-modal="false" customClass="customWidth" width="500px">
  431. <el-form ref="form2" :model="addClf" :rules="rules" label-width="100px">
  432. <el-form-item label="分类名称" prop="name">
  433. <el-input v-model="addClf.name" placeholder="请输入名称" clearable></el-input>
  434. </el-form-item>
  435. </el-form>
  436. <div slot="footer" class="dialog-footer">
  437. <el-button @click.native="addClfDialog = false">取消</el-button>
  438. <el-button type="primary" @click="submitClf" :loading="addLoading">提交</el-button>
  439. </div>
  440. </el-dialog>
  441. <el-dialog title="新增/修改成本项" v-if="addBaseItemDialog" :visible.sync="addBaseItemDialog" :close-on-click-modal="false" customClass="customWidth" width="500px">
  442. <el-form ref="form2" :model="addForm" :rules="rules" label-width="100px">
  443. <el-form-item label="成本项名称" prop="name">
  444. <el-input v-model="addForm.name" placeholder="请输入名称" clearable></el-input>
  445. </el-form-item>
  446. </el-form>
  447. <div slot="footer" class="dialog-footer">
  448. <el-button @click.native="addBaseItemDialog = false">取消</el-button>
  449. <el-button type="primary" @click="submitInsertBaseItem" :loading="addLoading">提交</el-button>
  450. </div>
  451. </el-dialog>
  452. <!-- 按部门选择人员 -->
  453. <el-dialog title="选择参与人员" v-if="chooseParticipVisible" :visible.sync="chooseParticipVisible" :close-on-click-modal="false" customClass="customWidth" width="500px">
  454. <!-- <el-input style="width:100%" v-model="filterName" placeholder="请输入姓名搜索" @change="findUserInTree"></el-input> -->
  455. <div class="tree" style="height:400px">
  456. <el-scrollbar style="height:100%">
  457. <el-input
  458. placeholder="输入关键字进行过滤"
  459. v-model="filterText">
  460. </el-input>
  461. <el-tree :data="deptMembData" show-checkbox :props="defaultProps" node-key="id"
  462. ref="chooseMembTree" @check-change="onTreeItemChange" :default-checked-keys="addForm.userId"
  463. highlight-current :filter-node-method="filterNode" default-expand-all></el-tree>
  464. </el-scrollbar>
  465. </div>
  466. <div>已选中&nbsp;{{chosenMembCount}}&nbsp;人</div>
  467. <div slot="footer" class="dialog-footer">
  468. <el-button @click="chooseParticipVisible = false" >取消</el-button>
  469. <el-button type="primary" @click="chooseParticip()" >确定</el-button>
  470. </div>
  471. </el-dialog>
  472. <!-- 按部门选择相关领导 -->
  473. <el-dialog title="选择相关领导" v-if="chooseLeaderVisible" :visible.sync="chooseLeaderVisible" :close-on-click-modal="false" customClass="customWidth" width="500px">
  474. <!-- <el-input style="width:100%" v-model="filterName" placeholder="请输入姓名搜索" @change="findUserInTree"></el-input> -->
  475. <div class="tree" style="height:400px">
  476. <el-scrollbar style="height:100%">
  477. <el-tree :data="deptMembData" show-checkbox :props="defaultProps" node-key="id"
  478. ref="chooseLeaderTree" @check-change="onLeaderTreeItemChange" :default-checked-keys="addForm.notifyUserIds"
  479. highlight-current ></el-tree>
  480. </el-scrollbar>
  481. </div>
  482. <div>已选中&nbsp;{{chosenMembCount}}&nbsp;人</div>
  483. <div slot="footer" class="dialog-footer">
  484. <el-button @click="chooseLeaderVisible = false" >取消</el-button>
  485. <el-button type="primary" @click="chooseLeader()" >确定</el-button>
  486. </div>
  487. </el-dialog>
  488. <!-- 项目专业人员的设置 -->
  489. <el-dialog title="设置项目专业人员" v-if="editPpMembDialog" :visible.sync="editPpMembDialog" :close-on-click-modal="false" customClass="customWidth" width="600px">
  490. <el-table :data="curProfessionRow.membList" height="400">
  491. <el-table-column prop="name" label="专业人员">
  492. <template slot-scope="scope">
  493. <el-select v-model="scope.row.membId" filterable placeholder="请选择专业参与人" style="width:100%;" >
  494. <el-option v-for="item in participator" :key="item.id" :label="item.name" :value="item.id">
  495. </el-option>
  496. </el-select>
  497. </template>
  498. </el-table-column>
  499. <el-table-column prop="percentage" width="120" label="占比(%)">
  500. <template slot-scope="scope">
  501. <el-input type="number" v-model="scope.row.percentage"></el-input>
  502. </template>
  503. </el-table-column>
  504. <el-table-column width="80">
  505. <template slot-scope="scope">
  506. <el-button icon="el-icon-delete" size="mini" style="margin-left:10px;" @click.stop.native="deleteMembItem(scope.$index)"></el-button>
  507. </template>
  508. <template slot="header" >
  509. <el-link @click="addMembItem">添加</el-link>
  510. </template>
  511. </el-table-column>
  512. </el-table>
  513. <div slot="footer" class="dialog-footer">
  514. <el-button @click="editPpMembDialog = false" >取消</el-button>
  515. <el-button type="primary" @click="addPpMemb" >确定</el-button>
  516. </div>
  517. </el-dialog>
  518. <!-- <el-dialog title="提示" v-if="deleteReconfirmDialog" :visible.sync="deleteReconfirmDialog" :close-on-click-modal="false" customClass="customWidth" width="500px">
  519. <p>{{deleteAlertMsg}}</p>
  520. <div slot="footer" class="dialog-footer">
  521. <el-button @click="deleteReconfirmDialog = false" >取消</el-button>
  522. <el-button type="primary" @click="forceDeletePro" >确认并删除</el-button>
  523. </div>
  524. </el-dialog> -->
  525. </section>
  526. </template>
  527. <style scoped>
  528. .input-with-select .el-input-group__prepend {
  529. background-color: #fff;
  530. }
  531. .line {
  532. padding:10px;
  533. }
  534. .line span{
  535. font-size:15px;
  536. }
  537. .line span:nth-child(even){
  538. float:right;
  539. }
  540. .kans {
  541. width: 230px;
  542. overflow:hidden;
  543. white-space:nowrap;
  544. text-overflow: ellipsis;
  545. }
  546. a {
  547. text-decoration: none;
  548. }
  549. .router-link-active {
  550. text-decoration: none;
  551. }
  552. </style>
  553. <script>
  554. import util from "../../common/js/util";
  555. import projectgantt from "./project_gantt.vue"
  556. export default {
  557. components:{projectgantt},
  558. data() {
  559. return {
  560. isganttshow: false,
  561. deleteAlertMsg: null,
  562. chosenLeaders:[],
  563. chooseLeaderVisible:false,
  564. projectProfessionItem:null,
  565. curProfessionRow:null,
  566. editPpMembDialog:false,
  567. professionList:[],
  568. projectProfessionList:[],
  569. activeName:"baseCostPanel",
  570. chosenMembCount:0,
  571. chosenMembList:[],//选中的人员
  572. allMembData:[],
  573. deptMembData: [
  574. {
  575. id: 0,
  576. label: '未分配',
  577. }
  578. ],
  579. option: [],
  580. depData: {
  581. id: -1,
  582. label: '全部人员',
  583. },
  584. defaultProps: {
  585. children: 'children',
  586. label: 'label'
  587. },
  588. filterName:null,
  589. chooseParticipVisible: false,
  590. projectBaseCostData:[],
  591. addBaseItemDialog:false,
  592. showBaseConfig:false,
  593. customerList:[],
  594. roleArray:["普通员工","超级管理员", "系统管理员", "公司高层","财务管理员", "项目管理员"],
  595. status:null,
  596. statusTxt:["-","进行中","已完成","已撤销"],
  597. importanceList:[{id:1,label:'正常'},{id:2,label:'紧急'},{id:3,label:'重要'},{id:4,label:'重要且紧急'}],
  598. searchField:null,
  599. keyword:null,
  600. user: JSON.parse(sessionStorage.getItem("user")),
  601. permissions: JSON.parse(sessionStorage.getItem("permissions")),
  602. userDetailVisible: false,
  603. userDetail:{},
  604. date: new Date(),
  605. users: [],
  606. participator:[],
  607. tableHeight: 0,
  608. listLoading: false,
  609. total: 0,
  610. page: 1,
  611. size: 20,
  612. list: [],
  613. subProjectVisible: false,
  614. subProjectList: [],//子项目列表
  615. currentProject:{},
  616. addSubProject: false,
  617. addFormVisible: false,
  618. addLoading: false,
  619. addUp: 0, // 合计
  620. title: "",
  621. addForm: {
  622. name: '',
  623. userId: [],
  624. level:1,
  625. taskGpIncharge: 0,
  626. id: '',
  627. code: ''
  628. },
  629. temaddForm: {},
  630. rules: {
  631. name: [{ required: true, message: "请输入名称", trigger: "blur" }]
  632. },
  633. ause: [],
  634. auseList: [],
  635. yonghuUser: [],
  636. filterText: '',
  637. showClfDialog: false,
  638. addClfDialog:false,
  639. addClf:{name:'',id:''},
  640. statusClf:null,
  641. permissionsObj: {},
  642. };
  643. },
  644. // 过滤器
  645. filters: {
  646. numberToCurrency(value) {
  647. if (!value) return '0.00'
  648. // 将数值截取,保留两位小数
  649. value = value.toFixed(2)
  650. // 获取整数部分
  651. const intPart = Math.trunc(value)
  652. // 整数部分处理,增加,
  653. const intPartFormat = intPart.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,')
  654. // 预定义小数部分
  655. let floatPart = '.00'
  656. // 将数值截取为小数部分和整数部分
  657. const valueArray = value.toString().split('.')
  658. if (valueArray.length === 2) { // 有小数部分
  659. floatPart = valueArray[1].toString() // 取得小数部分
  660. return intPartFormat + '.' + floatPart
  661. }
  662. return intPartFormat + floatPart
  663. },
  664. },
  665. watch: {
  666. filterText(val) {
  667. this.$refs.chooseMembTree.filter(val);
  668. }
  669. },
  670. methods: {
  671. filterNode(value, data) {
  672. if (!value) return true;
  673. return data.label.indexOf(value) !== -1;
  674. },
  675. //重启项目
  676. restartPro(row) {
  677. this.http.post('/project/start',{id: row.id},
  678. res => {
  679. if (res.code == "ok") {
  680. this.$message({
  681. message: '重启成功',
  682. type: "success"
  683. });
  684. row.status = 1;
  685. } else {
  686. this.$message({
  687. message: res.msg,
  688. type: "error"
  689. });
  690. }
  691. },
  692. error => {
  693. this.$message({
  694. message: error,
  695. type: "error"
  696. });
  697. });
  698. },
  699. //撤销项目
  700. cancelPro(row) {
  701. this.http.post('/project/cancel',{id: row.id},
  702. res => {
  703. if (res.code == "ok") {
  704. this.$message({
  705. message: '撤销成功',
  706. type: "success"
  707. });
  708. row.status = 3;
  709. } else {
  710. this.$message({
  711. message: res.msg,
  712. type: "error"
  713. });
  714. }
  715. },
  716. error => {
  717. this.$message({
  718. message: error,
  719. type: "error"
  720. });
  721. });
  722. },
  723. //完成项目
  724. finishPro(row) {
  725. this.http.post('/project/finish',{id: row.id},
  726. res => {
  727. if (res.code == "ok") {
  728. this.$message({
  729. message: '项目完成',
  730. type: "success"
  731. });
  732. row.status = 2;
  733. } else {
  734. this.$message({
  735. message: res.msg,
  736. type: "error"
  737. });
  738. }
  739. },
  740. error => {
  741. this.$message({
  742. message: error,
  743. type: "error"
  744. });
  745. });
  746. },
  747. exportProjectData() {
  748. //导出项目
  749. this.http.post('/project/exportData',{},
  750. res => {
  751. if (res.code == "ok") {
  752. var filePath = res.data;
  753. const a = document.createElement('a'); // 创建a标签
  754. a.setAttribute('download', '项目导出.xls');// download属性
  755. a.setAttribute('href', filePath);// href链接
  756. a.click(); //自执行点击事件
  757. a.remove();
  758. }
  759. },
  760. error => {
  761. this.$message({
  762. message: error,
  763. type: "error"
  764. });
  765. }
  766. );
  767. },
  768. userssHu() {
  769. this.http.post('/time-type/getCompanyTimeSetting',{
  770. companyId: this.user.companyId
  771. },
  772. res => {
  773. if (res.code == "ok") {
  774. this.yonghuUser = res.data
  775. console.log(this.yonghuUser)
  776. }
  777. },
  778. error => {
  779. this.$message({
  780. message: error,
  781. type: "error"
  782. });
  783. }
  784. );
  785. },
  786. yanjiuzx() {
  787. this.http.post('/report-extra-degree/getAll ',{},
  788. res => {
  789. if (res.code == "ok") {
  790. console.log(res, '过来的数据')
  791. this.ause = res.data
  792. } else {
  793. this.$message({
  794. message: res.msg,
  795. type: "error"
  796. });
  797. }
  798. },
  799. error => {
  800. this.$message({
  801. message: error,
  802. type: "error"
  803. });
  804. }
  805. );
  806. },
  807. selectPublic() {
  808. if (this.addForm.isPublic == 1) {
  809. this.participator = this.users;
  810. } else {
  811. this.participator = [];
  812. }
  813. },
  814. addPpMemb() {
  815. //检查合计比例是否到达100%
  816. let p = 0;
  817. let hasNoMemb = false;
  818. this.curProfessionRow.membList.forEach(m=>{
  819. p += parseInt(m.percentage);
  820. //检查人员是否选择
  821. if (m.membId == null) {
  822. hasNoMemb = true;
  823. }
  824. });
  825. if (hasNoMemb) {
  826. this.$message({
  827. message: '专业人员不能为空',
  828. type: "error"
  829. });
  830. return;
  831. }
  832. //检查人员不能重复
  833. let hasDuplicate = false;
  834. this.curProfessionRow.membList.forEach(m=>{
  835. if (this.curProfessionRow.membList.filter(innerM=>innerM.membId == m.membId).length>1) {
  836. hasDuplicate = true;
  837. }
  838. });
  839. if (hasDuplicate) {
  840. this.$message({
  841. message: '专业人员不能重复',
  842. type: "error"
  843. });
  844. return;
  845. }
  846. if (p != 100) {
  847. this.$message({
  848. message: '占比合计必须是100%',
  849. type: "error"
  850. });
  851. return;
  852. }
  853. this.editPpMembDialog = false;
  854. this.curProfessionRow.membList.forEach(m=>{
  855. m.membName = this.participator.filter(p=>p.id == m.membId)[0].name;
  856. });
  857. this.projectProfessionItem.membList = JSON.parse(JSON.stringify(this.curProfessionRow.membList));
  858. },
  859. //删除专业人员
  860. deleteMembItem(index) {
  861. this.curProfessionRow.membList.splice(index,1);
  862. },
  863. //添加专业人员
  864. addMembItem() {
  865. if (this.curProfessionRow.membList == null) {
  866. this.curProfessionRow.membList = [{membId:null, percentage:100}];
  867. } else {
  868. let p = 0;
  869. this.curProfessionRow.membList.forEach(m=>{
  870. p += parseInt(m.percentage);
  871. });
  872. this.curProfessionRow.membList.push({membId:null, percentage:100-p});
  873. }
  874. this.$forceUpdate();
  875. },
  876. showEditPpMembs(row) {
  877. this.projectProfessionItem = row;
  878. this.curProfessionRow = JSON.parse(JSON.stringify(row));
  879. if (this.curProfessionRow.membList == null || this.curProfessionRow.membList.length == 0) {
  880. this.curProfessionRow.membList = [{membId:null, percentage:100}];
  881. }
  882. this.editPpMembDialog = true;
  883. },
  884. getProjectNotifyUserList(projectId) {
  885. this.http.post("/project-notify-user/get", {projectId: projectId},
  886. res => {
  887. if (res.code == "ok") {
  888. var chosenLeaderIds = [];
  889. var chosenLeaderNames = '';
  890. var leaderList = res.data;
  891. this.chosenLeaders = leaderList;
  892. for(var j in leaderList) {
  893. chosenLeaderIds.push(leaderList[j].userId)
  894. chosenLeaderNames += leaderList[j].userName+',';
  895. }
  896. if (chosenLeaderNames.length > 0) {
  897. chosenLeaderNames = chosenLeaderNames.substring(0, chosenLeaderNames.length -1);
  898. }
  899. this.addForm.notifyUserIds = chosenLeaderIds;
  900. this.addForm.notifyUserNames = chosenLeaderNames;
  901. } else {
  902. this.$message({
  903. message: res.msg,
  904. type: "error"
  905. });
  906. }
  907. },
  908. error => {
  909. this.$message({
  910. message: error,
  911. type: "error"
  912. });
  913. });
  914. },
  915. getProjectProfessions(projectId) {
  916. this.http.post("/project-profession/get", {projectId: projectId},
  917. res => {
  918. if (res.code == "ok") {
  919. this.projectProfessionList = res.data;
  920. } else {
  921. this.$message({
  922. message: res.msg,
  923. type: "error"
  924. });
  925. }
  926. },
  927. error => {
  928. this.$message({
  929. message: error,
  930. type: "error"
  931. });
  932. });
  933. },
  934. checkProjectProfession() {
  935. //检查合计比例是否到达100%
  936. let p = 0;
  937. let hasNoMemb = false;
  938. let hasNoProfession = false;
  939. let hasNoMembList = false;
  940. this.projectProfessionList.forEach(m=>{
  941. p += parseInt(m.percentage);
  942. //检查人员是否选择
  943. if (m.inchargerId == null) {
  944. hasNoMemb = true;
  945. }
  946. if (m.professionId == null) {
  947. hasNoProfession = true;
  948. }
  949. if (m.membList == null) {
  950. hasNoMembList = true;
  951. }
  952. });
  953. if (hasNoProfession) {
  954. this.$message({
  955. message: '专业不能为空',
  956. type: "error"
  957. });
  958. return false;
  959. }
  960. if (hasNoMembList) {
  961. this.$message({
  962. message: '专业相关人员不能为空',
  963. type: "error"
  964. });
  965. return false;
  966. }
  967. if (hasNoMemb) {
  968. this.$message({
  969. message: '专业负责人不能为空',
  970. type: "error"
  971. });
  972. return false;
  973. }
  974. //检查专业不能重复
  975. let hasDuplicate = false;
  976. this.projectProfessionList.forEach(m=>{
  977. if (this.projectProfessionList.filter(innerM=>innerM.professionId == m.professionId).length>1) {
  978. hasDuplicate = true;
  979. }
  980. });
  981. if (hasDuplicate) {
  982. this.$message({
  983. message: '专业不能重复',
  984. type: "error"
  985. });
  986. return false;
  987. }
  988. if (this.projectProfessionList.length > 0 && p != 100) {
  989. this.$message({
  990. message: '专业占比合计必须是100%',
  991. type: "error"
  992. });
  993. return false;
  994. }
  995. return true;
  996. },
  997. //保存项目专业
  998. saveProjectProfessions(projectId) {
  999. var list = this.projectProfessionList.filter(p=>p.professionId != null);
  1000. list.forEach(p=>p.inchargerName = this.participator.filter(m=>m.id == p.inchargerId)[0].name);
  1001. list.forEach(p=>p.professionName = this.professionList.filter(m=>m.id == p.professionId)[0].name);
  1002. this.http.post("/project-profession/modify", {projectId: projectId, json: JSON.stringify(list)},
  1003. res => {
  1004. if (res.code == "ok") {
  1005. return false;
  1006. } else {
  1007. this.$message({
  1008. message: res.msg,
  1009. type: "error"
  1010. });
  1011. }
  1012. },
  1013. error => {
  1014. this.$message({
  1015. message: error,
  1016. type: "error"
  1017. });
  1018. });
  1019. },
  1020. //删除项目专业
  1021. deleteItem(index) {
  1022. this.projectProfessionList.splice(index,1);
  1023. },
  1024. //添加项目专业
  1025. addItem() {
  1026. let p = 0;
  1027. this.projectProfessionList.forEach(m=>{
  1028. p += parseInt(m.percentage);
  1029. });
  1030. this.projectProfessionList.push( { professionId:null, inchargerId:null,membIds:[], percentage: 100-p});
  1031. },
  1032. getProfessionList() {
  1033. this.http.post("/profession/getAll", {},
  1034. res => {
  1035. if (res.code == "ok") {
  1036. var list = res.data;
  1037. this.professionList = list;
  1038. } else {
  1039. this.$message({
  1040. message: res.msg,
  1041. type: "error"
  1042. });
  1043. }
  1044. },
  1045. error => {
  1046. this.$message({
  1047. message: error,
  1048. type: "error"
  1049. });
  1050. });
  1051. },
  1052. restrictNumber(targetId) {
  1053. let inpu = document.getElementById(targetId);
  1054. inpu.value = inpu.value.replace(/[^\d.]/g, ""); //仅保留数字和"."
  1055. inpu.value = inpu.value.replace(/\.{2,}/g, "."); //两个连续的"."仅保留第一个"."
  1056. inpu.value = inpu.value.replace(".", "$#*").replace(/\./g,'').replace('$#*','.');//去除其他"."
  1057. inpu.value = inpu.value.replace(/^(\d+)\.(\d\d).*$/, '$1.$2');;//限制只能输入两个小数
  1058. if (inpu.value.indexOf(".") < 0 && inpu.value != "") { //首位是0的话去掉
  1059. inpu.value = parseFloat(inpu.value);
  1060. }
  1061. },
  1062. showChooseLeaderTree() {
  1063. this.chosenMembCount = this.chosenLeaders.length;
  1064. this.chooseLeaderVisible = true;
  1065. },
  1066. onLeaderTreeItemChange() {
  1067. var chosenList = this.$refs.chooseLeaderTree.getCheckedNodes();
  1068. var list = chosenList.filter(item=>item.isUser == 1);
  1069. this.chosenMembCount = list.length;
  1070. },
  1071. showChooseMembTree() {
  1072. this.chosenMembCount = this.participator.length;
  1073. this.chooseParticipVisible = true;
  1074. },
  1075. onTreeItemChange() {
  1076. var chosenList = this.$refs.chooseMembTree.getCheckedNodes();
  1077. var list = chosenList.filter(item=>item.isUser == 1);
  1078. this.chosenMembCount = list.length;
  1079. },
  1080. findUserInTree() {
  1081. if (this.filterName == '') {
  1082. this.deptMembData = this.allMembData;
  1083. } else {
  1084. var list = this.findRecursively(this.filterName, this.allMembData);
  1085. this.deptMembData = list;
  1086. }
  1087. },
  1088. findRecursively(username, list) {
  1089. var filterList = [];
  1090. for (var i=0;i<list.length; i++) {
  1091. if (list[i].isUser == 1) {
  1092. if (list[i].label.indexOf(username) >= 0) {
  1093. //匹配上了
  1094. filterList.push(list[i]);
  1095. }
  1096. } else if (list[i].children != null && list[i].children.length > 0) {
  1097. var subList = this.findRecursively(username, list[i].children);
  1098. if (subList.length > 0) {
  1099. subList.forEach(s=>filterList.push(s));
  1100. }
  1101. }
  1102. }
  1103. return filterList;
  1104. },
  1105. //确定选择参与人
  1106. chooseParticip() {
  1107. this.chooseParticipVisible = false;
  1108. var chosenList = this.$refs.chooseMembTree.getCheckedNodes();
  1109. this.chosenMembList = chosenList.filter(item=>item.isUser == 1);
  1110. this.addForm.userNames = '';
  1111. this.addForm.userId = [];
  1112. this.participator = [];
  1113. for (var i=0;i<this.chosenMembList.length; i++) {
  1114. this.addForm.userId.push(this.chosenMembList[i].id);
  1115. this.addForm.userNames += this.chosenMembList[i].label+',';
  1116. var item = {id:this.chosenMembList[i].id, name:this.chosenMembList[i].label};
  1117. this.participator.push(item);
  1118. }
  1119. if (this.addForm.userNames.length > 0) {
  1120. this.addForm.userNames = this.addForm.userNames.substring(0, this.addForm.userNames.length-1);
  1121. }
  1122. },
  1123. //选中相关领导
  1124. chooseLeader() {
  1125. this.chooseLeaderVisible = false;
  1126. var chosenList = this.$refs.chooseLeaderTree.getCheckedNodes();
  1127. var chosenMembList = chosenList.filter(item=>item.isUser == 1);
  1128. this.addForm.notifyUserNames = '';
  1129. this.addForm.notifyUserIds = [];
  1130. this.chosenLeaders = [];
  1131. for (var i=0;i<chosenMembList.length; i++) {
  1132. this.addForm.notifyUserIds.push(chosenMembList[i].id);
  1133. this.addForm.notifyUserNames += chosenMembList[i].label+',';
  1134. var item = {userId:chosenMembList[i].id, userName:chosenMembList[i].label};
  1135. this.chosenLeaders.push(item);
  1136. }
  1137. if (this.addForm.notifyUserNames.length > 0) {
  1138. this.addForm.notifyUserNames = this.addForm.notifyUserNames.substring(0, this.addForm.notifyUserNames.length-1);
  1139. }
  1140. },
  1141. // 获取部门列表
  1142. getDepartment() {
  1143. this.http.post("/department/listAllMemb", {},
  1144. res => {
  1145. if (res.code == "ok") {
  1146. var list = res.data;
  1147. //设置员工到部门下面
  1148. this.setUserToDept(list);
  1149. this.deptMembData = list;
  1150. //用于筛选过滤
  1151. this.allMembData = JSON.parse(JSON.stringify(this.deptMembData));
  1152. } else {
  1153. this.$message({
  1154. message: res.msg,
  1155. type: "error"
  1156. });
  1157. }
  1158. },
  1159. error => {
  1160. this.$message({
  1161. message: error,
  1162. type: "error"
  1163. });
  1164. });
  1165. },
  1166. setUserToDept(list) {
  1167. for (var i in list) {
  1168. if (list[i].children != null) {
  1169. this.setUserToDept(list[i].children);
  1170. }
  1171. if (list[i].userList != null) {
  1172. if (list[i].children == null) {
  1173. list[i].children = [];
  1174. }
  1175. list[i].userList.forEach(element => {
  1176. var obj = {id: element.id, label:element.name, parentId:element.departmentId, isUser:1};
  1177. list[i].children.push(obj);
  1178. });
  1179. }
  1180. }
  1181. },
  1182. // 获取分类条目
  1183. getClfConfigList() {
  1184. this.http.get('/project-category/list',
  1185. res => {
  1186. if (res.code == "ok") {
  1187. this.baseClfList = res.data;
  1188. console.log("获取分类条目",res.data);
  1189. this.$forceUpdate();
  1190. } else {
  1191. this.$message({
  1192. message: res.msg,
  1193. type: "error"
  1194. });
  1195. }
  1196. },
  1197. error => {
  1198. this.$message({
  1199. message: error,
  1200. type: "error"
  1201. });
  1202. }
  1203. );
  1204. },
  1205. // 新增/编辑 分类条目
  1206. addNewClf(row) {
  1207. this.addClfDialog = true;
  1208. if (row == null) {
  1209. this.addClf = {}
  1210. } else {
  1211. this.addClf = row;
  1212. }
  1213. },
  1214. // 提交
  1215. submitClf() {
  1216. this.http.post('/project-category/addOrMod',this.addClf,
  1217. res => {
  1218. if (res.code == "ok") {
  1219. this.addClfDialog = false;
  1220. this.baseClfList = res.data;
  1221. // this.$forceUpdate();
  1222. console.log(res.data);
  1223. } else {
  1224. this.$message({
  1225. message: res.msg,
  1226. type: "error"
  1227. });
  1228. }
  1229. },
  1230. error => {
  1231. this.$message({
  1232. message: error,
  1233. type: "error"
  1234. });
  1235. }
  1236. );
  1237. },
  1238. // 删除
  1239. deleteClf(row) {
  1240. this.$confirm("该操作可能造成已有数据丢失,确定要删除吗?","删除分类条目", {
  1241. confirmButtonText: "确定",
  1242. cancelButtonText: "取消",
  1243. type: "warning"
  1244. })
  1245. .then(() => {
  1246. this.listLoading = true;
  1247. this.http.post('/project-category/delete',{
  1248. id: row.id
  1249. },
  1250. res => {
  1251. this.listLoading = false;
  1252. if (res.code == "ok") {
  1253. this.$message({
  1254. message: "删除成功",
  1255. type: "success"
  1256. });
  1257. this.getClfConfigList();
  1258. } else {
  1259. this.$message({
  1260. message: res.msg,
  1261. type: "error"
  1262. });
  1263. }
  1264. },
  1265. error => {
  1266. this.listLoading = false;
  1267. this.$message({
  1268. message: error,
  1269. type: "error"
  1270. });
  1271. }
  1272. );
  1273. })
  1274. .catch(() => {});
  1275. },
  1276. // 分类筛选
  1277. searchClfList(){
  1278. this.page = 1;
  1279. this.getList();
  1280. },
  1281. getProjectBaseConfigList() {
  1282. this.http.post('/project-basecost-setting/list',{},
  1283. res => {
  1284. if (res.code == "ok") {
  1285. this.baseCostItemList = res.data;
  1286. this.$forceUpdate();
  1287. } else {
  1288. this.$message({
  1289. message: res.msg,
  1290. type: "error"
  1291. });
  1292. }
  1293. },
  1294. error => {
  1295. this.$message({
  1296. message: error,
  1297. type: "error"
  1298. });
  1299. }
  1300. );
  1301. },
  1302. deleteBaseItem(row) {
  1303. this.$confirm("该操作可能造成已有数据丢失,确定要删除吗?","删除成本基线项", {
  1304. confirmButtonText: "确定",
  1305. cancelButtonText: "取消",
  1306. type: "warning"
  1307. })
  1308. .then(() => {
  1309. this.listLoading = true;
  1310. this.http.post('/project-basecost-setting/delete',{
  1311. id: row.id
  1312. },
  1313. res => {
  1314. this.listLoading = false;
  1315. if (res.code == "ok") {
  1316. this.$message({
  1317. message: "删除成功",
  1318. type: "success"
  1319. });
  1320. this.getProjectBaseConfigList();
  1321. } else {
  1322. this.$message({
  1323. message: res.msg,
  1324. type: "error"
  1325. });
  1326. }
  1327. },
  1328. error => {
  1329. this.listLoading = false;
  1330. this.$message({
  1331. message: error,
  1332. type: "error"
  1333. });
  1334. }
  1335. );
  1336. })
  1337. .catch(() => {});
  1338. },
  1339. submitInsertBaseItem() {
  1340. this.http.post('/project-basecost-setting/addOrMod',this.addForm,
  1341. res => {
  1342. if (res.code == "ok") {
  1343. this.addBaseItemDialog = false;
  1344. this.baseCostItemList = res.data;
  1345. this.$forceUpdate();
  1346. } else {
  1347. this.$message({
  1348. message: res.msg,
  1349. type: "error"
  1350. });
  1351. }
  1352. },
  1353. error => {
  1354. this.$message({
  1355. message: error,
  1356. type: "error"
  1357. });
  1358. }
  1359. );
  1360. },
  1361. showBaseCostItemDialog() {
  1362. this.showBaseConfig = true;
  1363. },
  1364. addNewBaseItem(row) {
  1365. this.addBaseItemDialog = true;
  1366. if (row == null) {
  1367. this.addForm = {}
  1368. } else {
  1369. this.addForm = row;
  1370. }
  1371. },
  1372. //获取客户列表
  1373. getCustomerList() {
  1374. this.http.post('/customer-info/getAll', {
  1375. },
  1376. res => {
  1377. if (res.code == "ok") {
  1378. this.customerList = res.data;
  1379. } else {
  1380. this.$message({
  1381. message: res.msg,
  1382. type: "error"
  1383. });
  1384. }
  1385. },
  1386. error => {
  1387. this.$message({
  1388. message: error,
  1389. type: "error"
  1390. });
  1391. });
  1392. },
  1393. importProject(item) {
  1394. //首先判断文件类型
  1395. let str = item.file.name.split(".");
  1396. let format = str[str.length - 1];
  1397. if (format != "xls" && format != "xlsx") {
  1398. this.$message({
  1399. message: "请选择.xls或.xlsx文件",
  1400. type: "error"
  1401. });
  1402. } else {
  1403. this.listLoading = true;
  1404. let formData = new FormData();
  1405. formData.append("file", item.file);
  1406. formData.append("userId", this.user.id);
  1407. this.http.uploadFile('/project/importData', formData,
  1408. res => {
  1409. this.$refs.upload.clearFiles();
  1410. this.listLoading = false;
  1411. if (res.code == "ok") {
  1412. this.$message({
  1413. message: "导入成功",
  1414. type: "success"
  1415. });
  1416. this.getList();
  1417. } else {
  1418. this.$message({
  1419. message: res.msg,
  1420. type: "error"
  1421. });
  1422. }
  1423. },
  1424. error => {
  1425. this.$refs.upload.clearFiles();
  1426. this.listLoading = false;
  1427. this.$message({
  1428. message: error,
  1429. type: "error"
  1430. });
  1431. });
  1432. }
  1433. },
  1434. number(){
  1435. //     this.addForm.budget = this.addForm.budget.replace(/[^\.\d]/g,'');
  1436. // this.addForm.budget = this.addForm.budget.replace('.','');
  1437. },
  1438. deleteSubPro(subProject) {
  1439. this.$confirm("确定要删除子项目" + subProject.name + "吗?","删除子项目", {
  1440. confirmButtonText: "确定",
  1441. cancelButtonText: "取消",
  1442. type: "warning"
  1443. })
  1444. .then(() => {
  1445. this.listLoading = true;
  1446. this.http.post('/sub-project/deleteProject',{
  1447. id: subProject.id
  1448. },
  1449. res => {
  1450. this.listLoading = false;
  1451. if (res.code == "ok") {
  1452. this.$message({
  1453. message: "删除成功",
  1454. type: "success"
  1455. });
  1456. this.subProject(this.currentProject);
  1457. } else {
  1458. this.$message({
  1459. message: res.msg,
  1460. type: "error"
  1461. });
  1462. }
  1463. },
  1464. error => {
  1465. this.listLoading = false;
  1466. this.$message({
  1467. message: error,
  1468. type: "error"
  1469. });
  1470. }
  1471. );
  1472. })
  1473. .catch(() => {});
  1474. },
  1475. searchList() {
  1476. this.page = 1;
  1477. this.getList();
  1478. },
  1479. addNewSubProject(subProject) {
  1480. if (subProject == null) {
  1481. this.temaddForm = {projectId: this.currentProject.id, level:1}
  1482. } else {
  1483. this.temaddForm = JSON.parse(JSON.stringify(subProject));
  1484. }
  1485. this.addSubProject = true;
  1486. },
  1487. //显示子项目
  1488. subProject(item) {
  1489. this.subProjectVisible = true;
  1490. this.currentProject = item;
  1491. this.http.post('/sub-project/list', {
  1492. projectId: item.id
  1493. },
  1494. res => {
  1495. if (res.code == "ok") {
  1496. this.subProjectList = res.data;
  1497. } else {
  1498. this.$message({
  1499. message: res.msg,
  1500. type: "error"
  1501. });
  1502. }
  1503. },
  1504. error => {
  1505. this.$message({
  1506. message: error,
  1507. type: "error"
  1508. });
  1509. });
  1510. },
  1511. //显示用户详情
  1512. showUser(userId) {
  1513. this.userDetailVisible = true;
  1514. this.http.post(this.port.manage.userDetail, {
  1515. userId: userId
  1516. },
  1517. res => {
  1518. if (res.code == "ok") {
  1519. this.userDetail = res.data;
  1520. } else {
  1521. this.$message({
  1522. message: res.msg,
  1523. type: "error"
  1524. });
  1525. }
  1526. },
  1527. error => {
  1528. this.$message({
  1529. message: error,
  1530. type: "error"
  1531. });
  1532. });
  1533. },
  1534. //选择参与人
  1535. changeParticipator() {
  1536. //检查是否在参与人中,如果没有需要加入到参与人中
  1537. this.participator = [];
  1538. this.addForm.userId.forEach(u=>{
  1539. var list = this.users.filter(au=>au.id == u);
  1540. if (list.length > 0) {
  1541. var findUser = list[0];
  1542. this.participator.push(findUser);
  1543. } else {
  1544. console.log('未找到用户: '+u);
  1545. }
  1546. })
  1547. },
  1548. getUsers() {
  1549. this.http.post(this.port.manage.list, {
  1550. departmentId: -1,
  1551. pageIndex: 1,
  1552. pageSize: 99999
  1553. },
  1554. res => {
  1555. if (res.code == "ok") {
  1556. this.users = res.data.records;
  1557. } else {
  1558. this.$message({
  1559. message: res.msg,
  1560. type: "error"
  1561. });
  1562. }
  1563. },
  1564. error => {
  1565. this.$message({
  1566. message: error,
  1567. type: "error"
  1568. });
  1569. });
  1570. },
  1571. //分页
  1572. handleCurrentChange(val) {
  1573. this.page = val;
  1574. this.getList();
  1575. },
  1576. handleSizeChange(val) {
  1577. this.size = val;
  1578. this.getList();
  1579. },
  1580. //获取项目列表
  1581. getList() {
  1582. this.listLoading = true;
  1583. this.http.post(this.port.project.listPage, {
  1584. pageIndex: this.page,
  1585. pageSize: this.size,
  1586. keyword:this.keyword,
  1587. searchField: this.searchField,
  1588. status: this.status,
  1589. category: this.statusClf
  1590. //
  1591. },
  1592. res => {
  1593. this.listLoading = false;
  1594. if (res.code == "ok") {
  1595. var list = res.data.records;
  1596. for(var i in list) {
  1597. var participator = list[i].participator , str = "";
  1598. for(var j in participator) {
  1599. if(j == participator.length-1) {
  1600. str += participator[j].name
  1601. } else {
  1602. str += participator[j].name + ','
  1603. }
  1604. }
  1605. list[i].userNames = str;
  1606. }
  1607. this.list = list;
  1608. this.total = res.data.total;
  1609. console.log("列表",res.data);
  1610. } else {
  1611. this.$message({
  1612. message: res.msg,
  1613. type: "error"
  1614. });
  1615. }
  1616. },
  1617. error => {
  1618. this.listLoading = false;
  1619. this.$message({
  1620. message: error,
  1621. type: "error"
  1622. });
  1623. });
  1624. },
  1625. //显示新增界面
  1626. handleAdd(i, item) {
  1627. if(i == -1) {
  1628. this.title = "新增项目";
  1629. this.addForm = {
  1630. name: '',
  1631. isPublic:0,
  1632. userId: [],
  1633. userNames:'',
  1634. code:'',
  1635. inchargerId:null,
  1636. level:1,
  1637. customerId:null,
  1638. notifyUserNames:'',
  1639. chosenLeaders:[],
  1640. taskGpIncharge: 0,
  1641. category:null
  1642. }
  1643. this.projectBaseCostData = [];
  1644. this.auseList = [];
  1645. for (var m=0;m<this.baseCostItemList.length; m++) {
  1646. this.projectBaseCostData.push({baseId: this.baseCostItemList[m].id, baseName:this.baseCostItemList[m].name, baseAmount:0});
  1647. }
  1648. } else {
  1649. this.title = "修改项目";
  1650. var list = item.participator;
  1651. if (item.isPublic == 1) {
  1652. list = this.users;
  1653. }
  1654. var arr = [];
  1655. var names = '';
  1656. for(var j in list) {
  1657. arr.push(list[j].id)
  1658. names += list[j].name+',';
  1659. }
  1660. if (names.length > 0) {
  1661. names = names.substring(0, names.length -1);
  1662. }
  1663. this.addForm = {
  1664. id: item.id,
  1665. name: item.projectName,
  1666. isPublic: item.isPublic,
  1667. userId: arr,
  1668. userNames:names,
  1669. code:item.projectCode,
  1670. inchargerId: item.inchargerId,
  1671. level: item.level,
  1672. planStartDate: item.planStartDate,
  1673. planEndDate: item.planEndDate,
  1674. budget: item.budget,
  1675. baseMan: item.baseMan,
  1676. contractAmount: item.contractAmount,
  1677. baseFee: item.baseFee,
  1678. baseRisk1: item.baseRisk1,
  1679. baseRisk2: item.baseRisk2,
  1680. baseOutsourcing: item.baseOutsourcing,
  1681. customerId:item.customerId==0?null:item.customerId,
  1682. taskGpIncharge: item.taskGpIncharge,
  1683. category:item.category
  1684. }
  1685. console.log("handleadd",item)
  1686. if(item.associateDegrees != null && item.associateDegrees != 'null' && item.associateDegrees != '') {
  1687. var spli = item.associateDegrees.split(',')
  1688. var sl = []
  1689. for(var i in spli) {
  1690. var num = +spli[i] + 0
  1691. sl.push(num)
  1692. }
  1693. this.auseList = sl
  1694. console.log(this.auseList)
  1695. } else {
  1696. this.auseList = []
  1697. }
  1698. // var spli = item.associateDegrees.split(',')
  1699. // var sl = []
  1700. // for(var i in spli) {
  1701. // var num = +spli[i] + 0
  1702. // sl.push(num)
  1703. // }
  1704. // this.auseList = sl
  1705. // console.log(this.auseList)
  1706. this.changeParticipator();
  1707. this.getProjectBaseData(item.id);
  1708. if (this.user.company.packageEngineering == 1) {
  1709. this.getProjectProfessions(item.id);
  1710. }
  1711. //获取项目的相关领导
  1712. this.getProjectNotifyUserList(item.id);
  1713. this.getProjectAutorList(item.id);
  1714. }
  1715. this.addFormVisible = true;
  1716. if (this.user.company.packageEngineering == 1) {
  1717. if (this.professionList.length == 0) {
  1718. this.getProfessionList();
  1719. }
  1720. }
  1721. },
  1722. //获取项目审核人
  1723. getProjectAutorList(projectId) {
  1724. this.http.post('/project-auditor/getList',{projectId: projectId},
  1725. res => {
  1726. if (res.code == "ok") {
  1727. this.addForm.auditUserIds = res.data.map(function(item) {
  1728. return item.auditorId;
  1729. });
  1730. } else {
  1731. this.$message({
  1732. message: res.msg,
  1733. type: "error"
  1734. });
  1735. }
  1736. },
  1737. error => {
  1738. this.listLoading = false;
  1739. this.$message({
  1740. message: error,
  1741. type: "error"
  1742. });
  1743. }
  1744. );
  1745. },
  1746. getProjectBaseData(projectId) {
  1747. this.http.post('/project-basecost/get',{projectId: projectId},
  1748. res => {
  1749. if (res.code == "ok") {
  1750. this.projectBaseCostData = res.data;
  1751. } else {
  1752. this.$message({
  1753. message: res.msg,
  1754. type: "error"
  1755. });
  1756. }
  1757. },
  1758. error => {
  1759. this.listLoading = false;
  1760. this.$message({
  1761. message: error,
  1762. type: "error"
  1763. });
  1764. }
  1765. );
  1766. },
  1767. //提交子项目创建修改请求
  1768. submitInsertSubProject () {
  1769. this.$refs.form2.validate(valid => {
  1770. if (valid) {
  1771. this.http.post('/sub-project/saveOrUpdate',this.temaddForm,
  1772. res => {
  1773. if (res.code == "ok") {
  1774. this.$message({
  1775. message: "操作成功",
  1776. type: "success"
  1777. });
  1778. this.subProject(this.currentProject);
  1779. this.addSubProject = false;
  1780. } else {
  1781. this.$message({
  1782. message: res.msg,
  1783. type: "error"
  1784. });
  1785. }
  1786. },
  1787. error => {
  1788. this.listLoading = false;
  1789. this.$message({
  1790. message: error,
  1791. type: "error"
  1792. });
  1793. }
  1794. );
  1795. }
  1796. });
  1797. },
  1798. // 项目基线合计
  1799. addUpfun() {
  1800. var total = 0;
  1801. for (var i=0;i<this.projectBaseCostData.length; i++) {
  1802. total += parseFloat(this.projectBaseCostData[i].baseAmount);
  1803. }
  1804. this.addForm.budget = total;
  1805. // var a = '0'
  1806. // var q = '0'
  1807. // var w = '0'
  1808. // var e = '0'
  1809. // var r = '0'
  1810. // // this.addForm.baseMan === undefined || this.addForm.baseMan === NaN ? this.addForm.baseMa = '0' : this.addForm.baseMan
  1811. // if (this.addForm.baseMan == undefined || this.addForm.baseMan == NaN) {
  1812. // a = 0
  1813. // } else {
  1814. // a = this.addForm.baseMan
  1815. // }
  1816. // if (this.addForm.baseFee !== undefined) q = this.addForm.baseFee
  1817. // if (this.addForm.baseOutsourcing !== undefined) w = this.addForm.baseOutsourcing
  1818. // if (this.addForm.baseRisk1 !== undefined) e = this.addForm.baseRisk1
  1819. // if (this.addForm.baseRisk2 !== undefined) r = this.addForm.baseRisk2
  1820. // this.addForm.budget = +a + +q + +w + +e + +r
  1821. },
  1822. submitInsert() {
  1823. this.$refs.form1.validate(valid => {
  1824. if (valid) {
  1825. if (this.user.company.packageEngineering == 1) {
  1826. if (!this.checkProjectProfession()) {//检查不通过,直接返回
  1827. return;
  1828. }
  1829. }
  1830. this.addLoading = true;
  1831. let formData = new FormData();
  1832. formData.append("name", this.addForm.name);
  1833. if(this.addForm.id != null) {
  1834. formData.append("id", this.addForm.id);
  1835. }
  1836. if(this.addForm.isPublic != null) {
  1837. formData.append("isPublic", this.addForm.isPublic);
  1838. }
  1839. if(this.addForm.userId.length != 0 && this.addForm.isPublic == 0) {
  1840. for(var j in this.addForm.userId) {
  1841. formData.append("userId", this.addForm.userId[j]);
  1842. }
  1843. }
  1844. if(this.addForm.inchargerId != null) {
  1845. formData.append("inchargerId", this.addForm.inchargerId);
  1846. }
  1847. if(this.addForm.code != null) {
  1848. formData.append("code", this.addForm.code);
  1849. }
  1850. if(this.addForm.planStartDate != null) {
  1851. formData.append("planStartDate", this.addForm.planStartDate);
  1852. }
  1853. if(this.addForm.planEndDate != null) {
  1854. formData.append("planEndDate", this.addForm.planEndDate);
  1855. }
  1856. if(this.addForm.level != null) {
  1857. formData.append("level", this.addForm.level);
  1858. }
  1859. if(this.addForm.contractAmount != null) {
  1860. formData.append("contractAmount", this.addForm.contractAmount);
  1861. }
  1862. if (this.projectBaseCostData != null) {
  1863. formData.append("projectBaseCostData", JSON.stringify(this.projectBaseCostData));
  1864. //计算总预算成本
  1865. if (this.addForm.budget == null) {
  1866. this.addForm.budget = 0;
  1867. }
  1868. formData.append("budget", this.addForm.budget);
  1869. }
  1870. if (this.addForm.customerId == null) {
  1871. formData.append("customerId", 0);
  1872. } else {
  1873. formData.append("customerId", this.addForm.customerId);
  1874. }
  1875. if (this.chosenLeaders != null && this.chosenLeaders.length > 0) {
  1876. formData.append("chosenLeaders", JSON.stringify(this.chosenLeaders));
  1877. }
  1878. var listId = []
  1879. var listName = []
  1880. for(var i in this.auseList) {
  1881. for(var j in this.ause) {
  1882. if(this.auseList[i] == this.ause[j].id) {
  1883. listId.push(this.ause[j].id);
  1884. listName.push(this.ause[j].name);
  1885. break;
  1886. }
  1887. }
  1888. }
  1889. listId.toString()
  1890. listName.toString()
  1891. formData.append("associateDegrees", listId)
  1892. formData.append("associateDegreeNames", listName)
  1893. formData.append("taskGpIncharge", this.addForm.taskGpIncharge)
  1894. //日报审核人
  1895. formData.append("auditUserIds", JSON.stringify(this.addForm.auditUserIds));
  1896. if(this.addForm.category != null) {
  1897. formData.append("category", this.addForm.category);
  1898. }
  1899. // formData.append("associateDegreeNames", listName)
  1900. // console.log("addform",formData);
  1901. // return
  1902. this.http.uploadFile(this.port.project.add,formData,
  1903. res => {
  1904. this.addLoading = false;
  1905. if (res.code == "ok") {
  1906. this.$message({
  1907. message: (this.addForm.id!=null?'修改':'创建')+"成功",
  1908. type: "success"
  1909. });
  1910. this.addFormVisible = false;
  1911. this.getList();
  1912. if (this.user.company.packageEngineering == 1) {
  1913. this.saveProjectProfessions(res.data);
  1914. }
  1915. } else {
  1916. this.$message({
  1917. message: res.msg,
  1918. type: "error"
  1919. });
  1920. }
  1921. },
  1922. error => {
  1923. this.addLoading = false;
  1924. this.$message({
  1925. message: error,
  1926. type: "error"
  1927. });
  1928. });
  1929. }
  1930. });
  1931. },
  1932. // 删除
  1933. deletePro(i, item) {
  1934. this.$confirm("确定要删除项目[" + item.projectName + "]吗?","删除项目", {
  1935. confirmButtonText: "确定",
  1936. cancelButtonText: "取消",
  1937. type: "warning"
  1938. })
  1939. .then(() => {
  1940. this.listLoading = true;
  1941. this.http.post(this.port.project.delete,{
  1942. id: item.id
  1943. },
  1944. res => {
  1945. this.listLoading = false;
  1946. if (res.code == "ok") {
  1947. this.$message({
  1948. message: "删除成功",
  1949. type: "success"
  1950. });
  1951. this.getList();
  1952. } else if (res.code == 'reconfirm') {
  1953. this.deleteAlertMsg = res.msg;
  1954. this.forceDeletePro(item.id);
  1955. } else {
  1956. this.$message({
  1957. message: res.msg,
  1958. type: "error"
  1959. });
  1960. }
  1961. },
  1962. error => {
  1963. this.listLoading = false;
  1964. this.$message({
  1965. message: error,
  1966. type: "error"
  1967. });
  1968. }
  1969. );
  1970. })
  1971. .catch(() => {});
  1972. },
  1973. //强制删除项目
  1974. forceDeletePro(deleteProId) {
  1975. this.$confirm(this.deleteAlertMsg,"删除项目", {
  1976. confirmButtonText: "确定",
  1977. cancelButtonText: "取消",
  1978. type: "warning"
  1979. })
  1980. .then(() => {
  1981. this.listLoading = true;
  1982. this.http.post(this.port.project.delete,{
  1983. id: deleteProId ,force:1
  1984. },
  1985. res => {
  1986. this.listLoading = false;
  1987. if (res.code == "ok") {
  1988. this.$message({
  1989. message: "删除成功",
  1990. type: "success"
  1991. });
  1992. this.getList();
  1993. } else {
  1994. this.$message({
  1995. message: res.msg,
  1996. type: "error"
  1997. });
  1998. }
  1999. },
  2000. error => {
  2001. this.listLoading = false;
  2002. this.$message({
  2003. message: error,
  2004. type: "error"
  2005. });
  2006. }
  2007. );
  2008. })
  2009. .catch(() => {});
  2010. },
  2011. detail(i) {
  2012. this.$router.push("/list/" + this.list[i].id + "/" + this.list[i].projectName);
  2013. }
  2014. },
  2015. created() {
  2016. let height = window.innerHeight;
  2017. this.tableHeight = height - 195;
  2018. const that = this;
  2019. window.onresize = function temp() {
  2020. that.tableHeight = window.innerHeight - 195;
  2021. };
  2022. },
  2023. mounted() {
  2024. this.userssHu()
  2025. this.getDepartment();
  2026. this.getList();
  2027. this.getUsers();
  2028. this.getCustomerList();
  2029. this.getProjectBaseConfigList();
  2030. this.getClfConfigList()
  2031. this.yanjiuzx()
  2032. }
  2033. };
  2034. </script>
  2035. <style lang="scss" scoped>
  2036. .rg_span{
  2037. display: inline-block;
  2038. }
  2039. .rg_span span {
  2040. text-align: right;
  2041. box-sizing: border-box;
  2042. padding-right: 10px;
  2043. }
  2044. .el-dialog__title {
  2045. display: inline-table;
  2046. margin-top: 20px;
  2047. }
  2048. .addss {
  2049. width: 100%;
  2050. overflow: hidden;
  2051. white-space: nowrap;
  2052. text-overflow: ellipsis;
  2053. }
  2054. // 111
  2055. </style>
  2056. <style>
  2057. .customdropdown .el-dropdown__caret-button{
  2058. height: 27px;
  2059. }
  2060. .customdropdown .el-button--mini:nth-child(1){
  2061. height: 27px;
  2062. }
  2063. .customdropdown_menu{
  2064. padding: 0;
  2065. }
  2066. .customdropdown_menu_btn{
  2067. border-color: transparent;
  2068. }
  2069. .ganttdialog .el-dialog__body{
  2070. height: 880px;
  2071. }
  2072. .toolbar_formitem_n1{
  2073. margin-right: 0 !important;
  2074. }
  2075. </style>