DepartProcessAdd.vue 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. <template>
  2. <div style="background-color: white;">
  3. <!-- 加上load效果 -->
  4. <div class="form_center" v-loading="loading">
  5. <el-form :model="form" :rules="rules" ref="form" label-width="120px">
  6. <el-row :gutter="20">
  7. <el-col :span="8">
  8. <el-form-item label="工单名称" prop="name">
  9. <el-input :disabled="forbidden=='true'?true:false" v-model="form.name"></el-input>
  10. </el-form-item>
  11. </el-col>
  12. <el-col :span="8">
  13. <el-form-item label="工单开始时间" prop="startTime">
  14. <el-date-picker :disabled="forbidden=='true'?true:false" v-model="form.startTime" type="datetime" placeholder="选择日期时间"
  15. format="yyyy-MM-dd HH:mm" value-format="yyyy-MM-dd HH:mm">
  16. </el-date-picker>
  17. </el-form-item>
  18. </el-col>
  19. <el-col :span="8">
  20. <el-form-item label="所属团组" prop="groupId">
  21. <el-select :disabled="forbidden=='true'?true:false" filterable v-model="form.groupId" placeholder="请选择">
  22. <el-option v-for="item in initResp.groupList" :key="item.id" :label="item.teamName"
  23. :value="item.id"></el-option>
  24. </el-select>
  25. </el-form-item>
  26. </el-col>
  27. </el-row>
  28. <el-row :gutter="20">
  29. <el-col :span="8">
  30. <!-- 添加筛选 -->
  31. <el-form-item label="指派用户" prop="assignedUserId">
  32. <el-select :disabled="forbidden=='true'?true:false" @change="userChange" filterable v-model="form.assignedUserId" placeholder="请选择">
  33. <el-option v-for="item in initResp.users" :key="item.id" :label="item.cnName"
  34. :value="item.id"></el-option>
  35. </el-select>
  36. </el-form-item>
  37. </el-col>
  38. <el-col :span="8">
  39. <el-form-item label="外办选项" prop="foreignOptionId">
  40. <el-select :disabled="forbidden=='true'?true:false" v-model="form.foreignOptionId" placeholder="请选择">
  41. <el-option v-for="item in initResp.foreignLv" :key="item.id" :label="item.name"
  42. :value="item.id"></el-option>
  43. </el-select>
  44. </el-form-item>
  45. </el-col>
  46. <el-col :span="8">
  47. </el-col>
  48. </el-row>
  49. <div class="form_detail">
  50. <el-collapse v-model="activeNames">
  51. <el-collapse-item title="主要任务" name="1">
  52. <el-table :data="mainTasks" style="width: 100%" border>
  53. <el-table-column type="index" label="序号" width="50"></el-table-column>
  54. <el-table-column prop="name" label="单项任务名称" width="250">
  55. <template slot-scope="scope">
  56. <el-input :disabled="forbidden=='true'?true:(scope.$index + 1 <= form.action - 1)" height="70"
  57. type="textarea" v-model="scope.row.name" size="mini"></el-input>
  58. </template>
  59. </el-table-column>
  60. <el-table-column prop="priorityId" label="优先级" width="100">
  61. <template slot-scope="scope">
  62. <el-select :disabled="forbidden=='true'?true:(scope.$index + 1 <= form.action - 1)"
  63. v-model="scope.row.priorityId" size="mini" placeholder="请选择">
  64. <el-option v-for="item in initResp.taskLv" :key="item.id" :label="item.name"
  65. :value="item.id"></el-option>
  66. </el-select>
  67. </template>
  68. </el-table-column>
  69. <el-table-column prop="isUrgent" label="是否加急" width="80">
  70. <template slot-scope="scope">
  71. <el-switch :disabled="forbidden=='true'?true:(scope.$index + 1 <= form.action - 1)"
  72. v-model="scope.row.isUrgent">
  73. </el-switch>
  74. </template>
  75. </el-table-column>
  76. <el-table-column prop="assignedUserId" label="指派给谁" width="120">
  77. <template slot-scope="scope">
  78. <el-select :disabled="forbidden=='true'?true:(scope.$index + 1 <= form.action - 1)"
  79. v-model="scope.row.assignedUserId" size="mini" placeholder="请选择">
  80. <el-option v-for="item in initResp.users" :key="item.id"
  81. :label="item.cnName" :value="item.id"></el-option>
  82. </el-select>
  83. </template>
  84. </el-table-column>
  85. <el-table-column prop="timeRange" label="任务时间(起止)">
  86. <template slot-scope="scope">
  87. <el-date-picker :disabled="forbidden=='true'?true:(scope.$index + 1 <= form.action - 1)"
  88. v-model="scope.row.timeRange" type="datetimerange" range-separator="至"
  89. start-placeholder="开始日期" end-placeholder="结束日期" size="mini"
  90. format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
  91. @input="onTimeRangeChange(scope.$index)">
  92. </el-date-picker>
  93. </template>
  94. </el-table-column>
  95. <el-table-column prop="durationHours" label="任务默认完成小时数" width="160">
  96. <template slot-scope="scope">
  97. <el-input-number :disabled="forbidden=='true'?true:(scope.$index + 1 <= form.action - 1)"
  98. v-model="scope.row.durationHours" size="mini" :min="0"
  99. :step="1"></el-input-number>
  100. </template>
  101. </el-table-column>
  102. <el-table-column prop="remark" label="备注" width="250">
  103. <template slot-scope="scope">
  104. <el-input :disabled="forbidden=='true'?true:(scope.$index + 1 <= form.action - 1)" height="70"
  105. type="textarea" v-model="scope.row.remark" size="mini"></el-input>
  106. </template>
  107. </el-table-column>
  108. <!-- <el-table-column prop="requiredFieldsValue" label="必填项设置" width="120">
  109. <template slot-scope="scope">
  110. <el-checkbox-group v-model="scope.row.requiredFieldsValue"
  111. @change="handleCheckedCitiesChange">
  112. <div v-for="requiredFieldsItem in requiredFieldsItems">
  113. <el-checkbox :label="requiredFieldsItem.id"
  114. :key="requiredFieldsItem.id">{{
  115. requiredFieldsItem.name
  116. }}
  117. </el-checkbox>
  118. </div>
  119. </el-checkbox-group>
  120. </template>
  121. </el-table-column> -->
  122. <el-table-column label="操作" width="120">
  123. <template slot-scope="scope">
  124. <div v-if="forbidden=='true'?false:!(scope.$index + 1 <= form.action - 1)">
  125. <el-button class="czbtn" size="mini" type="primary"
  126. @click="insertTaskAbove(scope.$index)">插入行↑</el-button>
  127. <br />
  128. <!-- 删除图标加在文字后方 -->
  129. <el-button class="czbtn" style="margin: 10px 0;" size="mini" type="danger"
  130. @click="deleteTask(scope.$index)">删除
  131. <i class="el-icon-delete"></i></el-button>
  132. <br />
  133. <el-button class="czbtn" size="mini" type="primary"
  134. @click="insertTaskBelow(scope.$index)">插入行↓</el-button>
  135. </div>
  136. </template>
  137. </el-table-column>
  138. </el-table>
  139. <div style="margin-top: 10px;text-align: center;">
  140. <el-button :disabled="forbidden=='true'?true:false" size="small" type="primary" @click="addTask">新增任务</el-button>
  141. </div>
  142. </el-collapse-item>
  143. <el-collapse-item title="临时额外任务" name="2">
  144. <el-table :data="extraTasks" style="width: 100%" border>
  145. <el-table-column type="index" label="序号" width="80"></el-table-column>
  146. <el-table-column prop="name" label="单项任务名称" width="250">
  147. <template slot-scope="scope">
  148. <el-input :disabled="forbidden=='true'?true:false" height="70" type="textarea" v-model="scope.row.name"
  149. size="mini"></el-input>
  150. </template>
  151. </el-table-column>
  152. <el-table-column prop="priorityId" label="优先级" width="100">
  153. <template slot-scope="scope">
  154. <el-select :disabled="forbidden=='true'?true:false" v-model="scope.row.priorityId" size="mini" placeholder="请选择">
  155. <el-option v-for="item in initResp.taskLv" :key="item.id" :label="item.name"
  156. :value="item.id"></el-option>
  157. </el-select>
  158. </template>
  159. </el-table-column>
  160. <el-table-column prop="isUrgent" label="是否加急" width="100">
  161. <template slot-scope="scope">
  162. <el-switch :disabled="forbidden=='true'?true:false" v-model="scope.row.isUrgent" >
  163. </el-switch>
  164. </template>
  165. </el-table-column>
  166. <el-table-column prop="assignedUserId" label="指派给谁" width="120">
  167. <template slot-scope="scope">
  168. <el-select :disabled="forbidden=='true'?true:false" v-model="scope.row.assignedUserId" size="mini" placeholder="请选择">
  169. <el-option v-for="item in initResp.users" :key="item.id"
  170. :label="item.cnName" :value="item.id"></el-option>
  171. </el-select>
  172. </template>
  173. </el-table-column>
  174. <el-table-column prop="timeRange" label="任务时间(起止)">
  175. <template slot-scope="scope">
  176. <el-date-picker :disabled="forbidden=='true'?true:false" v-model="scope.row.timeRange" type="datetimerange"
  177. range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"
  178. size="mini" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
  179. @change="onExtraTaskTimeRangeChange(scope.$index)">
  180. </el-date-picker>
  181. </template>
  182. </el-table-column>
  183. <el-table-column prop="durationHours" label="任务默认完成小时数" width="160">
  184. <template slot-scope="scope">
  185. <el-input-number :disabled="forbidden=='true'?true:false" v-model="scope.row.durationHours" size="mini" :min="0"
  186. :step="1"></el-input-number>
  187. </template>
  188. </el-table-column>
  189. <el-table-column prop="remark" label="备注" width="250">
  190. <template slot-scope="scope">
  191. <el-input :disabled="forbidden=='true'?true:(scope.$index + 1 <= form.action - 1)" height="70"
  192. type="textarea" v-model="scope.row.remark" size="mini"></el-input>
  193. </template>
  194. </el-table-column>
  195. <el-table-column label="操作" width="120">
  196. <template slot-scope="scope">
  197. <!-- <el-button class="czbtn" size="mini" type="primary"
  198. @click="insertExtraTaskAbove(scope.$index)">插入行↑</el-button>
  199. <br /> -->
  200. <el-button v-if="forbidden=='true'?false:true" class="czbtn" style="margin: 10px 0;" size="mini" type="danger"
  201. @click="deleteExtraTask(scope.$index)">删除 <i
  202. class="el-icon-delete"></i></el-button>
  203. <br />
  204. <!-- <el-button class="czbtn" size="mini" type="primary"
  205. @click="insertExtraTaskBelow(scope.$index)">插入行↓</el-button> -->
  206. </template>
  207. </el-table-column>
  208. </el-table>
  209. <div style="margin-top: 10px;text-align: center;">
  210. <el-button :disabled="forbidden=='true'?true:false" size="small" type="primary" @click="addExtraTask">新增任务</el-button>
  211. </div>
  212. </el-collapse-item>
  213. </el-collapse>
  214. </div>
  215. <br />
  216. <div style="text-align: right;">
  217. <el-form-item>
  218. <el-button :disabled="forbidden=='true'?true:false" type="primary" @click="submitForm">提交</el-button>
  219. <el-button @click="resetForm">返回</el-button>
  220. </el-form-item>
  221. </div>
  222. </el-form>
  223. </div>
  224. </div>
  225. </template>
  226. <script>
  227. export default {
  228. data() {
  229. return {
  230. token: '',
  231. userId: '',
  232. typeId: 1453,
  233. activeNames: ['1', '2'], // 只展开主要任务
  234. mainTasks: [
  235. ],
  236. extraTasks: [
  237. ],
  238. form: {
  239. id: 0,
  240. name: '',
  241. startTime: '',
  242. groupId: '',
  243. assignedUserId: '',
  244. foreignOptionId: '',
  245. action: 1
  246. },
  247. rules: {
  248. name: [
  249. { required: true, message: '请输入工单名称', trigger: 'blur' }
  250. ],
  251. startTime: [
  252. { required: true, message: '请选择工单开始时间', trigger: 'change' }
  253. ],
  254. groupId: [
  255. { required: true, message: '请输入所属团组ID', trigger: 'blur' }
  256. ],
  257. assignedUserId: [
  258. { required: true, message: '请输入指派用户ID', trigger: 'blur' }
  259. ],
  260. foreignOptionId: [
  261. { required: true, message: '请选择外办选项ID', trigger: 'change' }
  262. ]
  263. },
  264. requiredFieldsItems: [
  265. { name: "文本描述", id: 1 },
  266. { name: "相关文件", id: 2 }
  267. ],
  268. initResp: {
  269. groupList: [],
  270. taskLv: [],
  271. foreignLv: [],
  272. users: [],
  273. },
  274. loading: true,
  275. forbidden:false,
  276. }
  277. },
  278. mounted() {
  279. this.token = JSON.parse(localStorage.getItem('userinif')).token;
  280. this.userId = JSON.parse(localStorage.getItem('userinif')).userInfo.userId;
  281. //获取$router中的query
  282. this.form.id = this.$route.query.id;
  283. this.forbidden= this.$route.query.view;
  284. console.log(this.forbidden);
  285. console.log(this.forbidden=='true');
  286. if (this.$route.query.edit) {
  287. this.getDetail();
  288. } else {
  289. this.init();
  290. }
  291. },
  292. methods: {
  293. // 计算两个时间之间的小时数
  294. calculateHours(startTime, endTime) {
  295. if (!startTime || !endTime) return 0;
  296. const start = new Date(startTime);
  297. const end = new Date(endTime);
  298. // 计算时间差(毫秒)
  299. const diff = end - start;
  300. // 转换为小时数
  301. const hours = diff / (1000 * 60 * 60);
  302. // 保留一位小数
  303. return Math.round(hours * 10) / 10;
  304. },
  305. // 当时间范围改变时更新默认小时数
  306. onTimeRangeChange(index) {
  307. const task = this.mainTasks[index];
  308. if (task.timeRange && task.timeRange.length === 2) {
  309. task.durationHours = this.calcWorkHoursExact(task.timeRange[0], task.timeRange[1]);
  310. } else {
  311. task.durationHours = 0;
  312. }
  313. },
  314. addTask() {
  315. this.mainTasks.push({
  316. "id": 0,
  317. "name": "",
  318. "priorityId": 1455,
  319. "isUrgent": false,
  320. "assignedUserId": this.form.assignedUserId || '',
  321. "durationHours": 0,
  322. "workOrderId": 0,
  323. "sort": this.mainTasks.length + 1,
  324. "timeRange": [],
  325. "requiredFieldsValue": [],
  326. "isExtraTask": false,
  327. "remark": ""
  328. });
  329. },
  330. insertTaskAbove(index) {
  331. // 在指定位置上方插入新行
  332. this.mainTasks.splice(index, 0, {
  333. "id": 0,
  334. "name": "",
  335. "priorityId": 1455,
  336. "isUrgent": false,
  337. "assignedUserId": this.form.assignedUserId || '',
  338. "durationHours": 0,
  339. "workOrderId": 0,
  340. "sort": this.mainTasks.length + 1,
  341. "timeRange": [],
  342. "requiredFieldsValue": [],
  343. "isExtraTask": false,
  344. "remark": ""
  345. });
  346. },
  347. insertTaskBelow(index) {
  348. // 在指定位置下方插入新行
  349. this.mainTasks.splice(index + 1, 0, {
  350. "id": 0,
  351. "name": "",
  352. "priorityId": 1455,
  353. "isUrgent": false,
  354. "assignedUserId": this.form.assignedUserId || '',
  355. "durationHours": 0,
  356. "workOrderId": 0,
  357. "sort": this.mainTasks.length + 1,
  358. "timeRange": [],
  359. "requiredFieldsValue": [],
  360. "isExtraTask": false,
  361. "remark": ""
  362. });
  363. },
  364. deleteTask(index) {
  365. this.mainTasks.splice(index, 1);
  366. },
  367. submitForm() {
  368. this.$refs.form.validate((valid) => {
  369. if (valid) {
  370. this.save();
  371. } else {
  372. // 表单验证失败
  373. this.$message({
  374. message: '请检查填写内容',
  375. type: 'warning'
  376. });
  377. return false;
  378. }
  379. });
  380. },
  381. resetForm() {
  382. this.$refs.form.resetFields();
  383. this.$router.back();
  384. },
  385. /**
  386. * 计算两个时间之间的工作小时数
  387. * 工作时间:周一至周五,上午9:00-12:00,下午13:30-18:00
  388. * @param {string} startStr "yyyy-mm-dd HH:mm"
  389. * @param {string} endStr "yyyy-mm-dd HH:mm"
  390. * @returns {number} 工作小时数
  391. */
  392. calcWorkHoursExact(startStr, endStr) {
  393. console.log(startStr, endStr);
  394. const start = new Date(startStr);
  395. const end = new Date(endStr);
  396. if (end <= start) return 0;
  397. const workPeriods = [
  398. { start: 9 * 60, end: 12 * 60 }, // 上午 9:00-12:00
  399. { start: 13.5 * 60, end: 18 * 60 } // 下午 13:30-18:00
  400. ];
  401. let totalMinutes = 0;
  402. let current = new Date(start);
  403. while (current < end) {
  404. const day = current.getDay();
  405. if (day >= 1 && day <= 5) { // 工作日
  406. for (const period of workPeriods) {
  407. const periodStart = new Date(current);
  408. periodStart.setHours(Math.floor(period.start / 60), period.start % 60, 0, 0);
  409. const periodEnd = new Date(current);
  410. periodEnd.setHours(Math.floor(period.end / 60), period.end % 60, 0, 0);
  411. // 每天的有效区间
  412. const effectiveStart = periodStart > current ? periodStart : current;
  413. const effectiveEnd = periodEnd < end ? periodEnd : end;
  414. if (effectiveEnd > effectiveStart) {
  415. totalMinutes += (effectiveEnd - effectiveStart) / 60000;
  416. }
  417. }
  418. }
  419. // 下一天
  420. current.setDate(current.getDate() + 1);
  421. current.setHours(0, 0, 0, 0);
  422. }
  423. return (totalMinutes / 60).toFixed(2);
  424. },
  425. init() {
  426. this.$axios({
  427. method: 'post',
  428. url: '/api/Task/TaskInit',
  429. data: {
  430. typeId: 1453,
  431. }
  432. }).then(response => {
  433. // 处理响应数据
  434. if (response.data.code == 200) {
  435. this.initResp = response.data.data;
  436. var maintasks = response.data.data.defaultTask;
  437. maintasks.forEach(item => {
  438. item.timeRange = [item.startTime, item.endTime];
  439. item.requiredFieldsValue = [];
  440. })
  441. this.mainTasks = maintasks;
  442. this.form.startTime = response.data.data.startTime;
  443. console.log(this.mainTasks);
  444. } else {
  445. this.$message({
  446. message: response.data.msg,
  447. type: 'warning'
  448. });
  449. }
  450. }).catch(error => {
  451. // 处理错误
  452. console.error(error);
  453. }).finally(() => {
  454. this.loading = false;
  455. });
  456. },
  457. handleCheckedCitiesChange(val) {
  458. console.log(val);
  459. },
  460. save() {
  461. var tasks = this.mainTasks;
  462. var i = 1;
  463. for (let j = 0; j < tasks.length; j++) {
  464. const item = tasks[j];
  465. item.startTime = item.timeRange[0];
  466. item.endTime = item.timeRange[1];
  467. item.sort = i;
  468. i = i + 1;
  469. if (!item.name) {
  470. this.$message({
  471. message: '请填写主要任务名称',
  472. type: 'warning'
  473. });
  474. return false;
  475. }
  476. if (!item.assignedUserId) {
  477. this.$message({
  478. message: '请选择主要任务负责人',
  479. type: 'warning'
  480. });
  481. return false;
  482. }
  483. if (!item.timeRange[0] || !item.timeRange[1]) {
  484. this.$message({
  485. message: '请选择主要任务时间',
  486. type: 'warning'
  487. });
  488. return false;
  489. }
  490. }
  491. i = 1;
  492. // 处理额外任务
  493. var extraTasks = this.extraTasks;
  494. for (let j = 0; j < extraTasks.length; j++) {
  495. const item = extraTasks[j];
  496. item.startTime = item.timeRange[0];
  497. item.endTime = item.timeRange[1];
  498. item.sort = i;
  499. i = i + 1;
  500. if (!item.name) {
  501. this.$message({
  502. message: '请填写额外任务名称',
  503. type: 'warning'
  504. });
  505. return false;
  506. }
  507. if (!item.assignedUserId) {
  508. this.$message({
  509. message: '请选择额外任务负责人',
  510. type: 'warning'
  511. });
  512. return false;
  513. }
  514. if (!item.timeRange[0] || !item.timeRange[1]) {
  515. this.$message({
  516. message: '请选择额外任务时间',
  517. type: 'warning'
  518. });
  519. return false;
  520. }
  521. }
  522. var form = this.form;
  523. form.createUserId = this.userId;
  524. form.typeId = this.typeId;
  525. form.tasks = tasks.concat(extraTasks);
  526. this.$axios({
  527. method: 'post',
  528. url: '/api/Task/TaskOperation',
  529. data: form
  530. }).then(response => {
  531. // 处理响应数据
  532. if (response.data.code == 200) {
  533. this.$message({
  534. message: '保存成功',
  535. type: 'success'
  536. });
  537. this.$router.back();
  538. } else {
  539. this.$message({
  540. message: response.data.msg,
  541. type: 'warning'
  542. });
  543. }
  544. }).catch(error => {
  545. // 处理错误
  546. console.error(error);
  547. });
  548. },
  549. userChange() {
  550. this.mainTasks.forEach(item => {
  551. item.assignedUserId = this.form.assignedUserId;
  552. })
  553. this.extraTasks.forEach(item => {
  554. item.assignedUserId = this.form.assignedUserId;
  555. })
  556. },
  557. getDetail() {
  558. this.$axios({
  559. method: 'post',
  560. url: '/api/Task/TaskDetail',
  561. data: {
  562. id: this.form.id
  563. }
  564. }).then(response => {
  565. // 处理响应数据
  566. if (response.data.code == 200) {
  567. this.initResp = response.data.data;
  568. var maintasks = response.data.data.mainTask;
  569. maintasks.forEach(item => {
  570. item.timeRange = [item.startTime, item.endTime];
  571. item.requiredFieldsValue = [];
  572. })
  573. this.mainTasks = maintasks;
  574. var extraTasks = response.data.data.extraTask;
  575. extraTasks.forEach(item => {
  576. item.timeRange = [item.startTime, item.endTime];
  577. item.requiredFieldsValue = [];
  578. })
  579. this.extraTasks = extraTasks;
  580. this.form = response.data.data.workOrder;
  581. } else {
  582. this.$message({
  583. message: response.data.msg,
  584. type: 'warning'
  585. });
  586. }
  587. }).catch(error => {
  588. // 处理错误
  589. console.error(error);
  590. }).finally(() => {
  591. this.loading = false;
  592. });
  593. },
  594. // 在这里添加额外任务函数
  595. addExtraTask() {
  596. this.extraTasks.push({
  597. "id": 0,
  598. "name": "",
  599. "priorityId": 1455,
  600. "isUrgent": false,
  601. "assignedUserId": this.form.assignedUserId || '',
  602. "durationHours": 0,
  603. "workOrderId": 0,
  604. "sort": this.extraTasks.length + 1,
  605. "timeRange": [],
  606. "requiredFieldsValue": [],
  607. "isExtraTask": true,
  608. "remark": ""
  609. });
  610. },
  611. insertExtraTaskAbove(index) {
  612. // 在指定位置上方插入新行
  613. this.extraTasks.splice(index, 0, {
  614. "id": 0,
  615. "name": "",
  616. "priorityId": 1455,
  617. "isUrgent": false,
  618. "assignedUserId": this.form.assignedUserId || '',
  619. "durationHours": 0,
  620. "workOrderId": 0,
  621. "sort": this.extraTasks.length + 1,
  622. "timeRange": [],
  623. "requiredFieldsValue": [],
  624. "isExtraTask": true,
  625. "remark": ""
  626. });
  627. },
  628. insertExtraTaskBelow(index) {
  629. // 在指定位置下方插入新行
  630. this.extraTasks.splice(index + 1, 0, {
  631. "id": 0,
  632. "name": "",
  633. "priorityId": 1455,
  634. "isUrgent": false,
  635. "assignedUserId": this.form.assignedUserId || '',
  636. "durationHours": 0,
  637. "workOrderId": 0,
  638. "sort": this.extraTasks.length + 1,
  639. "timeRange": [],
  640. "requiredFieldsValue": [],
  641. "isExtraTask": true,
  642. "remark": ""
  643. });
  644. },
  645. deleteExtraTask(index) {
  646. this.extraTasks.splice(index, 1);
  647. },
  648. // 为额外任务添加时间范围变化处理方法
  649. onExtraTaskTimeRangeChange(index) {
  650. const task = this.extraTasks[index];
  651. if (task.timeRange && task.timeRange.length === 2) {
  652. task.durationHours = this.calcWorkHoursExact(task.timeRange[0], task.timeRange[1]);
  653. } else {
  654. task.durationHours = 0;
  655. }
  656. }
  657. }
  658. }
  659. </script>
  660. <style scoped>
  661. .form_center {
  662. max-width: 100%;
  663. /* 限制最大宽度 */
  664. width: 100%;
  665. margin: 20px auto;
  666. padding: 20px;
  667. box-sizing: border-box;
  668. }
  669. </style>