Task.vue 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073
  1. <template>
  2. <div class="create-container" v-loading="loading">
  3. <div class="title h1" v-if="!isModifyMode">任务</div>
  4. <div class="create-body">
  5. <div class="title h2" v-if="!isModifyMode">基本信息</div>
  6. <el-row :gutter="20">
  7. <el-col :span="15">
  8. <el-form :model="task" :rules="rules" ref="task" label-width="120px" class="demo-task"
  9. style="margin:0 0 0 80px;">
  10. <el-form-item label="任务名称" prop="title" style="width: 700px;">
  11. <el-input size="small" v-if="isModifyMode" v-model="task.title"></el-input>
  12. <span v-if="!isModifyMode">{{task.title}}</span>
  13. <el-tag v-if="!isModifyMode" :type="task.statusVO&&task.statusVO.style">{{task.statusVO ?
  14. task.statusVO.text:''}}
  15. </el-tag>
  16. </el-form-item>
  17. <el-form-item label="任务描述" prop="description" style="width: 700px;">
  18. <el-input autosize v-if="isModifyMode" type="textarea" v-model="task.description"></el-input>
  19. <span v-if="!isModifyMode">{{task.description ? task.description : '暂无'}}</span>
  20. </el-form-item>
  21. <el-form-item label="任务报价" prop="quotePrice" style="width: 700px;">
  22. <el-input size="small" type="number" v-if="isModifyMode" v-model="task.quotePrice">
  23. <template slot="append">¥</template>
  24. </el-input>
  25. <span v-if="!isModifyMode">{{task.quotePrice}}</span>
  26. </el-form-item>
  27. <!--<el-form-item type="number" label="任务定价" prop="fixedPrice">-->
  28. <!--<el-input v-if="isModifyMode" v-model="task.fixedPrice">-->
  29. <!--<template slot="append">¥</template>-->
  30. <!--</el-input>-->
  31. <!--<span v-if="!isModifyMode">{{task.fixedPrice}}</span>-->
  32. <!--</el-form-item>-->
  33. <el-form-item label="测试类型" prop="serviceType">
  34. <el-radio-group v-if="isModifyMode" v-model="task.serviceType" @change="handleTestTypeChange">
  35. <span v-for="(item,index) in serviceType" :key="index">
  36. <el-radio :label="item.code" name="serviceType">{{item.name}}</el-radio>
  37. </span>
  38. </el-radio-group>
  39. <span class="badge" v-if="!isModifyMode">{{serviceName}}</span>
  40. </el-form-item>
  41. <el-form-item label="服务序列号" prop="endPoint" style="width: 700px;"
  42. v-if="showBD&&task.endPoint&&currType.type===1"
  43. >
  44. <el-input v-if="isModifyMode" v-model="task.endPoint.serverCode" label="examId"></el-input>
  45. <span v-if="!isModifyMode&&showBD">{{task.endPoint.serverCode}}</span>
  46. </el-form-item>
  47. <el-form-item label="任务可见性" prop="resource" style="width: 700px;">
  48. <div v-if="!isModifyMode">
  49. <!--<div v-if="task.resource=='1'">{{updateLocation(task.location)}}</div>-->
  50. <div v-if="task.resource==0">定向</div>
  51. <div v-if="task.resource==2">{{resourceType[task.resource]}}</div>
  52. </div>
  53. <el-tabs
  54. :tab-position="tabPosition"
  55. v-model="task.resource"
  56. style="max-height: 200px;"
  57. v-if="isModifyMode"
  58. >
  59. <el-tab-pane :label="resourceType[0]" name="0">
  60. <el-radio-group v-model="task.institution" @change="handleTestTypeChange">
  61. <el-radio
  62. :label="item"
  63. name="type"
  64. v-for="(item,index) in institutionArray"
  65. :key="index"
  66. >{{item.evaluationAgencyName}}
  67. </el-radio>
  68. </el-radio-group>
  69. </el-tab-pane>
  70. <!--<el-tab-pane :label="resourceType[1]" name="1">-->
  71. <!--<provincecity-->
  72. <!--ref="addFormProvince"-->
  73. <!--@selectChange="locationChange"-->
  74. <!--:provinceCode="task.location == null ||task.location.provinceCode==null?'3200':task.location.provinceCode"-->
  75. <!--:cityCode="task.location == null ||task.location.cityCode==null?'3201':task.location.cityCode"-->
  76. <!--&gt;</provincecity>-->
  77. <!--</el-tab-pane>-->
  78. <el-tab-pane :label="resourceType[2]" name="2"></el-tab-pane>
  79. </el-tabs>
  80. </el-form-item>
  81. <el-form-item label="领取人数" prop="contactPhone" v-if="isModifyMode&&task.resource !== '0' && currType.type===0">
  82. <el-input-number v-model="task.participantCount" :min="1" :max="1000" label="领取人数"></el-input-number>
  83. </el-form-item>
  84. <el-form-item label="领取人数" prop="contactPhone" v-if="isModifyMode&&task.resource !== '0' && currType.type===1">
  85. <el-input-number v-model="task.participantCount" :min="2" :max="1000" label="领取人数"></el-input-number>
  86. </el-form-item>
  87. <el-form-item label="Go平台" prop="goPlatform">
  88. <div v-if="!isModifyMode">
  89. <!--<div v-if="task.resource=='1'">{{updateLocation(task.location)}}</div>-->
  90. <div v-if="task.goPlatform">使用</div>
  91. <div v-else>不使用</div>
  92. </div>
  93. <div v-else>
  94. <el-radio-group v-model="task.goPlatform">
  95. <el-radio :label="0">不使用</el-radio>
  96. <el-radio :label="1">使用</el-radio>
  97. </el-radio-group>
  98. </div>
  99. </el-form-item>
  100. <el-form-item label="领取人数" prop="quotePrice" v-if="!isModifyMode">
  101. {{task.acceptedCount }}/{{ task.participantCount}}
  102. </el-form-item>
  103. <el-form-item label="需求文档" prop="doc">
  104. <el-upload
  105. style="width: 400px"
  106. v-if="isModifyMode"
  107. drag
  108. class="upload-demo"
  109. action=""
  110. :on-remove="handleRemove"
  111. :before-remove="beforeRemove"
  112. :limit="1"
  113. :on-exceed="handleExceed"
  114. :http-request="uploadRequireDoc"
  115. :file-list="task.doc"
  116. >
  117. <i class="el-icon-upload"></i>
  118. <div class="el-upload__text">
  119. 将文件拖到此处,或
  120. <em>点击上传</em>
  121. </div>
  122. </el-upload>
  123. <span>
  124. <span v-if="task.requireDocUrl == null || task.requireDocUrl == ''">
  125. <i class="el-icon-document"></i>暂无文件
  126. </span>
  127. <span v-if="task.requireDocUrl != null && task.requireDocUrl != ''">
  128. <a :href="task.requireDocUrl"><el-link :underline="false" type="primary"><i
  129. class="el-icon-document"></i>下载文档</el-link></a>
  130. </span>
  131. </span>
  132. </el-form-item>
  133. <el-form-item label="任务截止时间" prop="datetime">
  134. <div class="block" v-if="isModifyMode">
  135. <el-date-picker
  136. size="small"
  137. v-model="task.datetime"
  138. type="datetime"
  139. placeholder="选择截止时间"
  140. align="right"
  141. :picker-options="pickerOptions"
  142. ></el-date-picker>
  143. </div>
  144. <span v-if="!isModifyMode">{{dateFormat(new Date(task.datetime),'yyyy-MM-dd HH:mm:ss')}}</span>
  145. </el-form-item>
  146. <el-form-item v-if="isModifyMode">
  147. <div class="btn btn-small btn-info" @click="updateTask()">确认修改</div>
  148. <!--<div class="btn btn-small" @click="resetForm()">重置</div>-->
  149. <div class="btn btn-small" @click="cancelMode()">取消</div>
  150. </el-form-item>
  151. <el-form-item v-if="editShortLink && task.endPoint.serverCode && taskOperationControl.confirmFinish" label="任务面板链接" props="shortLink">
  152. <el-input v-model="shortLink" placeholder="请输入短链接生成任务报告" style="width: 800px">
  153. <template slot="append">
  154. <el-button @click="getTaskDataBoard()">确定</el-button>
  155. </template>
  156. </el-input>
  157. </el-form-item>
  158. <el-form-item v-if="shortLink && !editShortLink" label="任务面板链接" props="shortLink">
  159. {{shortLink}}
  160. <i class="el-icon-edit" @click="editShortLink = true" v-if="taskOperationControl.confirmFinish"/>
  161. </el-form-item>
  162. <el-form-item v-if="!isModifyMode">
  163. <el-button size="mini" @click="toProject()">项目详情</el-button>
  164. <el-button v-if="taskOperationControl.update||taskOperationControl.taskRecommend" @click="manageVirtualMachine()" type="primary" size="mini">管理虚拟机</el-button>
  165. <el-button v-if="taskOperationControl.writeReport||taskOperationControl.uploadReport" @click="connectVirtualMachine()" type="primary" size="mini">连接虚拟机</el-button>
  166. <el-button v-if="(taskOperationControl.writeReport||taskOperationControl.uploadReport||taskOperationControl.update||taskOperationControl.taskRecommend)&&task.goPlatform" type="primary" size="mini" @click="toGo()">go语言测试在线测试平台</el-button>
  167. <el-popover
  168. placement="top-start"
  169. title="确认结束?"
  170. width="200"
  171. trigger="hover"
  172. content="测评机构已提交结束申请,请确认是否结束该任务">
  173. <el-button v-if="taskOperationControl.confirmFinish" type="success" size="mini" slot="reference"
  174. @click="endTask()">确认结束
  175. </el-button>
  176. </el-popover>
  177. <el-popover
  178. placement="top-start"
  179. title="确认提交?"
  180. width="200"
  181. trigger="hover"
  182. content="提交任务后不可更改,等待区域管理员验收">
  183. <el-button v-if="taskOperationControl.finish" type="primary" size="mini" slot="reference"
  184. @click="submitTaskRequest()">提交任务
  185. </el-button>
  186. </el-popover>
  187. <el-popover
  188. placement="top-start"
  189. title="确认拒绝?"
  190. width="200"
  191. trigger="hover"
  192. content="拒绝后不可再接收此任务,且该任务对您不可见">
  193. <el-button v-if="taskOperationControl.reject" type="danger" size="mini" slot="reference"
  194. @click="rejectTask()">拒绝任务
  195. </el-button>
  196. </el-popover>
  197. <el-popover
  198. placement="top-start"
  199. title="确认接收?"
  200. width="200"
  201. trigger="hover"
  202. content="接收任务后请认真完成!">
  203. <el-button v-if="taskOperationControl.receive" type="primary" size="mini" slot="reference"
  204. @click="receiveTask()">接收任务
  205. </el-button>
  206. </el-popover>
  207. <el-button v-if="taskOperationControl.writeReport" type="primary" size="mini" @click="gotoWriteReport()">填写报告
  208. </el-button>
  209. <el-button v-if="taskOperationControl.update" type="primary" size="mini" @click="modifyForm()">修改任务
  210. </el-button>
  211. <el-button v-if="taskOperationControl.taskRecommend" type="primary" size="mini" @click="recommendTask()">任务推荐
  212. </el-button>
  213. <el-button v-if="taskOperationControl.testCaseManage" type="primary" size="mini" @click="toTestCases()">
  214. 众测执行
  215. </el-button>
  216. <el-button v-if="taskOperationControl.testCaseExam" type="primary" size="mini" @click="toTestCasesExam()">
  217. 众测审核
  218. </el-button>
  219. <el-button v-if="taskOperationControl.taskDemonstrate" type="success" size="mini" @click="gotoDataboard()">
  220. 任务面板
  221. </el-button>
  222. <!--<div class="btn btn-small btn-info"-->
  223. <!--v-if="taskOperationControl.confirmFinish"-->
  224. <!--@click="endTask()">确认结束-->
  225. <!--</div>-->
  226. <!--<div class="btn btn-small btn-info" v-if="!taskOperationControl.finish" @click="submitTaskRequest()">提交任务-->
  227. <!--</div>-->
  228. <!--<div class="btn btn-small btn-info" v-if="!taskOperationControl.receive" @click="receiveTask()">接收任务</div>-->
  229. <!--<div class="btn btn-small btn-danger" v-if="!taskOperationControl.reject" @click="rejectTask()">拒绝任务</div>-->
  230. <!--<div class="btn btn-small btn-info" v-if="taskOperationControl.update" @click="modifyForm()">修改任务</div>-->
  231. <!--<div class="btn btn-small btn-info" v-if="!taskOperationControl.uploadReport" @click="toCreateReport()">上传报告-->
  232. <!--</div>-->
  233. </el-form-item>
  234. </el-form>
  235. </el-col>
  236. <el-col :span="9">
  237. <TaskCloud :info="wordCloud" v-if="wordCloud.length"></TaskCloud>
  238. </el-col>
  239. </el-row>
  240. </div>
  241. <div class="create-body" v-if="!isModifyMode">
  242. <div class="title h2">用户报告列表</div>
  243. <el-collapse accordion style="margin: 0 30px">
  244. <el-collapse-item v-for="(item,index) in acceptedUserList" :key="item.id">
  245. <template slot="title">
  246. <el-row style="width: 100%;font-size: 16px">
  247. <el-col :span="6">{{item.userVO.userName}}</el-col>
  248. <el-col :span="6">{{item.userVO.email}}</el-col>
  249. <el-col :span="6">
  250. <el-tag type="success" v-if="item.crowdReportVOS">已提交报告</el-tag>
  251. <el-tag type="info" v-if="!item.crowdReportVOS">未提交报告</el-tag>
  252. </el-col>
  253. <el-col :span="6">
  254. <el-tag type="success" v-if="item.isCommitted">已提交任务</el-tag>
  255. <el-tag type="info" v-if="!item.isCommitted">未提交任务</el-tag>
  256. </el-col>
  257. </el-row>
  258. </template>
  259. <report-list v-bind:reports="item.crowdReportVOS" v-bind:taskId="taskId" v-bind:projectId="projectId"/>
  260. </el-collapse-item>
  261. </el-collapse>
  262. <!-- <report-list v-if="isAgency" v-bind:reports="reportList" v-bind:taskId="taskId" v-bind:projectId="projectId"/>-->
  263. <!-- <report-list v-bind:reports="reportList" v-bind:taskId="taskId" v-bind:projectId="projectId"/>-->
  264. </div>
  265. </div>
  266. </template>
  267. <script>
  268. import ResourceType from '@/constants/enum/resource-type.js'
  269. import provincecity from '@/components/commons/ProvinceCity'
  270. import ReportList from '@/components/report/ReportList'
  271. import TaskCloud from '@/components/task/TaskCloud'
  272. import Http from '@/js/http.js'
  273. import Apis from '@/js/api.js'
  274. import {notify} from '@/constants/index'
  275. import {
  276. ensureEndTask,
  277. getAllAgencies,
  278. getAllServiceTypes,
  279. getFormalTimeFromDate,
  280. getProvinceCodeByProvinceName,
  281. getProvinceNameByProvinceCode,
  282. getTask,
  283. receiveTaskRequest,
  284. rejectTask,
  285. storageGet,
  286. submitTaskRequest,
  287. updateTask,
  288. getTaskWordCloud,
  289. getToken
  290. } from '@/js/index'
  291. export default {
  292. name: 'Task',
  293. components: {
  294. provincecity,
  295. ReportList,
  296. TaskCloud
  297. },
  298. data() {
  299. return {
  300. currType: {},
  301. user: {},
  302. serviceName:'',
  303. showBD: true,
  304. rolesPermissions: {},
  305. loading: false,
  306. isModifyMode: false, institutionArray: [],
  307. tabPosition: 'top',
  308. resourceType: ResourceType,
  309. serviceType: [],
  310. taskId: '',
  311. projectId: '',
  312. taskOperationControl: {
  313. confirmFinish: false,
  314. finish: false,
  315. receive: false,
  316. update: false,
  317. uploadReport: false,
  318. writeReport: false,
  319. taskDemonstrate: false,
  320. taskRecommend: false,
  321. testCaseExam: false,
  322. testCaseManage: false
  323. },
  324. crowdReportUrl: '',
  325. wordCloud:[],
  326. task: {
  327. agencyId: '',
  328. status: '',
  329. name: '',
  330. desc: '',
  331. serviceType: '',
  332. resource: '',
  333. location: {},
  334. institution: {},
  335. datetime: '',
  336. quotePrice: '',
  337. fixedPrice: '',
  338. doc: [],
  339. requireDocUrl: '',
  340. participantCount: 1,
  341. goPlatform: 0,
  342. title: '',
  343. description: '',
  344. endPoint: {
  345. serverCode: '',
  346. token: ''
  347. }
  348. },
  349. reportList: [],
  350. pickerOptions: {
  351. shortcuts: [
  352. {
  353. text: '今天',
  354. onClick(picker) {
  355. picker.$emit('pick', new Date())
  356. }
  357. },
  358. {
  359. text: '昨天',
  360. onClick(picker) {
  361. const date = new Date()
  362. date.setTime(date.getTime() - 3600 * 1000 * 24)
  363. picker.$emit('pick', date)
  364. }
  365. },
  366. {
  367. text: '一周前',
  368. onClick(picker) {
  369. const date = new Date()
  370. date.setTime(date.getTime() - 3600 * 1000 * 24 * 7)
  371. picker.$emit('pick', date)
  372. }
  373. }
  374. ]
  375. },
  376. rules: {
  377. title: [
  378. {required: true, message: '请输入任务名称', trigger: 'blur'},
  379. {min: 5, max: 50, message: '任务名称长度在 5 到 50 个字符', trigger: 'blur'}
  380. ],
  381. serviceType: [
  382. {required: true, message: '测试类型不可为空', trigger: 'change'},
  383. ],
  384. description: [{required: true, message: '请填写描述', trigger: 'blur'}],
  385. //price: [{required: true, message: '请填写价格', trigger: 'blur'}],
  386. quotePrice: [
  387. {required: true, message: '预算不可为空', trigger: 'blur'},
  388. {
  389. validator: (rule, value, callback) => {
  390. if (value < 0) {
  391. callback(new Error('请输入不小于0的数'))
  392. } else {
  393. callback()
  394. }
  395. }, trigger: 'blur'
  396. },
  397. ],
  398. resource: [
  399. {required: true},
  400. {
  401. validator: (rule, value, callback) => {
  402. if (value == 0 && this.task.institution.id == null) {
  403. callback(new Error('定向发布至少要选择一个测评机构'))
  404. } else {
  405. callback()
  406. }
  407. }, trigger: 'change'
  408. },
  409. ],
  410. endPoint: [
  411. {
  412. validator: (rule, value, callback) => {
  413. if (this.currType.type === 1 && this.task.endPoint.serverCode === '') {
  414. callback(new Error('请填写对应得服务序列号'))
  415. } else {
  416. callback()
  417. }
  418. }, trigger: ['change','blur']
  419. },
  420. ],
  421. datetime: [{required: true, message: '截止时间不可为空', trigger: 'blur'}],
  422. },
  423. acceptedUserList: [],
  424. shortLink:'',
  425. editShortLink:false,
  426. creatorId:'',
  427. receiverId:''
  428. }
  429. },
  430. watch: {
  431. institutionArray(val) {
  432. this.institutionArray = val
  433. },
  434. serviceType(val) {
  435. this.serviceType = val
  436. },
  437. deep: true
  438. },
  439. mounted() {
  440. this.$nextTick(() => {
  441. this.init();
  442. })
  443. },
  444. methods: {
  445. //跳转到任务对应的数据面板
  446. gotoDataboard(){
  447. window.open(this.task.endPoint.token)
  448. },
  449. //根据短链接获取生成databoard
  450. getTaskDataBoard(){
  451. this.showLoading()
  452. Http.put(`/api/project/${this.projectId}/task/${this.taskId}/addToken`,{"token":this.shortLink}).then((res)=>{
  453. this.taskOperationControl = res.taskOperationControl;
  454. this.task.endPoint = res.crowdTaskVO.endPointVO;
  455. this.shortLink = res.crowdTaskVO.endPointVO.token;
  456. if(this.shortLink != ''){
  457. this.editShortLink = false;
  458. }
  459. this.hideLoading()
  460. })
  461. },
  462. getServiceByCode(code){
  463. let serviceName = this.serviceType.filter((item) => {
  464. return item.code === code;
  465. });
  466. return serviceName&&serviceName[0]&&serviceName[0]['name']
  467. },
  468. handleTestTypeChange(val) {
  469. let type = this.serviceType.filter((item) => {
  470. return item.code === val;
  471. });
  472. this.currType = type[0] ? type[0] : {};
  473. if (this.currType.type === 0) {
  474. this.$refs.task.clearValidate('endPoint');
  475. }
  476. },
  477. init() {
  478. this.taskId = this.$route.params.taskId
  479. this.projectId = this.$route.params.projectId
  480. this.setUserInfo()
  481. this.setServiceType()
  482. //this.loadData(this.projectId, this.taskId)
  483. this.getTaskDetail()
  484. this.getWordCloud()
  485. this.setInstitutions()
  486. this.getProjectInfo()
  487. },
  488. //北斗测试报告填写跳转
  489. gotoWriteReport() {
  490. window.open(this.crowdReportUrl, '_blank');
  491. },
  492. //跳转至项目详情页面
  493. toProject() {
  494. this.$router.push({
  495. name: 'Project',
  496. params: {projectId: this.projectId}
  497. })
  498. },
  499. toGo() {
  500. let roleid=1;
  501. // console.log(this.user.roleList.length,"this.user.roleList.length");
  502. // console.log(this.user.roleList.includes("generalUser"),'this.user.roleList.includes("generalUser")');
  503. // console.log(this.receiverId,"this.receiverId ",this.user.userVO.id,"this.user.userVO.id");
  504. // console.log(this.creatorId,'this.creatorId')
  505. if(this.user.roleList.length==1 && this.user.roleList.includes("generalUser")){roleid = 1;}
  506. if(this.creatorId==this.user.userVO.id){roleid=3;}
  507. if(this.taskOperationControl.uploadReport){roleid=4;}
  508. if(this.receiverId==this.user.userVO.id){roleid=2;}
  509. // console.log(roleid,'roleid')
  510. let goUrl='http://101.132.74.9:1106/hjc2?project_code='+this.projectId+'&user_id'+this.user.userVO.id+'&role_id='+roleid;
  511. window.open(goUrl, '_blank');
  512. },
  513. //切换至可编辑页面
  514. modifyForm() {
  515. // this.task.serviceType = ''
  516. this.isModifyMode = true
  517. },
  518. //切换至不可编辑页面
  519. cancelMode() {
  520. this.isModifyMode = false
  521. },
  522. //重置表单
  523. resetForm() {
  524. this.task.name = ''
  525. this.task.desc = ''
  526. this.task.quotePrice = ''
  527. this.task.fixedPrice = ''
  528. this.task.type = ''
  529. this.task.resource = '2' //如果是广场不用管Location和institution ,定向看institution,区域看location
  530. this.task.location = {provinceCode: '', cityCode: ''}
  531. this.task.institution = ''
  532. this.task.datetime = ''
  533. this.task.participantCount = 1
  534. this.task.goPlatform = 0
  535. // this.task.endPointVO.caseId = ''
  536. // this.task.endPointVO.examId = ''
  537. },
  538. //显示页面加载画面
  539. showLoading() {
  540. this.loading = true
  541. },
  542. //隐藏页面加载画面
  543. hideLoading() {
  544. this.loading = false
  545. },
  546. //加载用户信息
  547. setUserInfo() {
  548. this.user = storageGet('user')
  549. console.log(this.user,'this.user')
  550. this.rolesPermissions = storageGet('rolesPermissions')
  551. console.log(this.rolesPermissions,'this.rolesPermissions')
  552. if (storageGet('rolesPermissions').isRegionManager || storageGet('rolesPermissions').isSystemAdministrator) {
  553. this.showBD = true;
  554. } else {
  555. this.showBD = false;
  556. }
  557. },
  558. getProjectInfo(){
  559. Http.get(Apis.PROJECT.GET_PROJECT.replace('{projectId}', this.projectId)).then((res) => {
  560. // console.log(res,"获取project res");
  561. this.creatorId = res.projectDetails.userId;
  562. this.receiverId =res.projectDetails.regionManagerId;
  563. // console.log(typeof res.projectDetails.field)
  564. }).catch((error) => {
  565. // this.hideLoading()
  566. // notify('error', error.data)
  567. })
  568. },
  569. //加载任务的测试类型
  570. setServiceType() {
  571. getAllServiceTypes().then((res) => {
  572. this.serviceType = res
  573. }).catch((error) => {
  574. notify('error', '加载测试类型失败')
  575. })
  576. },
  577. //加载所有的测评机构
  578. setInstitutions() {
  579. getAllAgencies().then((res) => {
  580. this.institutionArray = res
  581. }).catch((error) => {
  582. notify('error', '获取机构列表失败')
  583. })
  584. },
  585. //获取任务详情
  586. getTaskDetail() {
  587. this.showLoading()
  588. getTask(this.projectId, this.taskId, this.getTaskDetailSuccess, this.getTaskDetailFail)
  589. },
  590. manageVirtualMachine(){
  591. getToken(this.projectId, this.taskId).then((res) => {
  592. var token = res.data
  593. var url = 'http://docker.chuangchaokeji.cn:38080/cloudtest/api/oauth/gateway?website=cofortest&token='+ token + '&userId='+this.user.userVO.id +
  594. '&screen=PROJECT' + '&projectId='+this.projectId+'&taskId='+this.taskId;
  595. window.open(url);
  596. })
  597. },
  598. // createVirtualMachine(){
  599. // getToken(this.projectId, this.taskId).then((res) => {
  600. // var token = res.data
  601. // var url = 'http://docker.chuangchaokeji.cn:38080/cloudtest/api/oauth/gateway?website=cofortest&token='+ token + '&userId='+this.user.userVO.id +
  602. // '&screen=HOME';
  603. // window.open(url);
  604. // })
  605. // },
  606. connectVirtualMachine(){
  607. getToken(this.projectId, this.taskId).then((res) => {
  608. var token = res.data
  609. var url = 'http://docker.chuangchaokeji.cn:38080/cloudtest/api/oauth/connect?userId='+this.user.userVO.id+ '&projectId='+
  610. this.projectId+'&taskId='+this.taskId+'&token='+token;
  611. window.open(url);
  612. })
  613. },
  614. //获取词云
  615. getWordCloud(){
  616. getTaskWordCloud(this.projectId, this.taskId, this.getTaskCloudSuccess, this.getTaskCloudFail)
  617. },
  618. getTaskCloudSuccess(words){
  619. this.wordCloud = words.data;
  620. },
  621. getTaskCloudFail(err){
  622. notify('error',err)
  623. },
  624. //获取任务详情成功时回调函数
  625. getTaskDetailSuccess(res) {
  626. this.hideLoading()
  627. // console.log(res)
  628. this.taskId = res.crowdTaskVO.id
  629. this.projectId = res.crowdTaskVO.projectId
  630. this.task.title = res.crowdTaskVO.title
  631. this.task.description = res.crowdTaskVO.description
  632. this.task.serviceType = res.crowdTaskVO.serviceType
  633. this.task.resource = res.crowdTaskVO.resource.toString()
  634. this.task.location = getProvinceCodeByProvinceName(res.crowdTaskVO.location.provinceCode, res.crowdTaskVO.location.cityCode)
  635. this.task.institution = res.crowdTaskVO.institution
  636. this.task.datetime = new Date(res.crowdTaskVO.datetime)
  637. this.task.quotePrice = res.crowdTaskVO.quotePrice
  638. this.task.acceptedCount = res.crowdTaskVO.acceptedCount
  639. this.task.participantCount = res.crowdTaskVO.participantCount
  640. this.task.goPlatform = res.crowdTaskVO.goPlatform
  641. this.task.fixedPrice = res.crowdTaskVO.fixedPrice
  642. this.task.doc = []
  643. this.task.requireDocUrl = res.crowdTaskVO.requirementFile
  644. this.task.agencyId = res.crowdTaskVO.agencyId
  645. this.task.status = res.crowdTaskVO.status
  646. this.task.statusVO = res.crowdTaskVO.statusVO
  647. this.task.endPoint = res.crowdTaskVO.endPointVO ? res.crowdTaskVO.endPointVO : {
  648. serverCode: '',
  649. }
  650. this.taskOperationControl = res.taskOperationControl;
  651. console.log(this.taskOperationControl)
  652. this.acceptedUserList = res.acceptedUserList;
  653. this.crowdReportUrl = res.crowdTaskVO.writeReportUrl;
  654. this.handleFormatReport(this.acceptedUserList);
  655. this.handleTestTypeChange(res.crowdTaskVO.serviceType);
  656. this.serviceName = this.getServiceByCode(res.crowdTaskVO.serviceType);
  657. if(res.crowdTaskVO.endPointVO){
  658. if(res.crowdTaskVO.endPointVO.token){
  659. this.shortLink = res.crowdTaskVO.endPointVO.token;
  660. this.editShortLink = false
  661. }else{
  662. this.editShortLink = true
  663. }
  664. }
  665. // console.log(res.crowdTaskVO.endPointVO.token)
  666. // console.log(this.editShortLink)
  667. // console.log(this.isModifyMode)
  668. },
  669. //获取任务详情失败时回调函数
  670. getTaskDetailFail(error) {
  671. this.hideLoading()
  672. // notify('error', '获取任务详情失败:' + error.data)
  673. },
  674. //处理显示报告
  675. handleFormatReport(acceptedUserList) {
  676. console.log(acceptedUserList,"this.acceptedUserList")
  677. acceptedUserList.map((user) => {
  678. user.crowdReportVOS && user.crowdReportVOS.map((report) => {
  679. report.userName = user.userVO.userName;
  680. this.reportList.push(report);
  681. })
  682. })
  683. },
  684. dateFormat(date, format) {
  685. date = new Date(date)
  686. let o = {
  687. 'M+': date.getMonth() + 1, //month
  688. 'd+': date.getDate(), //day
  689. 'H+': date.getHours(), //hour+8小时
  690. 'm+': date.getMinutes(), //minute
  691. 's+': date.getSeconds(), //second
  692. 'q+': Math.floor((date.getMonth() + 3) / 3), //quarter
  693. 'S': date.getMilliseconds() //millisecond
  694. }
  695. if (/(y+)/.test(format)) {
  696. format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
  697. }
  698. for (let k in o)
  699. if (new RegExp('(' + k + ')').test(format))
  700. format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length));
  701. return format;
  702. },
  703. //更新任务信息
  704. updateTask() {
  705. this.$refs['task'].validate(valid => {
  706. if (valid) {
  707. this.showLoading()
  708. const newTask = {
  709. name: this.task.title,
  710. desc: this.task.description,
  711. type: this.task.serviceType,
  712. resource: this.task.resource,
  713. location: this.task.location == null ? {} : getProvinceNameByProvinceCode(this.task.location.provinceCode, this.task.location.cityCode),
  714. institution: this.task.institution ? this.task.institution.id : null,
  715. datetime: this.task.datetime,
  716. quotePrice: this.task.quotePrice,
  717. fixedPrice: this.task.fixedPrice,
  718. requirementFile: this.task.requireDocUrl,
  719. participantCount: this.task.participantCount,
  720. goPlatform: this.task.goPlatform,
  721. endPoint: this.task.endPoint
  722. }
  723. //console.log(newTask)
  724. updateTask(this.projectId, this.taskId, newTask, this.updateTaskSuccess, this.updateTaskFail)
  725. } else {
  726. notify('error', '表单填写有误!')
  727. return false
  728. }
  729. })
  730. },
  731. //更新任务信息成功时回调函数
  732. updateTaskSuccess(res) {
  733. this.cancelMode()
  734. this.taskId = res.crowdTaskVO.id
  735. this.projectId = res.crowdTaskVO.projectId
  736. this.task.title = res.crowdTaskVO.title
  737. this.task.description = res.crowdTaskVO.description
  738. this.task.serviceType = res.crowdTaskVO.serviceType
  739. this.task.resource = res.crowdTaskVO.resource.toString()
  740. this.task.location = res.crowdTaskVO.location == null ? {
  741. provinceCode: 3200,
  742. cityCode: 3201
  743. } : getProvinceCodeByProvinceName(res.crowdTaskVO.location.provinceCode, res.crowdTaskVO.location.cityCode)
  744. this.task.institution = res.crowdTaskVO.institution
  745. this.task.datetime = new Date(res.crowdTaskVO.datetime)
  746. this.task.quotePrice = res.crowdTaskVO.quotePrice
  747. this.task.fixedPrice = res.crowdTaskVO.fixedPrice
  748. // this.task.endPointVO = res.crowdTaskVO.endPointVO
  749. this.task.doc = []
  750. this.task.requireDocUrl = res.crowdTaskVO.requirementFile,
  751. this.task.participantCount = res.crowdTaskVO.participantCount
  752. this.task.goPlatform = res.crowdTaskVO.goPlatform
  753. this.task.endPoint = res.crowdTaskVO.endPointVO ? res.crowdTaskVO.endPointVO : {
  754. serverCode: '',
  755. }
  756. this.task.createTime = res.crowdTaskVO.createTime,
  757. this.reportList = res.crowdReportVOList
  758. this.crowdReportUrl = res.crowdTaskVO.writeReportUrl;
  759. this.acceptedUserList = res.acceptedUserList
  760. this.handleTestTypeChange(res.crowdTaskVO.serviceType);
  761. this.serviceName = this.getServiceByCode(res.crowdTaskVO.serviceType)
  762. this.getWordCloud()
  763. this.hideLoading()
  764. notify('success', '修改成功')
  765. },
  766. //更新任务信息失败时回调函数
  767. updateTaskFail(error) {
  768. notify('error', '修改失败:' + error.data)
  769. this.hideLoading()
  770. },
  771. //上传任务需求文档
  772. uploadRequireDoc(param) {
  773. const formData = new FormData()
  774. let config = {
  775. //添加请求头
  776. headers: {'Content-Type': 'multipart/form-data'},
  777. }
  778. formData.append('file', param.file)
  779. Http.upload(Apis.FILE.REQUIREMENT_FILE.replace('{userId}', this.user.userVO.id), formData, config).then((res) => {
  780. notify('success', '上传成功')
  781. this.uploadRequireDocSuccess(res)
  782. }).catch((error) => {
  783. notify('error', '上传失败:' + error.data)
  784. this.uploadRequireDocFail(error)
  785. })
  786. },
  787. //上传任务需求文档成功时回调函数
  788. uploadRequireDocSuccess(res) {
  789. this.hideLoading()
  790. console.log('上传成功')
  791. this.task.requireDocUrl = res.data
  792. console.log(res.data)
  793. },
  794. //上传任务需求文档失败时回调函数
  795. uploadRequireDocFail(error) {
  796. this.hideLoading()
  797. notify('error', '任务需求文档上传失败:' + error.data)
  798. },
  799. //文档上传前响应函数
  800. //移除文档前的响应函数
  801. beforeRemove(file, fileList) {
  802. //return this.$confirm(`确定移除 ${file.name}?`)
  803. },
  804. //移除文档时的响应函数
  805. handleRemove(file, fileList) {
  806. console.log(file, fileList)
  807. },
  808. //需求文档添加进来时的响应函数
  809. handleExceed(files, fileList) {
  810. this.$message.warning(
  811. `当前限制选择 1 个文件,本次选择了 ${
  812. files.length
  813. } 个文件,共选择了 ${files.length + fileList.length} 个文件`
  814. )
  815. },
  816. //接收任务
  817. receiveTask() {
  818. this.$confirm('确认接收任务?', '提示', {
  819. confirmButtonText: '确认接收',
  820. cancelButtonText: '取消',
  821. type: 'success'
  822. }).then(() => {
  823. this.showLoading()
  824. receiveTaskRequest(this.projectId, this.taskId, this.user.userVO.id, this.receiveTaskSuccess, this.receiveTaskFail)
  825. }).catch(() => {
  826. })
  827. },
  828. //接收任务成功时的回调函数
  829. receiveTaskSuccess(res) {
  830. this.hideLoading()
  831. this.getTaskDetail();
  832. notify('success', '接收任务成功')
  833. // console.log(res)
  834. this.taskOperationControl = res.taskOperationControl
  835. this.task.status = res.crowdTaskVO.status
  836. this.task.institution = res.crowdTaskVO.institution
  837. },
  838. //接收任务失败时的回调函数
  839. receiveTaskFail(error) {
  840. this.hideLoading()
  841. notify('error', '接收任务失败:' + error.data)
  842. },
  843. // 任务推荐
  844. recommendTask(){
  845. let task = {
  846. "title": this.task.title,
  847. "description": this.task.description,
  848. "participantCount": this.task.participantCount,
  849. "quotePrice": this.task.quotePrice,
  850. "requirementFile": this.task.requireDocUrl,
  851. "serviceType": this.task.serviceType,
  852. "createTime": this.task.createTime,
  853. "datetime": this.task.datetime
  854. };
  855. Http.post('/recommendationtest/query',task).then((res)=>{
  856. console.log("recommend")
  857. window.open('http://8.134.39.104:7477/userinformation.html');
  858. })
  859. },
  860. //拒绝任务
  861. rejectTask() {
  862. this.$confirm('确认拒绝任务?拒绝后将不能再接收该任务', '提示', {
  863. confirmButtonText: '确认拒绝',
  864. cancelButtonText: '取消',
  865. type: 'success'
  866. }).then(() => {
  867. this.showLoading()
  868. rejectTask(this.projectId, this.taskId, this.rejectTaskSuccess, this.rejectTaskFail)
  869. }).catch(() => {
  870. })
  871. },
  872. //拒绝任务成功时的回调函数
  873. rejectTaskSuccess(res) {
  874. this.hideLoading()
  875. this.$router.push({
  876. name: 'Mine'
  877. })
  878. notify('success', '拒绝任务成功,已为您自动跳转到个人中心')
  879. },
  880. //拒绝任务失败时的回调函数
  881. rejectTaskFail(error) {
  882. this.hideLoading()
  883. notify('error', '拒绝任务失败:' + error.data)
  884. },
  885. //提交结束任务申请
  886. submitTaskRequest() {
  887. this.$confirm('确认提交任务?提交后将不能再修改', '提示', {
  888. confirmButtonText: '确认提交',
  889. cancelButtonText: '取消',
  890. type: 'success'
  891. }).then(() => {
  892. this.showLoading()
  893. submitTaskRequest(this.projectId, this.taskId, this.submitTaskRequestSuccess, this.submitTaskRequestFail)
  894. }).catch(() => {
  895. })
  896. },
  897. //提交结束任务申请成功时的回调函数
  898. submitTaskRequestSuccess(res) {
  899. this.hideLoading()
  900. console.log(res)
  901. this.taskOperationControl = res.taskOperationControl
  902. this.task.status = res.crowdTaskVO.status
  903. this.task.institution = res.crowdTaskVO.institution
  904. notify('success', '提交任务成功,等待区域管理员审核')
  905. this.getTaskDetail();
  906. },
  907. //提交结束任务申请失败时的回调函数
  908. submitTaskRequestFail(error) {
  909. this.hideLoading()
  910. notify('error', '提交任务失败:' + error.data)
  911. },
  912. //结束任务
  913. endTask() {
  914. this.$confirm('确认结束任务?', '提示', {
  915. confirmButtonText: '确认结束',
  916. cancelButtonText: '取消',
  917. type: 'success'
  918. }).then(() => {
  919. this.getTaskDetail()
  920. this.showLoading()
  921. ensureEndTask(this.projectId, this.taskId, this.endTaskSuccess, this.endTaskFail)
  922. }).catch(() => {
  923. })
  924. },
  925. //结束任务成功时的回调函数
  926. endTaskSuccess(res) {
  927. this.hideLoading()
  928. this.taskOperationControl = res.taskOperationControl
  929. this.task.status = res.crowdTaskVO.status
  930. this.task.institution = res.crowdTaskVO.institution
  931. notify('success', '结束任务成功!')
  932. this.getTaskDetail();
  933. },
  934. //结束任务失败时的回调函数
  935. endTaskFail(error) {
  936. this.hideLoading()
  937. notify('error', '结束任务失败:' + error.data)
  938. },
  939. //跳转到创建项目报告页面
  940. toCreateReport() {
  941. this.$router.push({
  942. name: 'TaskReportCreate',
  943. params: {
  944. scope: 1,
  945. dependencyCode: this.taskId,
  946. projectId: this.projectId,
  947. taskId: this.taskId,
  948. }
  949. })
  950. },
  951. reformDate(date) {
  952. return getFormalTimeFromDate(date)
  953. },
  954. // 跳转到测试用例管理页面
  955. toTestCases () {
  956. this.$router.push({
  957. name: 'TestCases',
  958. params: {
  959. taskCode: this.taskId
  960. }
  961. })
  962. },
  963. // 跳转到测试用例审核页面
  964. toTestCasesExam () {
  965. console.log(this.user.userVO.id)
  966. console.log(this.projectId)
  967. this.$router.push({
  968. name: 'ExamTestCases',
  969. params: {
  970. projectCode: this.projectId,
  971. taskCode: this.taskId,
  972. userId: 0
  973. }
  974. })
  975. }
  976. }
  977. }
  978. //回收站
  979. //
  980. // updateLocation (location) {
  981. // console.log(location)
  982. // const loactionName = getProvinceNameByProvinceCode(location.provinceCode, location.cityCode)
  983. // // var provinceName = ''
  984. // // var cityName = ''
  985. // // for (var item of provinceCityJSON.provinces) {
  986. // // if (item.code === location.provinceCode) {
  987. // // provinceName = item.name
  988. // // for (var city of item.cities) {
  989. // // if (city.code === location.cityCode) {
  990. // // cityName = city.name
  991. // // break
  992. // // }
  993. // // }
  994. // // }
  995. // // }
  996. // return loactionName.provinceCode + ' / ' + loactionName.cityCode
  997. // },
  998. //
  999. // locationChange (provinceId, cityId) {
  1000. // if (provinceId || cityId) {
  1001. // this.task.location = {provinceCode: provinceId, cityCode: cityId}
  1002. // }
  1003. // },
  1004. // submitForm (formName) {
  1005. // this.$refs[formName].validate(valid => {
  1006. // if (valid) {
  1007. // this.isModifyMode = false
  1008. //
  1009. // } else {
  1010. // console.log('error submit!!')
  1011. // return false
  1012. // }
  1013. // })
  1014. // },
  1015. </script>
  1016. <style lang="less" scoped>
  1017. .el-radio {
  1018. margin: 10px 20px 10px 0;
  1019. }
  1020. .el-form-item /deep/ .el-tabs__content {
  1021. /*max-height: 120px !important;*/
  1022. overflow: auto;
  1023. }
  1024. .el-collapse-item__content {
  1025. padding-bottom: 0 !important;
  1026. }
  1027. </style>