OverallPlan.vue 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503
  1. <template>
  2. <GlobalLayout title="试验任务参数调整">
  3. <template #header-controls>
  4. <el-button icon="el-icon-close" @click="close">关闭</el-button>
  5. <el-button type="success" icon="el-icon-download">暂存</el-button>
  6. <el-button type="primary" icon="el-icon-plus" @click="submitForm">保存</el-button>
  7. </template>
  8. <div class="main-container">
  9. <div class="left-section">
  10. <!-- 任务配置区 -->
  11. <div class="task-editor-section">
  12. <!-- <h3 class="section-title dark-title">干扰方案配置</h3>-->
  13. <el-card class="editor-card dark-card" shadow="hover">
  14. <div class="editor-content">
  15. <el-form
  16. ref="measurementForm"
  17. :model="measurementData"
  18. :rules="formRules"
  19. class="dark-form"
  20. label-width="150px"
  21. >
  22. <h4 class="form-section-title">任务基本信息</h4>
  23. <el-form-item label="干扰保障方案名称" prop="schemeName">
  24. <el-input
  25. v-model="measurementData.schemeName"
  26. placeholder="请输入测量保障方案名称"
  27. clearable
  28. disabled
  29. />
  30. </el-form-item>
  31. <el-form-item label="任务名称" prop="taskName">
  32. <el-input
  33. v-model="measurementData.taskName"
  34. placeholder="请输入任务名称"
  35. clearable
  36. disabled
  37. />
  38. </el-form-item>
  39. <el-form-item label="任务代号" prop="taskCode">
  40. <el-input
  41. v-model="measurementData.taskCode"
  42. placeholder="请输入任务代号"
  43. clearable
  44. disabled
  45. />
  46. </el-form-item>
  47. <el-form-item label="任务开始时间" prop="startTime">
  48. <el-date-picker
  49. v-model="measurementData.startTime"
  50. type="datetime"
  51. placeholder="选择开始时间"
  52. style="width: 100%"
  53. value-format="yyyy-MM-dd HH:mm:ss"
  54. disabled
  55. />
  56. </el-form-item>
  57. <el-form-item label="任务结束时间" prop="endTime">
  58. <el-date-picker
  59. v-model="measurementData.endTime"
  60. type="datetime"
  61. placeholder="选择结束时间"
  62. style="width: 100%"
  63. value-format="yyyy-MM-dd HH:mm:ss"
  64. disabled
  65. />
  66. </el-form-item>
  67. <el-form-item label="干扰方案编制状态" prop="status">
  68. <el-select
  69. v-model="measurementData.status"
  70. placeholder="请选择状态"
  71. style="width: 100%"
  72. disabled
  73. >
  74. <el-option label="进行中" value="进行中" />
  75. <el-option label="未开始" value="未开始" />
  76. <el-option label="已完成" value="已完成" />
  77. </el-select>
  78. </el-form-item>
  79. <el-form-item label="秘级" prop="securityLevel">
  80. <el-select
  81. v-model="measurementData.securityLevel"
  82. placeholder="请选择秘级"
  83. style="width: 100%"
  84. disabled
  85. >
  86. <el-option label="绝密" value="绝密" />
  87. <el-option label="机密" value="机密" />
  88. <el-option label="秘密" value="秘密" />
  89. <el-option label="内部" value="内部" />
  90. <el-option label="公开" value="公开" />
  91. </el-select>
  92. </el-form-item>
  93. <el-form-item label="秘级年限" prop="securityYears">
  94. <el-input-number
  95. v-model="measurementData.securityYears"
  96. :min="1"
  97. :max="30"
  98. controls-position="right"
  99. style="width: 100%"
  100. disabled
  101. />
  102. </el-form-item>
  103. <el-form-item label="任务依据" prop="taskBasis">
  104. <el-input
  105. v-model="measurementData.taskBasis"
  106. type="textarea"
  107. :rows="3"
  108. placeholder="请输入任务依据"
  109. disabled
  110. />
  111. </el-form-item>
  112. <el-form-item label="任务要求" prop="taskRequirements">
  113. <el-input
  114. v-model="measurementData.taskRequirements"
  115. type="textarea"
  116. :rows="3"
  117. placeholder="请输入任务要求"
  118. disabled
  119. />
  120. </el-form-item>
  121. <el-form-item label="蓝方干扰要求" prop="blueSideRequirements">
  122. <el-input
  123. v-model="measurementData.blueSideRequirements"
  124. type="textarea"
  125. :rows="3"
  126. placeholder="请输入蓝方干扰要求"
  127. disabled
  128. />
  129. </el-form-item>
  130. </el-form>
  131. </div>
  132. <!--方案配置区-->
  133. <el-tabs v-model="activeTab">
  134. <el-tab-pane v-if="currentRole === 'int'" label="干扰方案配置" name="interference">
  135. </el-tab-pane>
  136. <el-tab-pane v-if="currentRole === 'mea'" label="测量方案配置" name="meas">
  137. </el-tab-pane>
  138. <el-tab-pane v-if="currentRole === 'targ'" label="靶标方案配置" name="target">
  139. </el-tab-pane>
  140. </el-tabs>
  141. <!--干扰-->
  142. <div v-if="currentRole === 'int'">
  143. <!-- 干扰装备配置区域 -->
  144. <div class="card-config-section">
  145. <div class="section-header">
  146. <h3>导弹一干扰装备保障配置</h3>
  147. <el-button
  148. type="primary"
  149. size="small"
  150. @click="handleAddEquipment('missile2')"
  151. >
  152. 添加保障配置目标
  153. </el-button>
  154. </div>
  155. <div class="equipment-grid">
  156. <MeasEquipmentConfig
  157. v-for="(item, index) in interferenceConfigList"
  158. :key="item.id"
  159. :equipment="item"
  160. :unit-options="unitOptions"
  161. @update="handleUpdateEquipment"
  162. @delete="handleDeleteEquipment"
  163. class="equipment-card-item"
  164. />
  165. </div>
  166. </div>
  167. <div class="card-config-section">
  168. <div class="section-header">
  169. <h3>导弹二干扰装备保障配置</h3>
  170. <el-button
  171. type="primary"
  172. size="small"
  173. @click="handleAddEquipment('missile2')"
  174. >
  175. 添加保障配置目标
  176. </el-button>
  177. </div>
  178. <div class="equipment-grid">
  179. <MeasEquipmentConfig
  180. v-for="(item, index) in interferenceConfigList"
  181. :key="item.id"
  182. :equipment="item"
  183. :unit-options="unitOptions"
  184. @update="handleUpdateEquipment"
  185. @delete="handleDeleteEquipment"
  186. class="equipment-card-item"
  187. />
  188. </div>
  189. </div>
  190. <div class="card-config-section">
  191. <div class="section-header">
  192. <h3>导弹三干扰装备保障配置</h3>
  193. <el-button
  194. type="primary"
  195. size="small"
  196. @click="handleAddEquipment('missile2')"
  197. >
  198. 添加保障配置目标
  199. </el-button>
  200. </div>
  201. <div class="equipment-grid">
  202. <MeasEquipmentConfig
  203. v-for="(item, index) in interferenceConfigList"
  204. :key="item.id"
  205. :equipment="item"
  206. :unit-options="unitOptions"
  207. @update="handleUpdateEquipment"
  208. @delete="handleDeleteEquipment"
  209. class="equipment-card-item"
  210. />
  211. </div>
  212. </div>
  213. </div>
  214. <!--测量-->
  215. <div v-if="currentRole === 'meas'">
  216. <div class="card-config-section">
  217. <div class="section-header">
  218. <h3>导弹一测量装备保障配置</h3>
  219. <el-button
  220. type="primary"
  221. size="small"
  222. @click="handleAddEquipment('missile2')"
  223. >
  224. 添加保障配置目标
  225. </el-button>
  226. </div>
  227. <div class="equipment-grid">
  228. <MeasEquipmentConfig
  229. v-for="(item, index) in MeasEquipmentConfigList"
  230. :key="item.id"
  231. :equipment="item"
  232. :unit-options="unitOptions"
  233. @update="handleUpdateEquipment"
  234. @delete="handleDeleteEquipment"
  235. class="equipment-card-item"
  236. />
  237. </div>
  238. </div>
  239. <div class="card-config-section">
  240. <div class="section-header">
  241. <h3>导弹二测量装备保障配置</h3>
  242. <el-button
  243. type="primary"
  244. size="small"
  245. @click="handleAddEquipment('missile2')"
  246. >
  247. 添加保障配置目标
  248. </el-button>
  249. </div>
  250. <div class="equipment-grid">
  251. <MeasEquipmentConfig
  252. v-for="(item, index) in MeasEquipmentConfigList"
  253. :key="item.id"
  254. :equipment="item"
  255. :unit-options="unitOptions"
  256. @update="handleUpdateEquipment"
  257. @delete="handleDeleteEquipment"
  258. class="equipment-card-item"
  259. />
  260. </div>
  261. </div>
  262. <div class="card-config-section">
  263. <div class="section-header">
  264. <h3>导弹三测量装备保障配置</h3>
  265. <el-button
  266. type="primary"
  267. size="small"
  268. @click="handleAddEquipment('missile2')"
  269. >
  270. 添加保障配置目标
  271. </el-button>
  272. </div>
  273. <div class="equipment-grid">
  274. <MeasEquipmentConfig
  275. v-for="(item, index) in MeasEquipmentConfigList"
  276. :key="item.id"
  277. :equipment="item"
  278. :unit-options="unitOptions"
  279. @update="handleUpdateEquipment"
  280. @delete="handleDeleteEquipment"
  281. class="equipment-card-item"
  282. />
  283. </div>
  284. </div>
  285. </div>
  286. <!--靶标-->
  287. <div v-if="currentRole === 'targ'">
  288. <div class="card-config-section">
  289. <div class="section-header">
  290. <h3>导弹一靶标装备保障配置</h3>
  291. <el-button
  292. type="primary"
  293. size="small"
  294. @click="handleAddEquipment('missile2')"
  295. >
  296. 添加保障配置目标
  297. </el-button>
  298. </div>
  299. <div class="equipment-grid">
  300. <TargetConfig
  301. v-for="(item, index) in attackedTargetList"
  302. :key="item.id"
  303. :target="item"
  304. :unit-options="unitOptions"
  305. @update="handleUpdateEquipment"
  306. @delete="handleDeleteEquipment"
  307. class="equipment-card-item"
  308. />
  309. </div>
  310. </div>
  311. <div class="card-config-section">
  312. <div class="section-header">
  313. <h3>导弹三靶标装备保障配置</h3>
  314. <el-button
  315. type="primary"
  316. size="small"
  317. @click="handleAddEquipment('missile1')"
  318. >
  319. 添加保障配置目标
  320. </el-button>
  321. </div>
  322. <div class="equipment-grid">
  323. <TargetConfig
  324. v-for="(item, index) in attackedTargetList"
  325. :key="item.id"
  326. :target="item"
  327. :unit-options="unitOptions"
  328. @update="handleUpdateEquipment"
  329. @delete="handleDeleteEquipment"
  330. class="equipment-card-item"
  331. />
  332. </div>
  333. </div>
  334. <div class="card-config-section">
  335. <div class="section-header">
  336. <h3>导弹二靶标装备保障配置</h3>
  337. <el-button
  338. type="primary"
  339. size="small"
  340. @click="handleAddEquipment('missile2')"
  341. >
  342. 添加保障配置目标
  343. </el-button>
  344. </div>
  345. <div class="equipment-grid">
  346. <TargetConfig
  347. v-for="(item, index) in attackedTargetList"
  348. :key="item.id"
  349. :target="item"
  350. :unit-options="unitOptions"
  351. @update="handleUpdateEquipment"
  352. @delete="handleDeleteEquipment"
  353. class="equipment-card-item"
  354. />
  355. </div>
  356. </div>
  357. </div>
  358. </el-card>
  359. </div>
  360. </div>
  361. <!-- 时序列表和时间线区域 -->
  362. <div class="right-section">
  363. <h3 class="section-title dark-title">干扰装置时序运行表</h3>
  364. <el-card class="dark-card time-sequence-card">
  365. <div class="time-sequence-header">
  366. <el-button type="primary" size="small" @click="showAddTimeSequenceDialog()">
  367. <i class="el-icon-plus"></i> 添加时序记录
  368. </el-button>
  369. </div>
  370. <!-- 时序表格 -->
  371. <el-table
  372. :data="sortedTimeSequenceList"
  373. border
  374. style="width: 100%; margin-top: 10px;"
  375. :header-cell-style="{background: '#2d3a4b', color: '#e0e6ed', borderColor: '#425163'}"
  376. :row-style="{background: '#1f2a38', color: '#e0e6ed', borderColor: '#425163'}"
  377. >
  378. <el-table-column
  379. prop="timePoint"
  380. label="时间点"
  381. width="120"
  382. >
  383. <template slot-scope="scope">
  384. <span v-if="!scope.row.editing">{{ scope.row.timePoint }}</span>
  385. <el-input
  386. v-if="scope.row.editing"
  387. v-model="scope.row.timePoint"
  388. size="small"
  389. placeholder="如T0-30分钟"
  390. ></el-input>
  391. </template>
  392. </el-table-column>
  393. <el-table-column
  394. prop="equipmentName"
  395. label="设备名称"
  396. width="150"
  397. >
  398. <template slot-scope="scope">
  399. <span v-if="!scope.row.editing">{{ scope.row.equipmentName }}</span>
  400. <el-select
  401. v-if="scope.row.editing"
  402. v-model="scope.row.equipmentId"
  403. size="small"
  404. placeholder="选择设备"
  405. >
  406. <el-option
  407. v-for="equip in allEquipmentList"
  408. :key="equip.id"
  409. :label="equip.equipmentName"
  410. :value="equip.id"
  411. ></el-option>
  412. </el-select>
  413. </template>
  414. </el-table-column>
  415. <el-table-column
  416. prop="operation"
  417. label="操作内容"
  418. >
  419. <template slot-scope="scope">
  420. <span v-if="!scope.row.editing">{{ scope.row.operation }}</span>
  421. <el-input
  422. v-if="scope.row.editing"
  423. v-model="scope.row.operation"
  424. size="small"
  425. placeholder="输入操作内容"
  426. ></el-input>
  427. </template>
  428. </el-table-column>
  429. <el-table-column
  430. label="操作"
  431. >
  432. <template slot-scope="scope">
  433. <el-button
  434. v-if="!scope.row.editing"
  435. size="mini"
  436. type="text"
  437. @click="handleEditTimeSequence(scope.$index, scope.row)"
  438. >编辑</el-button>
  439. <el-button
  440. v-if="scope.row.editing"
  441. size="mini"
  442. type="text"
  443. @click="handleSaveTimeSequence(scope.$index, scope.row)"
  444. >保存</el-button>
  445. <el-button
  446. size="mini"
  447. type="text"
  448. @click="handleDeleteTimeSequence(scope.row.id)"
  449. >删除</el-button>
  450. </template>
  451. </el-table-column>
  452. </el-table>
  453. <!-- 时间线展示 -->
  454. <div class="timeline-container">
  455. <h4 class="timeline-title">时序时间线</h4>
  456. <el-timeline>
  457. <el-timeline-item
  458. v-for="(item, index) in sortedTimeSequenceList"
  459. :key="item.id"
  460. :timestamp="item.timePoint"
  461. :icon="getTimelineIcon(item.status)"
  462. :type="getStatusTagType(item.status)"
  463. placement="top"
  464. >
  465. <div class="timeline-content-title">{{ item.equipmentName }}</div>
  466. <div class="timeline-content-desc">{{ item.operation }}</div>
  467. </el-timeline-item>
  468. </el-timeline>
  469. </div>
  470. </el-card>
  471. </div>
  472. </div>
  473. <!-- 添加时序记录对话框 -->
  474. <el-dialog
  475. title="添加时序记录"
  476. :visible.sync="addTimeSequenceVisible"
  477. width="500px"
  478. >
  479. <el-form
  480. :model="newTimeSequence"
  481. ref="timeSequenceForm"
  482. label-width="100px"
  483. class="dark-form"
  484. >
  485. <el-form-item label="时间点" prop="timePoint">
  486. <el-input
  487. v-model="newTimeSequence.timePoint"
  488. placeholder="如T0-30分钟"
  489. ></el-input>
  490. </el-form-item>
  491. <el-form-item label="设备名称" prop="equipmentId">
  492. <el-select
  493. v-model="newTimeSequence.equipmentId"
  494. placeholder="选择设备"
  495. >
  496. <el-option
  497. v-for="equip in allEquipmentList"
  498. :key="equip.id"
  499. :label="equip.equipmentName"
  500. :value="equip.id"
  501. ></el-option>
  502. </el-select>
  503. </el-form-item>
  504. <el-form-item label="操作内容" prop="operation">
  505. <el-input
  506. v-model="newTimeSequence.operation"
  507. type="textarea"
  508. :rows="3"
  509. placeholder="输入操作内容"
  510. ></el-input>
  511. </el-form-item>
  512. </el-form>
  513. <div slot="footer" class="dialog-footer">
  514. <el-button @click="addTimeSequenceVisible = false">取消</el-button>
  515. <el-button type="primary" @click="saveNewTimeSequence">确定</el-button>
  516. </div>
  517. </el-dialog>
  518. </GlobalLayout>
  519. </template>
  520. <script>
  521. import E from 'wangeditor'
  522. import GlobalLayout from '@/components/Components/GlobalLayout.vue'
  523. import InterferenceEquipmentConfig from '@/views/command/taskEdit/components/InterferenceEquipmentConfig.vue'
  524. export default {
  525. components: { GlobalLayout, InterferenceEquipmentConfig },
  526. data() {
  527. // 校验结束时间必须大于开始时间
  528. const validateEndTime = (rule, value, callback) => {
  529. if (!value) {
  530. callback(new Error('请选择结束时间'))
  531. } else if (new Date(value) <= new Date(this.measurementData.startTime)) {
  532. callback(new Error('结束时间必须大于开始时间'))
  533. } else {
  534. callback()
  535. }
  536. }
  537. return {
  538. currentRole:'',
  539. activeTab:this.currentRole,
  540. editor: null,
  541. adjustmentContent: '',
  542. measurementData: {
  543. schemeName: '2023年度东海靶场导弹干扰保障方案',
  544. taskName: '东风-17导弹飞行轨迹干扰任务',
  545. taskCode: 'DF17-2023-001',
  546. startTime: '2023-06-15 08:00:00',
  547. endTime: '2023-06-15 18:00:00',
  548. status: '进行中',
  549. securityLevel: '机密',
  550. securityYears: 10,
  551. taskBasis: '根据《XXXXX试验计划》和《XXXX靶场干扰保障要求》开展本次干扰任务',
  552. taskRequirements: '1. 全程跟踪dd飞行轨迹\n2. 记录关键节点数据\n3. 确保干扰精度误差不超过0.5%\n4. 实时传输干扰数据至指挥中心',
  553. blueSideRequirements: '1. 提供dd发射前30分钟预警\n2. 确保干扰设备不受电子干扰\n3. 提供靶场安全区域坐标\n4. 配合完成干扰数据校验'
  554. },
  555. // 分导弹类型存储装备列表
  556. missile1EquipmentList: [
  557. {
  558. id: "missile1-equip-001",
  559. objective: "测试目标001",
  560. equipmentName: "角反装置",
  561. longitude: "116.404",
  562. latitude: "39.915",
  563. mission: "20KM",
  564. altitude: "T0+15分钟",
  565. secretLevel: "秘密",
  566. status: "有效",
  567. launchPosition: "发射架位1",
  568. task: "使用角反装置干扰目标",
  569. isEditing: false
  570. }
  571. ],
  572. missile2EquipmentList: [
  573. {
  574. id: "missile2-equip-001",
  575. objective: "边境监测任务",
  576. equipmentName: "发烟罐",
  577. longitude: "121.473",
  578. latitude: "31.230",
  579. mission: "20KM",
  580. altitude: "T0+15分钟",
  581. secretLevel: "机密",
  582. status: "待审核",
  583. launchPosition: "发射架位1",
  584. task: "使用发烟罐干扰目标",
  585. isEditing: false
  586. }
  587. ],
  588. missile3EquipmentList: [
  589. {
  590. id: "missile3-equip-001",
  591. objective: "海上巡逻监测",
  592. equipmentName: "箔条干扰装置",
  593. longitude: "122.058",
  594. latitude: "37.496",
  595. mission: "20KM",
  596. altitude: "T0+15分钟",
  597. secretLevel: "绝密",
  598. status: "有效",
  599. launchPosition: "发射架位1",
  600. task: "使用箔条干扰装置干扰信号",
  601. isEditing: false
  602. }
  603. ],
  604. //干扰
  605. interferenceConfigList: [
  606. {
  607. id: "equip-001",
  608. objective: "测试目标001", // 目标
  609. equipmentName: "角反装置", // 装备名称
  610. longitude: "116.404", // 经度
  611. latitude: "39.915", // 纬度
  612. mission: "20KM", // 任务
  613. altitude: "T0+15分钟", // 离地高度(米)
  614. secretLevel: "秘密",
  615. status: "有效",
  616. launchPosition:"发射架位1",
  617. task:"使用角反装置干扰目标"
  618. },
  619. {
  620. id: "equip-002",
  621. objective: "边境监测任务", // 目标
  622. equipmentName: "发烟罐", // 装备名称
  623. longitude: "121.473", // 经度
  624. latitude: "31.230", // 纬度
  625. mission: "20KM", // 任务
  626. altitude: "T0+15分钟", // 离地高度(米)
  627. secretLevel: "机密",
  628. status: "待审核",
  629. launchPosition:"发射架位1",
  630. task:"使用发烟罐干扰目标"
  631. },
  632. {
  633. id: "equip-003",
  634. objective: "海上巡逻监测", // 目标
  635. equipmentName: "箔条干扰装置", // 装备名称
  636. longitude: "122.058", // 经度
  637. latitude: "37.496", // 纬度
  638. mission: "20KM", // 任务
  639. altitude: "T0+15分钟", // 离地高度(米)
  640. secretLevel: "绝密",
  641. status: "有效",
  642. launchPosition:"发射架位1",
  643. task:"使用箔条干扰装置干扰信号"
  644. }
  645. ],
  646. //靶标
  647. attackedTargetList: [
  648. {
  649. id: "target-001",
  650. targetName: "海上移动靶标-A1",
  651. longitude: "122.058",
  652. latitude: "37.496",
  653. mission: "用于海上移动目标射击训练\n1. 每日检查靶标状态\n2. 实时监控靶标位置",
  654. secretLevel: "秘密",
  655. status: "有效"
  656. },
  657. {
  658. id: "target-002",
  659. targetName: "固定靶标-北区",
  660. longitude: "116.404",
  661. latitude: "39.915",
  662. mission: "基础射击训练使用\n1. 每周检查靶标状态\n2. 设置安全警戒区",
  663. secretLevel: "机密",
  664. status: "待审核"
  665. },
  666. {
  667. id: "target-003",
  668. targetName: "电子模拟靶场系统",
  669. longitude: "121.473",
  670. latitude: "31.230",
  671. mission: "提供全天候电子靶标训练\n1. 定期系统维护\n2. 备用电源保障",
  672. secretLevel: "秘密",
  673. status: "有效"
  674. }
  675. ],
  676. //测量
  677. MeasEquipmentConfigList: [
  678. {
  679. id: "equip-001",
  680. objective: "测试目标001", // 目标
  681. equipmentName: "雷达探测仪-X1", // 装备名称
  682. longitude: "116.404", // 经度
  683. latitude: "39.915", // 纬度
  684. mission: "执行区域探测任务", // 任务
  685. altitude: "1500", // 离地高度(米)
  686. secretLevel: "秘密",
  687. status: "有效"
  688. },
  689. {
  690. id: "equip-002",
  691. objective: "边境监测任务", // 目标
  692. equipmentName: "红外热像仪-Pro", // 装备名称
  693. longitude: "121.473", // 经度
  694. latitude: "31.230", // 纬度
  695. mission: "24小时边境热源监测", // 任务
  696. altitude: "800", // 离地高度(米)
  697. secretLevel: "机密",
  698. status: "待审核"
  699. },
  700. {
  701. id: "equip-003",
  702. objective: "海上巡逻监测", // 目标
  703. equipmentName: "声呐探测系统-S2", // 装备名称
  704. longitude: "122.058", // 经度
  705. latitude: "37.496", // 纬度
  706. mission: "海上目标探测与追踪", // 任务
  707. altitude: "海平面下50米", // 离地高度(米)
  708. secretLevel: "绝密",
  709. status: "有效"
  710. }
  711. ],
  712. //
  713. unitOptions: [
  714. {value: "unit1", label: "第一测量队"},
  715. {value: "unit2", label: "第二测量队"},
  716. {value: "unit3", label: "第三测量队"},
  717. ],
  718. formRules: {
  719. schemeName: [
  720. {required: true, message: '请输入测量保障方案名称', trigger: 'blur'},
  721. {min: 2, max: 50, message: '长度在2到50个字符', trigger: 'blur'}
  722. ],
  723. taskName: [
  724. {required: true, message: '请输入任务名称', trigger: 'blur'},
  725. {min: 2, max: 30, message: '长度在2到30个字符', trigger: 'blur'}
  726. ],
  727. taskCode: [
  728. {required: true, message: '请输入任务代号', trigger: 'blur'}
  729. ],
  730. startTime: [
  731. {required: true, message: '请选择开始时间', trigger: 'change'}
  732. ],
  733. endTime: [
  734. {required: true, message: '请选择结束时间', trigger: 'change'},
  735. {validator: validateEndTime, trigger: 'change'}
  736. ],
  737. status: [
  738. {required: true, message: '请选择状态', trigger: 'change'}
  739. ],
  740. securityLevel: [
  741. {required: true, message: '请选择秘级', trigger: 'change'}
  742. ],
  743. securityYears: [
  744. {required: true, message: '请输入秘级年限', trigger: 'blur'},
  745. {type: 'number', min: 1, max: 30, message: '年限必须在1-30之间', trigger: 'blur'}
  746. ],
  747. taskBasis: [
  748. {required: true, message: '请输入任务依据', trigger: 'blur'}
  749. ],
  750. taskRequirements: [
  751. {required: true, message: '请输入任务要求', trigger: 'blur'}
  752. ],
  753. blueSideRequirements: [
  754. {required: true, message: '请输入蓝方干扰要求', trigger: 'blur'}
  755. ]
  756. },
  757. // 时序相关数据
  758. timeSequenceList: [
  759. {
  760. id: "time-001",
  761. timePoint: "T0-30分钟",
  762. equipmentId: "equip-001",
  763. equipmentName: "角反装置",
  764. status: "准备中",
  765. operation: "设备启动检查,确认电源供应正常",
  766. editing: false
  767. },
  768. {
  769. id: "time-002",
  770. timePoint: "T0-15分钟",
  771. equipmentId: "equip-002",
  772. equipmentName: "发烟罐",
  773. status: "运行中",
  774. operation: "开始释放烟雾,形成干扰屏障",
  775. editing: false
  776. },
  777. {
  778. id: "time-003",
  779. timePoint: "T0-5分钟",
  780. equipmentId: "equip-003",
  781. equipmentName: "箔条干扰装置",
  782. status: "待审核",
  783. operation: "部署箔条干扰弹,准备电子干扰",
  784. editing: false
  785. }
  786. ],
  787. addTimeSequenceVisible: false,
  788. newTimeSequence: {
  789. timePoint: '',
  790. equipmentId: '',
  791. operation: ''
  792. }
  793. }
  794. },
  795. computed: {
  796. sortedTimeSequenceList() {
  797. // 按时间点排序
  798. return [...this.timeSequenceList].sort((a, b) => {
  799. return a.timePoint.localeCompare(b.timePoint);
  800. });
  801. },
  802. allEquipmentList() {
  803. // 合并所有装备列表
  804. return [
  805. ...this.missile1EquipmentList,
  806. ...this.missile2EquipmentList,
  807. ...this.missile3EquipmentList
  808. ];
  809. }
  810. },
  811. methods: {
  812. // 初始化富文本编辑器
  813. initEditor() {
  814. this.editor = new E('#editor-toolbar-container', '#editor-container');
  815. // 可以根据需要配置编辑器
  816. this.editor.config.menus = [
  817. 'head', // 标题
  818. 'bold', // 粗体
  819. 'fontSize', // 字号
  820. 'fontName', // 字体
  821. 'italic', // 斜体
  822. 'underline', // 下划线
  823. 'strikeThrough', // 删除线
  824. 'foreColor', // 文字颜色
  825. 'backColor', // 背景颜色
  826. 'link', // 插入链接
  827. 'list', // 列表
  828. 'justify', // 对齐方式
  829. 'quote', // 引用
  830. 'emoticon', // 表情
  831. 'image', // 插入图片
  832. 'table', // 表格
  833. 'code', // 代码
  834. 'undo', // 撤销
  835. 'redo' // 重做
  836. ];
  837. this.editor.create();
  838. },
  839. // 关闭页面
  840. close() {
  841. this.$router.go(-1);
  842. },
  843. // 提交表单
  844. submitForm() {
  845. this.$refs.measurementForm.validate((valid) => {
  846. if (valid) {
  847. // 获取编辑器内容
  848. const content = this.editor.txt.html();
  849. // 构建提交数据
  850. const submitData = {
  851. ...this.measurementData,
  852. adjustmentContent: content,
  853. missile1EquipmentList: this.missile1EquipmentList,
  854. missile2EquipmentList: this.missile2EquipmentList,
  855. missile3EquipmentList: this.missile3EquipmentList,
  856. timeSequenceList: this.timeSequenceList
  857. };
  858. // 这里添加实际提交逻辑
  859. console.log('提交数据:', submitData);
  860. this.$message.success('保存成功');
  861. } else {
  862. this.$message.error('表单验证失败,请检查填写内容');
  863. return false;
  864. }
  865. });
  866. },
  867. // 添加装备
  868. handleAddEquipment(type) {
  869. const newId = `${type}-equip-${Date.now()}`;
  870. const newEquip = {
  871. id: newId,
  872. objective: `新目标-${newId.slice(-4)}`,
  873. equipmentName: `新干扰设备-${newId.slice(-4)}`,
  874. longitude: '',
  875. latitude: '',
  876. mission: '',
  877. altitude: '',
  878. secretLevel: '内部',
  879. status: '待审核',
  880. launchPosition: '',
  881. task: '',
  882. isEditing: true
  883. };
  884. this[`${type}EquipmentList`].push(newEquip);
  885. },
  886. // 更新装备
  887. handleUpdateEquipment(type, index, data) {
  888. this[`${type}EquipmentList`].splice(index, 1, data);
  889. },
  890. // 删除装备
  891. handleDeleteEquipment(type, id) {
  892. this[`${type}EquipmentList`] = this[`${type}EquipmentList`].filter(item => item.id !== id);
  893. this.$message.success('装备已删除');
  894. },
  895. // 显示添加时序记录对话框
  896. showAddTimeSequenceDialog() {
  897. this.addTimeSequenceVisible = true;
  898. this.newTimeSequence = {
  899. timePoint: '',
  900. equipmentId: '',
  901. status: '',
  902. operation: ''
  903. };
  904. },
  905. // 保存新的时序记录
  906. saveNewTimeSequence() {
  907. if (!this.newTimeSequence.timePoint) {
  908. this.$message.error('请输入时间点');
  909. return;
  910. }
  911. if (!this.newTimeSequence.equipmentId) {
  912. this.$message.error('请选择设备');
  913. return;
  914. }
  915. if (!this.newTimeSequence.status) {
  916. this.$message.error('请选择运行状态');
  917. return;
  918. }
  919. if (!this.newTimeSequence.operation) {
  920. this.$message.error('请输入操作内容');
  921. return;
  922. }
  923. // 查找设备名称
  924. const equip = this.allEquipmentList.find(item => item.id === this.newTimeSequence.equipmentId);
  925. this.timeSequenceList.push({
  926. id: `time-${Date.now()}`,
  927. ...this.newTimeSequence,
  928. equipmentName: equip ? equip.equipmentName : '',
  929. editing: false
  930. });
  931. this.addTimeSequenceVisible = false;
  932. this.$message.success('时序记录添加成功');
  933. },
  934. // 编辑时序记录
  935. handleEditTimeSequence(index, row) {
  936. this.$set(row, 'editing', true);
  937. },
  938. // 保存时序记录编辑
  939. handleSaveTimeSequence(index, row) {
  940. if (!row.timePoint) {
  941. this.$message.error('请输入时间点');
  942. return;
  943. }
  944. if (!row.equipmentId) {
  945. this.$message.error('请选择设备');
  946. return;
  947. }
  948. if (!row.status) {
  949. this.$message.error('请选择运行状态');
  950. return;
  951. }
  952. if (!row.operation) {
  953. this.$message.error('请输入操作内容');
  954. return;
  955. }
  956. // 更新设备名称
  957. const equip = this.allEquipmentList.find(item => item.id === row.equipmentId);
  958. if (equip) {
  959. this.$set(row, 'equipmentName', equip.equipmentName);
  960. }
  961. this.$set(row, 'editing', false);
  962. this.$message.success('时序记录已更新');
  963. },
  964. // 删除时序记录
  965. handleDeleteTimeSequence(id) {
  966. this.timeSequenceList = this.timeSequenceList.filter(item => item.id !== id);
  967. this.$message.success('时序记录已删除');
  968. },
  969. // 获取状态标签类型
  970. getStatusTagType(status) {
  971. switch(status) {
  972. case '有效':
  973. case '运行中':
  974. return 'success';
  975. case '待审核':
  976. case '准备中':
  977. return 'warning';
  978. case '已失效':
  979. case '故障':
  980. return 'danger';
  981. case '已完成':
  982. return 'info';
  983. case '未启动':
  984. return 'default';
  985. default:
  986. return 'default';
  987. }
  988. },
  989. // 获取时间线图标
  990. getTimelineIcon(status) {
  991. switch(status) {
  992. case '运行中':
  993. return 'el-icon-loading';
  994. case '已完成':
  995. return 'el-icon-check';
  996. case '故障':
  997. return 'el-icon-error';
  998. case '准备中':
  999. return 'el-icon-time';
  1000. case '未启动':
  1001. return 'el-icon-circle-close';
  1002. default:
  1003. return 'el-icon-info';
  1004. }
  1005. }
  1006. },
  1007. mounted() {
  1008. this.$nextTick(() =>{
  1009. this.currentRole = this.$route.query.planType;
  1010. this.activeTab = this.currentRole;
  1011. console.log("是否显示编辑按钮:", this.currentRole)
  1012. })
  1013. // 初始化编辑器
  1014. this.initEditor();
  1015. },
  1016. beforeDestroy() {
  1017. // 销毁编辑器
  1018. if (this.editor) {
  1019. this.editor.destroy();
  1020. }
  1021. }
  1022. }
  1023. </script>
  1024. <style scoped>
  1025. ::v-deep .el-tabs__item {
  1026. color: white;
  1027. }
  1028. .main-container {
  1029. display: grid;
  1030. grid-template-columns: 60% 40%;
  1031. gap: 20px;
  1032. height: calc(100vh - 120px);
  1033. padding: 20px;
  1034. box-sizing: border-box;
  1035. }
  1036. .left-section {
  1037. display: flex;
  1038. flex-direction: column;
  1039. gap: 20px;
  1040. height: 100%;
  1041. overflow-y: auto;
  1042. }
  1043. .right-section {
  1044. height: 100%;
  1045. overflow: hidden;
  1046. display: flex;
  1047. flex-direction: column;
  1048. }
  1049. .time-sequence-card {
  1050. flex: 1;
  1051. display: flex;
  1052. flex-direction: column;
  1053. overflow: hidden;
  1054. }
  1055. .time-sequence-header {
  1056. padding: 10px 15px;
  1057. border-bottom: 1px solid #425163;
  1058. }
  1059. .el-table {
  1060. flex: 0 0 40%;
  1061. overflow-y: auto;
  1062. }
  1063. ::v-deep .el-table .cell{
  1064. color: white !important;
  1065. }
  1066. /* 时间线样式 - 无卡片展示 */
  1067. .timeline-container {
  1068. flex: 1;
  1069. padding: 20px;
  1070. overflow-y: auto;
  1071. border-top: 1px solid #425163;
  1072. margin-top: 10px;
  1073. background-color: #1a2332;
  1074. }
  1075. .timeline-title {
  1076. color: #e0e6ed;
  1077. margin-bottom: 25px;
  1078. padding-bottom: 10px;
  1079. border-bottom: 1px solid #425163;
  1080. font-size: 16px;
  1081. font-weight: 500;
  1082. display: flex;
  1083. align-items: center;
  1084. }
  1085. .timeline-title::before {
  1086. content: "";
  1087. display: inline-block;
  1088. width: 4px;
  1089. height: 16px;
  1090. background-color: #409eff;
  1091. margin-right: 8px;
  1092. border-radius: 2px;
  1093. }
  1094. ::v-deep .el-timeline {
  1095. padding-left: 24px;
  1096. position: relative;
  1097. }
  1098. /* 时间线主轴线 */
  1099. ::v-deep .el-timeline::before {
  1100. content: "";
  1101. position: absolute;
  1102. top: 0;
  1103. bottom: 0;
  1104. left: 10px;
  1105. width: 2px;
  1106. background: linear-gradient(to bottom,
  1107. #425163 0%,
  1108. #409eff 50%,
  1109. #425163 100%);
  1110. }
  1111. ::v-deep .el-timeline-item {
  1112. margin-bottom: 30px;
  1113. position: relative;
  1114. padding-bottom: 10px;
  1115. }
  1116. ::v-deep .el-timeline-item:last-child {
  1117. margin-bottom: 10px;
  1118. padding-bottom: 0;
  1119. }
  1120. /* 时间点样式 */
  1121. ::v-deep .el-timeline-item__timestamp {
  1122. color: #409eff;
  1123. margin-bottom: 8px;
  1124. font-size: 14px;
  1125. font-weight: 500;
  1126. padding-left: 8px;
  1127. }
  1128. /* 时间线节点样式 */
  1129. ::v-deep .el-timeline-item__node {
  1130. width: 20px;
  1131. height: 20px;
  1132. left: -24px;
  1133. background-color: #2d3a4b;
  1134. border-color: #409eff;
  1135. border-width: 2px;
  1136. transition: all 0.3s;
  1137. }
  1138. ::v-deep .el-timeline-item:hover .el-timeline-item__node {
  1139. transform: scale(1.2);
  1140. box-shadow: 0 0 10px rgba(64, 158, 255, 0.5);
  1141. }
  1142. ::v-deep .el-timeline-item__node--success {
  1143. background-color: #00b42a;
  1144. border-color: #00b42a;
  1145. }
  1146. ::v-deep .el-timeline-item__node--warning {
  1147. background-color: #ff7d00;
  1148. border-color: #ff7d00;
  1149. }
  1150. ::v-deep .el-timeline-item__node--danger {
  1151. background-color: #f53f3f;
  1152. border-color: #f53f3f;
  1153. }
  1154. ::v-deep .el-timeline-item__node--info {
  1155. background-color: #86909c;
  1156. border-color: #86909c;
  1157. }
  1158. /* 时间线内容样式 */
  1159. ::v-deep .el-timeline-item__content {
  1160. color: #e0e6ed;
  1161. padding: 8px 12px;
  1162. border-left: 2px solid #425163;
  1163. margin-left: 10px;
  1164. transition: all 0.3s;
  1165. }
  1166. ::v-deep .el-timeline-item:hover .el-timeline-item__content {
  1167. border-left-color: #409eff;
  1168. padding-left: 16px;
  1169. }
  1170. /* 内容标题和描述样式 */
  1171. .timeline-content-title {
  1172. color: #ffffff;
  1173. font-weight: 500;
  1174. margin-bottom: 5px;
  1175. font-size: 14px;
  1176. }
  1177. .timeline-content-desc {
  1178. color: #c9cdcf;
  1179. font-size: 13px;
  1180. line-height: 1.6;
  1181. }
  1182. .status-label {
  1183. margin-top: 8px;
  1184. display: inline-block;
  1185. }
  1186. /* 添加时序记录弹窗样式优化 */
  1187. ::v-deep .el-dialog {
  1188. background-color: #2d3a4b;
  1189. border: 1px solid #425163;
  1190. border-radius: 6px;
  1191. box-shadow: 0 10px 30px -5px rgba(0, 0, 0, 0.3);
  1192. }
  1193. ::v-deep .el-dialog__header {
  1194. border-bottom: 1px solid #425163;
  1195. padding: 15px 20px;
  1196. }
  1197. ::v-deep .el-dialog__title {
  1198. color: #ffffff;
  1199. font-size: 16px;
  1200. font-weight: 500;
  1201. }
  1202. ::v-deep .el-dialog__body {
  1203. padding: 20px;
  1204. color: #e0e6ed;
  1205. max-height: 60vh;
  1206. overflow-y: auto;
  1207. }
  1208. ::v-deep .el-dialog__footer {
  1209. border-top: 1px solid #425163;
  1210. padding: 15px 20px;
  1211. background-color: #273344;
  1212. border-bottom-left-radius: 6px;
  1213. border-bottom-right-radius: 6px;
  1214. }
  1215. /* 弹窗内表单样式 */
  1216. ::v-deep .el-dialog .el-form-item {
  1217. margin-bottom: 18px;
  1218. }
  1219. ::v-deep .el-dialog .el-form-item__label {
  1220. color: #8796ad;
  1221. font-weight: 400;
  1222. }
  1223. ::v-deep .el-dialog .el-input__inner,
  1224. ::v-deep .el-dialog .el-textarea__inner,
  1225. ::v-deep .el-dialog .el-select .el-input__inner {
  1226. background-color: #1f2a38;
  1227. border: 1px solid #425163;
  1228. color: #e0e6ed;
  1229. transition: all 0.3s;
  1230. }
  1231. ::v-deep .el-dialog .el-input__inner:focus,
  1232. ::v-deep .el-dialog .el-textarea__inner:focus,
  1233. ::v-deep .el-dialog .el-select .el-input__inner:focus {
  1234. border-color: #409eff;
  1235. box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
  1236. }
  1237. /* 弹窗内下拉菜单样式 */
  1238. ::v-deep .el-dialog .el-select-dropdown {
  1239. background-color: #2d3a4b;
  1240. border: 1px solid #425163;
  1241. }
  1242. ::v-deep .el-dialog .el-select-dropdown__item {
  1243. color: #e0e6ed;
  1244. background-color: #2d3a4b;
  1245. }
  1246. ::v-deep .el-dialog .el-select-dropdown__item:hover {
  1247. background-color: #384860;
  1248. }
  1249. ::v-deep .el-dialog .el-select-dropdown__item.selected {
  1250. background-color: #409eff1a;
  1251. color: #409eff;
  1252. }
  1253. /* 弹窗按钮样式 */
  1254. ::v-deep .el-dialog .el-button {
  1255. border-radius: 4px;
  1256. transition: all 0.2s;
  1257. }
  1258. ::v-deep .el-dialog .el-button--primary {
  1259. background-color: #409eff;
  1260. border-color: #409eff;
  1261. }
  1262. ::v-deep .el-dialog .el-button--primary:hover {
  1263. background-color: #66b1ff;
  1264. border-color: #66b1ff;
  1265. }
  1266. ::v-deep .el-dialog .el-button:not(.el-button--primary) {
  1267. background-color: #1f2a38;
  1268. border-color: #425163;
  1269. color: #e0e6ed;
  1270. }
  1271. ::v-deep .el-dialog .el-button:not(.el-button--primary):hover {
  1272. background-color: #384860;
  1273. border-color: #556680;
  1274. }
  1275. /* 弹窗关闭按钮 */
  1276. ::v-deep .el-dialog__headerbtn .el-dialog__close {
  1277. color: #8796ad;
  1278. transition: all 0.2s;
  1279. }
  1280. ::v-deep .el-dialog__headerbtn .el-dialog__close:hover {
  1281. color: #ffffff;
  1282. background-color: #384860;
  1283. border-radius: 50%;
  1284. }
  1285. .section-title {
  1286. margin: 0 0 15px 0;
  1287. font-size: 18px;
  1288. color: #ffffff;
  1289. padding-bottom: 10px;
  1290. border-bottom: 1px solid #ebeef5;
  1291. }
  1292. .task-editor-section {
  1293. flex: 1;
  1294. }
  1295. .editor-card {
  1296. height: 100%;
  1297. }
  1298. .editor-content {
  1299. height: calc(100% - 60px);
  1300. overflow-y: auto;
  1301. padding: 20px;
  1302. }
  1303. /* 暗色主题样式 */
  1304. .dark-card {
  1305. background-color: #2d3a4b;
  1306. border: 1px solid #425163;
  1307. color: #e0e6ed;
  1308. overflow: auto !important;
  1309. }
  1310. .dark-title {
  1311. color: #ffffff;
  1312. }
  1313. .dark-form ::v-deep .el-form-item__label {
  1314. color: #8796ad;
  1315. }
  1316. .dark-form ::v-deep .el-input__inner,
  1317. .dark-form ::v-deep .el-textarea__inner,
  1318. .dark-form ::v-deep .el-select .el-input__inner,
  1319. .dark-form ::v-deep .el-input-number__input {
  1320. background-color: #1f2a38;
  1321. border: 1px solid #425163;
  1322. color: #e0e6ed;
  1323. }
  1324. .task-detail-section {
  1325. margin-bottom: 30px;
  1326. padding: 15px;
  1327. background-color: white;
  1328. border-radius: 4px;
  1329. box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  1330. }
  1331. .section-header {
  1332. display: flex;
  1333. justify-content: space-between;
  1334. align-items: center;
  1335. margin-bottom: 20px;
  1336. }
  1337. .equipment-grid {
  1338. display: grid;
  1339. grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  1340. gap: 20px;
  1341. margin-bottom: 30px;
  1342. }
  1343. .equipment-card-item {
  1344. transition: all 0.3s ease;
  1345. }
  1346. .equipment-card-item:hover {
  1347. transform: translateY(-5px);
  1348. box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
  1349. }
  1350. .task-adjustment-section {
  1351. margin-top: 20px;
  1352. margin-bottom: 30px;
  1353. }
  1354. .editor-toolbar {
  1355. border: 1px solid #425163;
  1356. border-bottom: none;
  1357. background-color: #2d3a4b;
  1358. }
  1359. .editor-main {
  1360. height: 300px;
  1361. border: 1px solid #425163;
  1362. background-color: #1f2a38;
  1363. color: #e0e6ed;
  1364. }
  1365. .editor-actions {
  1366. margin-top: 15px;
  1367. text-align: right;
  1368. }
  1369. .form-section-title {
  1370. color: #409eff;
  1371. margin: 20px 0 15px;
  1372. padding-bottom: 10px;
  1373. border-bottom: 1px solid #425163;
  1374. }
  1375. /* 响应式设计 */
  1376. @media (max-width: 1200px) {
  1377. .main-container {
  1378. grid-template-columns: 1fr;
  1379. grid-template-rows: auto auto;
  1380. }
  1381. .right-section {
  1382. margin-top: 20px;
  1383. height: 800px;
  1384. }
  1385. .el-table {
  1386. flex: 0 0 30%;
  1387. }
  1388. .equipment-grid {
  1389. grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  1390. }
  1391. }
  1392. @media (max-width: 992px) {
  1393. .equipment-grid {
  1394. grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  1395. }
  1396. }
  1397. @media (max-width: 768px) {
  1398. .equipment-grid {
  1399. grid-template-columns: 1fr;
  1400. }
  1401. }
  1402. </style>