project_gantt.vue 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889
  1. <template>
  2. <div class="container">
  3. <!-- <div class="gantt_head">
  4. <div class="head_RorX">
  5. <div class="filter-lefts">
  6. <el-radio-group v-model="radio1" @change="selChange()" size="small">
  7. <el-radio-button :label="$t('an-ren-yuan-cha-kan')" value="renyuan"></el-radio-button>
  8. <el-radio-button :label="$t('an-xiang-mu-cha-kan')" value="xiangmu"></el-radio-button>
  9. <el-radio-button :label="$t('zi-yuan-xu-qiu')" value="demand"></el-radio-button>
  10. </el-radio-group>
  11. </div>
  12. </div>
  13. 时间段筛选
  14. <div class="head_date" v-if="isDataLoaded">
  15. <span>{{ $t('message.period') }}</span>
  16. <el-date-picker
  17. style="margin-left:9px;width:15vw;margin-right: 8px;"
  18. size="small"
  19. v-model="valueDate"
  20. type="daterange"
  21. :range-separator="$t('other.to')"
  22. :start-placeholder="$t('time.startDate')"
  23. :end-placeholder="$t('time.endDate')"
  24. value-format="yyyy-MM-dd"
  25. @change="dateupdata()">
  26. </el-date-picker>
  27. </div>
  28. 任务类型筛选
  29. <div v-if="radio1 == $t('an-xiang-mu-cha-kan')" class="head_taskType">
  30. <span>{{ $t('ren-wu-lei-xing') }}</span>
  31. <el-select clearable filterable v-model="taskType" :placeholder="$t('defaultText.pleaseChoose')" size="small" style="margin-left:9px;width:10vw" @change="taskTypeSel()">
  32. <el-option v-for="item in typeList" :label="item.name" :value="item.id" :key="item.id">
  33. <div style="display: flex;justify-content: space-between;align-items: center;">
  34. 左边是文字,右边是色块(有color的话)
  35. <div style="float: left; ">{{ item.name }}</div>
  36. <div v-if="item.color" :style="'width:40px;margin-left:20px;height:20px;background-color:'+item.color"></div>
  37. </div>
  38. </el-option>
  39. </el-select>
  40. </div>
  41. 任务分组筛选
  42. <div v-if="reqpar1" class="head_taskgroup">
  43. <span>{{ $t('other.taskGroup') }}</span>
  44. <el-select clearable filterable v-model="valuex2" :placeholder="$t('defaultText.pleaseChoose')" size="small" style="margin-left:9px;width:10vw" @change="taskgroupSel()">
  45. <el-option
  46. v-for="item in taskgroupList"
  47. :key="item.name"
  48. :label="item.name"
  49. :value="item.name"
  50. >
  51. </el-option>
  52. </el-select>
  53. </div>
  54. 人员/项目筛选
  55. <div class="head_select">
  56. <span>{{(this.radio1 == $t('an-ren-yuan-cha-kan') ? $t('ren-yuan') : $t('other.project'))}}</span>
  57. <el-select v-if="reqpar1" clearable filterable v-model="valuex" :placeholder="$t('defaultText.pleaseChoose')" size="small" style="margin-left:9px;width:10vw" @change="optupdata()">
  58. <el-option v-for="item in screenList" :key="item.id" :label="item.projectName" :value="item.id">
  59. <span v-if="reqpar1" style="float: left;color: #8492a6;">{{ item.projectCode }}</span>
  60. <span v-if="reqpar1" style="float: right;font-size: 13px;margin-left: 20px">{{ item.projectName }}</span>
  61. </el-option>
  62. </el-select>
  63. <el-select v-if="!reqpar1 && user.userNameNeedTranslate != '1'" clearable filterable v-model="valuex" :placeholder="$t('defaultText.pleaseChoose')" size="small" style="margin-left:9px;width:10vw" @change="optupdata()">
  64. <el-option v-for="item in screenList" :key="item.id" :label="item.name" :value="item.id">
  65. </el-option>
  66. </el-select>
  67. <selectCat v-if="!reqpar1 && user.userNameNeedTranslate == '1'" style="margin-left:9px;" :size="'small'" :widthStr="'153'" :subject="screenList" :subjectId="valuex" :distinction="'1'" @selectCal="selectCal"></selectCat>
  68. </div>
  69. 资源需求导入/导出
  70. <div class="head_files" v-if="!isDataLoaded">
  71. <div style="margin-left:10px;float:left;">
  72. <el-link type="primary" :underline="false" :href="'./upload/'+$t('zi-yuan-xu-qiu-dao-ru-mo-ban')+'.xlsx'" download="资源需求导入模板.xlsx">{{ $t('Downloadthetemplate') }}</el-link>
  73. </div>
  74. <el-upload ref="upload" style="margin-left:10px;float:left;" action="#" :limit="1" :http-request="importProject" :show-file-list="false">
  75. <el-link type="primary" :underline="false" >{{ $t('dao-ru-xu-qiu') }}</el-link>
  76. </el-upload>
  77. <div style="margin-left:10px;float:left;">
  78. <el-link type="primary" :underline="false" @click="exportProjectData" download="资源需求导出.xlsx">{{ $t('dao-chu-xu-qiu') }}</el-link>
  79. </div>
  80. </div>
  81. </div> -->
  82. <!-- 甘特图表头 -->
  83. <div class="ganttChartHeader">
  84. <!-- 切换 -->
  85. <div class="eachLayout">
  86. <el-radio-group v-model="radio1" @change="selChange()" size="small">
  87. <el-radio-button :label="$t('an-ren-yuan-cha-kan')" value="renyuan"></el-radio-button>
  88. <el-radio-button :label="$t('an-xiang-mu-cha-kan')" value="xiangmu"></el-radio-button>
  89. <el-radio-button :label="$t('zi-yuan-xu-qiu')" value="demand"></el-radio-button>
  90. </el-radio-group>
  91. </div>
  92. <!-- 时间段 -->
  93. <template v-if="radio1 == $t('an-ren-yuan-cha-kan') || radio1 == $t('an-xiang-mu-cha-kan')">
  94. <div class="eachLayout">
  95. <div class="eachLayout-title">{{ $t('message.period') }}</div>
  96. <el-date-picker
  97. class="eachLayout-title"
  98. size="small"
  99. v-model="valueDate"
  100. type="daterange"
  101. :clearable="false"
  102. :range-separator="$t('other.to')"
  103. :start-placeholder="$t('time.startDate')"
  104. :end-placeholder="$t('time.endDate')"
  105. value-format="yyyy-MM-dd"
  106. @change="dateupdata()">
  107. </el-date-picker>
  108. <el-button size="small" @click="weekSwitching('prev2')">上上周</el-button>
  109. <el-button size="small" @click="weekSwitching('prev')">上周</el-button>
  110. <el-button size="small" @click="weekSwitching('next')">下周</el-button>
  111. </div>
  112. <div class="eachLayout">
  113. <div class="eachLayout-colorBlock" style="background: #ffa500">待审核</div>
  114. <div class="eachLayout-colorBlock" style="background: #32cd32">已通过</div>
  115. <div class="eachLayout-colorBlock" style="background: #ff0000">已驳回/漏填</div>
  116. <div class="eachLayout-colorBlock" style="background: #e0e0e0">未提交</div>
  117. </div>
  118. </template>
  119. <!-- 任务类型 -->
  120. <template v-if="radio1 == $t('an-xiang-mu-cha-kan')">
  121. <div class="eachLayout">
  122. <div class="eachLayout-title">{{ $t('ren-wu-lei-xing') }}</div>
  123. <el-select clearable filterable v-model="taskType" :placeholder="$t('defaultText.pleaseChoose')" size="small" style="width: 180px" @change="taskTypeSel()">
  124. <el-option v-for="item in typeList" :label="item.name" :value="item.id" :key="item.id">
  125. <div style="display: flex;justify-content: space-between;align-items: center;">
  126. <!-- 左边是文字,右边是色块(有color的话) -->
  127. <div style="float: left; ">{{ item.name }}</div>
  128. <div v-if="item.color" :style="'width:40px;margin-left:20px;height:20px;background-color:'+item.color"></div>
  129. </div>
  130. </el-option>
  131. </el-select>
  132. </div>
  133. </template>
  134. <!-- 任务分组 -->
  135. <template v-if="radio1 == $t('an-xiang-mu-cha-kan') || radio1 == $t('zi-yuan-xu-qiu')">
  136. <div class="eachLayout">
  137. <div class="eachLayout-title">分组</div>
  138. <el-select clearable filterable v-model="valuex2" :placeholder="$t('defaultText.pleaseChoose')" size="small" style="width: 180px"@change="taskgroupSel()">
  139. <el-option v-for="item in taskgroupList" :key="item.name" :label="item.name" :value="item.name"></el-option>
  140. </el-select>
  141. </div>
  142. </template>
  143. <!-- 项目 -->
  144. <template v-if="radio1 == $t('an-xiang-mu-cha-kan') || radio1 == $t('zi-yuan-xu-qiu')">
  145. <div class="eachLayout">
  146. <div class="eachLayout-title">项目</div>
  147. <el-select clearable filterable v-model="valuex" :placeholder="$t('defaultText.pleaseChoose')" size="small" style="width:180px" @change="optupdata()">
  148. <el-option v-for="item in screenList" :key="item.id" :label="item.projectName" :value="item.id">
  149. <span style="float: left;color: #8492a6;">{{ item.projectCode }}</span>
  150. <span style="float: right;font-size: 13px;margin-left: 20px">{{ item.projectName }}</span>
  151. </el-option>
  152. </el-select>
  153. </div>
  154. </template>
  155. <!-- 人员 -->
  156. <template v-if="radio1 == $t('an-ren-yuan-cha-kan')">
  157. <div class="eachLayout">
  158. <div class="eachLayout-title">人员</div>
  159. <el-select clearable filterable v-model="valuex" :placeholder="$t('defaultText.pleaseChoose')" size="small" style="width: 180px" @change="optupdata()">
  160. <el-option v-for="item in screenList" :key="item.id" :label="item.name" :value="item.id"></el-option>
  161. </el-select>
  162. </div>
  163. </template>
  164. <!-- 其他操作 -->
  165. <template v-if="radio1 == $t('zi-yuan-xu-qiu')">
  166. <div class="eachLayout">
  167. <el-link type="primary" :underline="false" :href="'./upload/'+$t('zi-yuan-xu-qiu-dao-ru-mo-ban')+'.xlsx'" download="资源需求导入模板.xlsx">{{ $t('Downloadthetemplate') }}</el-link>
  168. <el-upload ref="upload" style="margin: 0 10px;" action="#" :limit="1" :http-request="importProject" :show-file-list="false">
  169. <el-link type="primary" :underline="false" >{{ $t('dao-ru-xu-qiu') }}</el-link>
  170. </el-upload>
  171. <el-link type="primary" :underline="false" @click="exportProjectData" download="资源需求导出.xlsx">{{ $t('dao-chu-xu-qiu') }}</el-link>
  172. </div>
  173. </template>
  174. </div>
  175. <div :style="`height: ${radio1 == $t('an-xiang-mu-cha-kan') ? '40' : '0'}px`"></div>
  176. <gantt v-if="isDataLoaded && user.userNameNeedTranslate != 1" ref="ganttTable1" class="left-container" :tasks="tasks"
  177. :stafforpro="radio1"
  178. :valueDate="valueDate"
  179. :key="updatakey1"
  180. @closeBounced="closeBounced"
  181. :style="`height: ${radio1 == $t('an-xiang-mu-cha-kan') ? '84' : '88'}vh`"
  182. ></gantt>
  183. <vueGantt v-if="isDataLoaded && user.userNameNeedTranslate == 1" ref="ganttTable1" :stafforpro="radio1"
  184. :valueDate="valueDate"
  185. :key="updatakey1" :tasks="tasks"></vueGantt>
  186. <div class="demand-container" v-if="!isDataLoaded">
  187. <el-table height="84vh" :loading="demandListLoading" :data="demandList" border>
  188. <el-table-column :label="user.companyId == '7030' ? '项目令号' : $t('Itemno')" prop="projectCode" width="160"></el-table-column>
  189. <el-table-column :label="$t('headerTop.projectName')" prop="projectName" min-width="240"></el-table-column>
  190. <el-table-column :label="$t('jin-qi-ri-huo-yue-ren-yuan')" prop="activeUsers" min-width="240">
  191. <template slot-scope="scope">
  192. <div>
  193. <span v-if="user.userNameNeedTranslate == 1">
  194. <span v-for="(item, index) in scope.row.activeUsers" :key="index">
  195. <TranslationOpenDataText type='userName' :openid='item'></TranslationOpenDataText>
  196. <span v-if="index < scope.row.activeUsers.length - 1">,</span>
  197. </span>
  198. </span>
  199. <span v-if="user.userNameNeedTranslate != 1">
  200. {{scope.row.activeUsers}}
  201. </span>
  202. </div>
  203. </template>
  204. </el-table-column>
  205. <el-table-column :label="$t('starttimes') +' - '+ $t('time.endTime')" min-width="240">
  206. <template slot-scope="scope">
  207. <span>{{scope.row.startDate ? scope.row.startDate + ' ~ ' + scope.row.endDate : ''}}</span>
  208. </template>
  209. </el-table-column>
  210. <el-table-column :label="$t('he-tong-yao-qiu')" prop="contractReq" min-width="240" show-overflow-tooltip></el-table-column>
  211. <el-table-column :label="$t('li-cheng-bei-jin-du')" prop="milepost" min-width="280">
  212. <template slot-scope="scope">
  213. <span>{{scope.row.milepost ? scope.row.milepost.name + '\u3000'+$t('wan-cheng-shi-jian')+':' + scope.row.milepost.finishDate : ''}}</span>
  214. </template>
  215. </el-table-column>
  216. <el-table-column :label="$t('ren-yuan-xu-qiu')" prop="membReq" min-width="280"></el-table-column>
  217. <el-table-column :label="$t('ren-wu-xu-qiu')" prop="taskReq" min-width="280"></el-table-column>
  218. <el-table-column :label="$t('can-yu-bu-men-jin-du')" prop="departmentSpeed" min-width="280"></el-table-column>
  219. <el-table-column :label="$t('operation')" width="120" align="center" fixed="right">
  220. <template slot-scope="scope">
  221. <el-button @click="demandEdit(scope.row)" size="small">{{ $t('xiu-gai') }}</el-button>
  222. </template>
  223. </el-table-column>
  224. </el-table>
  225. <div class="poss">
  226. <el-pagination
  227. @size-change="handleSizeChange"
  228. @current-change="handleCurrentChange"
  229. :current-page="pageIndex"
  230. :page-sizes="[20, 50, 100, 200]"
  231. :page-size="20"
  232. layout="total, sizes, prev, pager, next"
  233. :total="total">
  234. </el-pagination>
  235. </div>
  236. <!-- 资源需求修改 -->
  237. <el-dialog v-if="demandEditDialog" width="500px" append-to-body :visible.sync="demandEditDialog" :title="$t('xiu-gai') +' - ' + editParameter.projectName">
  238. <el-form label-width="150">
  239. <el-form-item :label="$t('starttimes')">
  240. <el-date-picker
  241. style="width:350px"
  242. v-model="editDate1"
  243. type="date"
  244. :placeholder="$t('defaultText.pleaseChoose')"
  245. value-format="yyyy-MM-dd"></el-date-picker>
  246. </el-form-item>
  247. <el-form-item :label="$t('time.endTime')">
  248. <el-date-picker
  249. style="width:350px"
  250. v-model="editDate2"
  251. type="date"
  252. :placeholder="$t('defaultText.pleaseChoose')"
  253. value-format="yyyy-MM-dd"></el-date-picker>
  254. </el-form-item>
  255. <el-form-item :label="$t('ren-yuan-xu-qiu')">
  256. <el-input style="width:350px" v-model="editParameter.membReq" clearable></el-input>
  257. </el-form-item>
  258. <el-form-item :label="$t('ren-wu-xu-qiu')">
  259. <el-input style="width:350px" v-model="editParameter.taskReq" clearable></el-input>
  260. </el-form-item>
  261. <el-form-item :label="$t('he-tong-yao-qiu')">
  262. <el-input style="width:350px" v-model="editParameter.contractReq" clearable></el-input>
  263. </el-form-item>
  264. <el-form-item :label="$t('bu-men-jin-du')">
  265. <el-input style="width:350px" v-model="editParameter.departmentSpeed" clearable></el-input>
  266. </el-form-item>
  267. </el-form>
  268. <div slot="footer" class="dialog-footer">
  269. <el-button type="default" @click="demandEditDialog = false">{{ $t('btn.cancel') }}</el-button>
  270. <el-button type="primary" @click="demandEditSure" >{{ $t('btn.determine') }}</el-button>
  271. </div>
  272. </el-dialog>
  273. </div>
  274. </div>
  275. </template>
  276. <script>
  277. import { error } from 'dingtalk-jsapi';
  278. import Gantt from './gantt.vue';
  279. import vueGantt from './vueGantt.vue'
  280. // 自定义select组件
  281. import SelectCat from "@/components/select.vue"
  282. export default {
  283. name: 'project_gantt',
  284. props: {},
  285. components: {Gantt, vueGantt, SelectCat},
  286. data() {
  287. return {
  288. taskType: '',
  289. isDataLoaded:false,
  290. tasks: {
  291. data : [],
  292. links: []
  293. },
  294. tasks1: {links:[]},
  295. updatakey1: 1,
  296. updatakey2: -1,
  297. radio1:this.$t('an-ren-yuan-cha-kan'),
  298. valueDate:[],
  299. options:[{value:this.$t('xuan-xiang-1'),label:this.$t('all')},{value:this.$t('xuan-xiang-2'),label:this.$t('ren-yuan')+"1"}],
  300. valuex:'',
  301. screenList:[],
  302. // 请求参数
  303. reqpar1:0,
  304. reqpar2:[],
  305. demandListLoading: false,
  306. demandList: [],
  307. pageIndex: 1,
  308. pageSize: 20,
  309. demandEditDialog: false,
  310. editParameter: {},
  311. editDate1: '',
  312. editDate2: '',
  313. taskgroupList: [],
  314. valuex2: '',
  315. user: JSON.parse(sessionStorage.getItem("user")),
  316. typeList: []
  317. };
  318. },
  319. computed: {},
  320. watch: {},
  321. created() {},
  322. mounted() {
  323. let nowdate = new Date()
  324. let nowmonth = nowdate.getMonth() + 1
  325. let startdate = nowdate.getFullYear() + "-" + (nowmonth < 10 ? "0" + nowmonth : nowmonth) + "-" + (nowdate.getDate() < 10 ? "0" + nowdate.getDate() : nowdate.getDate())
  326. let udate = new Date(nowdate.getFullYear(),nowdate.getMonth(),nowdate.getDate() + 31)
  327. let endmonth = udate.getMonth() + 1
  328. let enddate = udate.getFullYear() + "-" + (endmonth < 10 ? "0" + endmonth : endmonth) + "-" + (udate.getDate() < 10 ? "0" + udate.getDate() : udate.getDate())
  329. this.valueDate = [startdate,enddate]
  330. this.valueDate2 = this.valueDate
  331. this.reqpar2 = this.valueDate
  332. // console.log("date",this.valueDate);
  333. this.getList();
  334. this.getScreen()
  335. // this.tasks1 = this.tasks
  336. this.isDataLoaded = true
  337. this.getTaskTypeList()
  338. console.log('<===== 开始执行咯')
  339. localStorage.removeItem('ganttChartTaskId')
  340. },
  341. methods: {
  342. // 周的切换
  343. weekSwitching(weekType) {
  344. // const now = weekType == 'next' ? this.dayjs(this.valueDate[1]) : this.dayjs(this.valueDate[0]); // 获取当前日期
  345. const now = this.dayjs()// 获取当前日期
  346. let startOfWeek, endOfWeek;
  347. switch (weekType) {
  348. case 'prev2': // 上上周
  349. startOfWeek = now.subtract(2, 'week').startOf('week');
  350. endOfWeek = startOfWeek.endOf('week');
  351. break;
  352. case 'prev': // 上周
  353. startOfWeek = now.subtract(1, 'week').startOf('week');
  354. endOfWeek = startOfWeek.endOf('week');
  355. break;
  356. case 'next': // 下周
  357. startOfWeek = now.add(1, 'week').startOf('week');
  358. endOfWeek = startOfWeek.endOf('week');
  359. break;
  360. default:
  361. break;
  362. }
  363. // 设置日期范围
  364. this.valueDate = [startOfWeek.format('YYYY-MM-DD'), endOfWeek.format('YYYY-MM-DD')];
  365. this.dateupdata()
  366. },
  367. getTaskTypeList() {
  368. this.http.post('/task-type/list', { companyId: this.user.companyId },
  369. res => {
  370. if (res.code == "ok") {
  371. this.typeList = res.data;
  372. } else {
  373. this.$message({ message: res.msg, type: "error" });
  374. }
  375. },
  376. error => {
  377. this.$message({ message: error, type: "error" });
  378. });
  379. },
  380. parentLevelOpensPopUpWindowGantt(row) {
  381. setTimeout(() => {
  382. this.$refs.ganttTable1.detaliTaskExposure(row);
  383. }, 1000)
  384. },
  385. closeBounced(obj) {
  386. if(obj.submitInsert) {
  387. if(obj.dateList && obj.dateList.length > 0) {
  388. const formattedDates = obj.dateList.map(dateString => this.formatDate(dateString));
  389. const one = formattedDates[0]
  390. const two = formattedDates[1]
  391. this.valueDate = [one, two]
  392. }
  393. this.dateupdata()
  394. }
  395. },
  396. formatDate(dateString) {
  397. const date = new Date(dateString);
  398. const year = date.getFullYear();
  399. const month = String(date.getMonth() + 1).padStart(2, '0');
  400. const day = String(date.getDate()).padStart(2, '0');
  401. return `${year}-${month}-${day}`;
  402. },
  403. selectCal(obj) {
  404. if(obj.distinction == '1') {
  405. this.valuex = obj.id
  406. this.optupdata()
  407. }
  408. },
  409. setGroup() {
  410. this.$refs.ganttTable1.setGroup();
  411. // this.$refs.ganttTable2.setGroup();
  412. },
  413. taskTypeSel(){
  414. console.log(this.taskType);
  415. this.getList()
  416. },
  417. // 资源需求导出
  418. exportProjectData() {
  419. let parameter = {}
  420. if(this.valuex){
  421. parameter.projectId = this.valuex
  422. }
  423. if(this.valuex2){
  424. parameter.groupName = this.valuex2
  425. }
  426. this.http.post('/project-requirement/exportData',parameter,
  427. res => {
  428. if (res.code == "ok") {
  429. let filePath = res.data;
  430. const a = document.createElement('a'); // 创建a标签
  431. a.setAttribute('download', this.$t('zi-yuan-xu-qiu-dao-chu')+'.xlsx');// download属性
  432. a.setAttribute('href', filePath);// href链接
  433. a.click(); //自执行点击事件
  434. a.remove();
  435. }
  436. },
  437. error => {
  438. this.$message({
  439. message: error,
  440. type: "error"
  441. });
  442. }
  443. );
  444. },
  445. // 资源需求导入
  446. importProject(item) {
  447. //首先判断文件类型
  448. let str = item.file.name.split(".");
  449. let format = str[str.length - 1];
  450. if (format != "xls" && format != "xlsx") {
  451. this.$message({
  452. message: this.$t('other.PleaseselecttheXLSorXLSXfile'),
  453. type: "error"
  454. });
  455. } else {
  456. let formData = new FormData();
  457. formData.append("multipartFile", item.file);
  458. this.http.uploadFile('/project-requirement/importData', formData,
  459. res => {
  460. this.$refs.upload.clearFiles();
  461. if (res.code == "ok") {
  462. this.$message({
  463. message: this.$t('other.importSuccess'),
  464. type: "success"
  465. });
  466. this.getDemandList();
  467. } else {
  468. this.$message({
  469. message: res.msg,
  470. type: "error"
  471. });
  472. }
  473. },
  474. error => {
  475. this.$refs.upload.clearFiles();
  476. this.$message({
  477. message: error,
  478. type: "error"
  479. });
  480. });
  481. }
  482. },
  483. // 人员/项目切换
  484. selChange(){
  485. this.valuex = null
  486. // console.log("切换按钮",this.radio1);
  487. if (this.radio1 == this.$t('an-ren-yuan-cha-kan')) {
  488. this.isDataLoaded = true
  489. this.reqpar1 = 0
  490. this.getList()
  491. this.getScreen()
  492. }else if(this.radio1 == this.$t('an-xiang-mu-cha-kan')){
  493. this.isDataLoaded = true
  494. this.reqpar1 = 1
  495. this.getList()
  496. this.getXmScreen()
  497. this.getTaskgroupList()
  498. }else {
  499. this.reqpar1 = 1
  500. this.isDataLoaded = false
  501. this.pageIndex = 1
  502. this.pageSize = 20
  503. this.valuex = ''
  504. this.valuex2 = ''
  505. this.getDemandList()
  506. this.getXmScreen()
  507. this.getTaskgroupList()
  508. }
  509. },
  510. // 时间段改变
  511. dateupdata(){
  512. this.reqpar2 = this.valueDate
  513. if(this.isDataLoaded){
  514. this.getList()
  515. }else {
  516. this.getDemandList()
  517. }
  518. },
  519. // 人员/项目筛选改变
  520. optupdata(){
  521. // console.log(this.valuex);
  522. if(this.isDataLoaded){
  523. this.getList()
  524. }else{
  525. this.getDemandList()
  526. }
  527. },
  528. // 任务分组筛选改变
  529. taskgroupSel(){
  530. // console.log(this.valuex2);
  531. if(this.isDataLoaded){
  532. this.getList()
  533. }else{
  534. this.getDemandList()
  535. }
  536. },
  537. handleSizeChange(val){
  538. this.pageSize = val
  539. this.pageIndex = 1
  540. this.getDemandList()
  541. },
  542. handleCurrentChange(val){
  543. this.pageIndex = val
  544. this.getDemandList()
  545. },
  546. // 资源需求修改
  547. demandEdit(row){
  548. console.log(row);
  549. this.demandEditDialog = true
  550. this.editParameter = JSON.parse(JSON.stringify(row))
  551. this.editDate1 = this.editParameter.startDate
  552. this.editDate2 = this.editParameter.endDate
  553. // console.log('edit',this.demandEditDialog);
  554. },
  555. demandEditSure(){
  556. this.editParameter.startDate = this.editDate1
  557. this.editParameter.endDate = this.editDate2
  558. delete this.editParameter.reStartDate
  559. delete this.editParameter.reEndDate
  560. delete this.editParameter.milepost
  561. this.http.post('/project-requirement/addOrMod',this.editParameter,
  562. res => {
  563. if(res.code == 'ok'){
  564. this.$message({
  565. message: this.$t('message.modifyTheSuccess'),
  566. type: 'success'
  567. })
  568. this.demandEditDialog = false
  569. this.getDemandList()
  570. }else {
  571. this.$message({
  572. message: res.msg,
  573. type: 'error'
  574. })
  575. }
  576. },err => {
  577. this.$message({
  578. message: err,
  579. type: 'error'
  580. })
  581. })
  582. },
  583. // 获取人员项目筛选列表
  584. getScreen(){
  585. this.http.get('/project/getMyUsers',
  586. res => {
  587. if (res.code == "ok") {
  588. this.screenList = res.data
  589. }else{
  590. this.$message({
  591. message: res.msg,
  592. type: "error"
  593. });
  594. }
  595. },
  596. error => {
  597. this.$message({
  598. message : error,
  599. type : "error"
  600. })
  601. }
  602. )
  603. },
  604. getXmScreen(){
  605. this.http.get('/project/getProjectList',
  606. res => {
  607. if (res.code == "ok") {
  608. this.screenList = res.data
  609. // console.log("screen",this.screenList);
  610. }else{
  611. this.$message({
  612. message: res.msg,
  613. type: "error"
  614. });
  615. }
  616. },
  617. error => {
  618. this.$message({
  619. message : error,
  620. type : "error"
  621. })
  622. }
  623. )
  624. },
  625. // 获取任务分组筛选列表
  626. getTaskgroupList(){
  627. this.http.post('/task-group/getGroupNames',{},
  628. res => {
  629. if(res.code == 'ok'){
  630. this.taskgroupList = res.data
  631. }else {
  632. this.$message({
  633. message: res.msg,
  634. type: 'error'
  635. })
  636. }
  637. },err => {
  638. this.$message({
  639. message: err,
  640. type: 'error'
  641. })
  642. })
  643. },
  644. // 获取甘特图数据
  645. getList() {
  646. let getlistcs = {type : this.reqpar1 , startDate : this.reqpar2[0] , endDate : this.reqpar2[1]}
  647. if(this.reqpar1) {
  648. if(this.valuex != ''){
  649. getlistcs.projectId = this.valuex
  650. }
  651. if(this.valuex2 != ''){
  652. getlistcs.groupName = this.valuex2
  653. }
  654. getlistcs.taskType = this.taskType
  655. }else {
  656. if(this.valuex != ''){
  657. getlistcs.userId = this.valuex
  658. }
  659. }
  660. var urls = '/project/getGanttData';
  661. this.http.post(urls, getlistcs,
  662. // this.http.post('/project/getGanttDataNew', getlistcs,
  663. res => {
  664. if (res.code == "ok") {
  665. for(var i in res.data) {
  666. if(res.data[i].id.indexOf(this.$t('chu-cha')) != '-1') {
  667. res.data[i].color = '#E6A23C'
  668. }
  669. if(res.data[i].id.indexOf(this.$t('other.AskForLeave')) != '-1') {
  670. res.data[i].color = '#F56C6C'
  671. }
  672. res.data[i].startDateStr = JSON.parse(JSON.stringify(res.data[i].start_date || ''))
  673. res.data[i].endDateStr = JSON.parse(JSON.stringify(res.data[i].end_date || ''))
  674. }
  675. this.tasks = {data:res.data};
  676. if(this.user.userNameNeedTranslate != '1') {
  677. let taskson = []
  678. for(let m in this.tasks.data){
  679. this.tasks.data[m].render = null
  680. if(this.tasks.data[m].time != 0){
  681. if(this.tasks.data[m].id != this.tasks.data[m].userId){
  682. this.tasks.data[m].render = 'split'
  683. let item = JSON.parse(JSON.stringify(this.tasks.data[m]))
  684. item.parent = this.tasks.data[m].id
  685. item.id = this.tasks.data[m].id + 'son'
  686. taskson.push(item)
  687. this.tasks.data[m].time = 0
  688. }
  689. }
  690. }
  691. this.tasks.data.push.apply(this.tasks.data,taskson)
  692. for(let i in this.tasks.data){
  693. if(this.tasks.data[i].time == 0){
  694. delete this.tasks.data[i].start_date
  695. delete this.tasks.data[i].end_date
  696. this.tasks.data[i].type = 'milestone'
  697. }
  698. if(this.tasks.data[i].end_date){
  699. let date = new Date(this.tasks.data[i].end_date)
  700. let date2 = new Date(date.getFullYear(),date.getMonth(),date.getDate() + 1)
  701. let dmonth = date2.getMonth() + 1
  702. let dday = date2.getDate()
  703. this.tasks.data[i].end_date = date2.getFullYear() + '-' + (dmonth < 10 ? '0' + dmonth : dmonth) + '-' + (dday < 10 ? '0' + dday : dday)
  704. }
  705. }
  706. }
  707. console.log('ganttData',this.tasks.data);
  708. this.$nextTick(()=>{
  709. this.updatakey1 += 1
  710. })
  711. } else {
  712. this.$message({
  713. message: res.msg,
  714. type: "error"
  715. });
  716. }
  717. },
  718. error => {
  719. this.$message({
  720. message: error,
  721. type: "error"
  722. });
  723. }
  724. );
  725. },
  726. // 获取资源需求列表
  727. getDemandList(){
  728. let parameter = {
  729. pageIndex: this.pageIndex,
  730. pageSize: this.pageSize,
  731. }
  732. if(this.valuex != ''){
  733. parameter.projectId = this.valuex
  734. }
  735. if(this.valuex2 != ''){
  736. parameter.groupName = this.valuex2
  737. }
  738. this.demandListLoading = true
  739. this.http.post('/project-requirement/listByPage',parameter,
  740. res => {
  741. if(res.code == 'ok'){
  742. this.demandListLoading = false
  743. this.total = res.data.total
  744. if(this.user.userNameNeedTranslate == 1) {
  745. for(let i in res.data.records) {
  746. if(res.data.records[i].activeUsers){
  747. res.data.records[i].activeUsers = res.data.records[i].activeUsers.split(',')
  748. }
  749. }
  750. }
  751. this.demandList = res.data.records
  752. }else {
  753. this.demandListLoading = false
  754. this.$message({
  755. message: res.msg,
  756. type: 'error'
  757. })
  758. }
  759. },err => {
  760. this.demandListLoading = false
  761. this.$message({
  762. message: err,
  763. type: 'error'
  764. })
  765. })
  766. },
  767. },
  768. };
  769. </script>
  770. <style scoped lang="scss">
  771. .container {
  772. height: 100%;
  773. width: 100%;
  774. }
  775. .filter-lefts {
  776. display: flex;
  777. align-items: center;
  778. }
  779. .left-container {
  780. overflow: hidden;
  781. position: relative;
  782. }
  783. .demand-container{
  784. overflow: hidden;
  785. position: relative;
  786. height: 92%;
  787. }
  788. .gantt_head{
  789. width: 100%;
  790. height: 80px;
  791. display: flex;
  792. justify-content: space-between;
  793. align-items: center;
  794. }
  795. .gantt_head .head_RorX{
  796. width: 380px;
  797. }
  798. .gantt_head .head_date{
  799. width: 30vw;
  800. }
  801. .gantt_head .head_taskgroup{
  802. width: 15vw;
  803. }
  804. .gantt_head .head_taskType{
  805. width: 15vw;
  806. }
  807. .gantt_head .head_select{
  808. width: 15vw;
  809. }
  810. .gantt_head .head_files{
  811. width: 17vw;
  812. }
  813. .poss {
  814. height: 8%;
  815. float: right;
  816. padding-top: 5px;
  817. }
  818. .container {
  819. // 重新修改表头
  820. .ganttChartHeader {
  821. position: absolute;
  822. padding: 14px 50px 14px 20px;
  823. width: 100%;
  824. box-sizing: border-box;
  825. top: 0;
  826. left: 0;
  827. display: flex;
  828. flex-wrap: wrap;
  829. line-height: 18px;
  830. .eachLayout {
  831. display: flex;
  832. align-items: center;
  833. margin-right: 30px;
  834. margin-bottom: 12px;
  835. .eachLayout-title {
  836. margin-right: 10px;
  837. }
  838. .eachLayout-colorBlock {
  839. padding: 6px 14px;
  840. color: #fff;
  841. border-radius: 4px;
  842. margin-right: 10px;
  843. }
  844. }
  845. }
  846. }
  847. </style>