MaintPlanForm.vue 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  1. <template>
  2. <el-dialog :title="title" :visible.sync="dialogVisible" width="1200px" append-to-body @close="handleClose">
  3. <el-form ref="form" :model="formData" :rules="rules" label-width="120px">
  4. <!-- 基础信息区域 -->
  5. <div class="form-section">
  6. <div class="section-header">
  7. <i class="el-icon-info"></i>
  8. <span class="section-title">基础信息</span>
  9. </div>
  10. <el-row :gutter="20">
  11. <el-col :span="12">
  12. <el-form-item label="选择设备" prop="devId">
  13. <el-select
  14. v-model="formData.devId"
  15. filterable
  16. remote
  17. :remote-method="searchDevice"
  18. :loading="deviceLoading"
  19. placeholder="请输入设备位号或名称搜索"
  20. style="width: 100%"
  21. @change="handleDeviceChange"
  22. @focus="handleDeviceFocus"
  23. :disabled="!!formData.planId"
  24. clearable>
  25. <el-option
  26. v-for="device in deviceOptions"
  27. :key="device.devId"
  28. :label="`${device.devTag} - ${device.devName}`"
  29. :value="device.devId">
  30. <span style="float: left">{{ device.devTag }}</span>
  31. <span style="float: right; color: #8492a6; font-size: 13px">{{ device.devName }}</span>
  32. </el-option>
  33. <div v-if="deviceOptions.length === 0 && !deviceLoading" style="padding: 10px; text-align: center; color: #909399;">
  34. 请输入设备位号或名称进行搜索
  35. </div>
  36. </el-select>
  37. </el-form-item>
  38. </el-col>
  39. <el-col :span="12">
  40. <el-form-item label="计划开始时间" prop="planTime">
  41. <el-date-picker
  42. v-model="formData.planTime"
  43. type="date"
  44. value-format="yyyy-MM-dd"
  45. placeholder="选择计划开始时间"
  46. style="width: 100%">
  47. </el-date-picker>
  48. </el-form-item>
  49. </el-col>
  50. </el-row>
  51. <el-row :gutter="20">
  52. <el-col :span="12">
  53. <el-form-item label="计划结束时间" prop="planEndTime">
  54. <el-date-picker
  55. v-model="formData.planEndTime"
  56. type="date"
  57. value-format="yyyy-MM-dd"
  58. placeholder="选择计划结束时间"
  59. style="width: 100%">
  60. </el-date-picker>
  61. </el-form-item>
  62. </el-col>
  63. <el-col :span="12">
  64. <el-form-item label="责任人" prop="responsible">
  65. <el-select
  66. v-model="formData.responsible"
  67. placeholder="请选择责任人"
  68. style="width: 100%"
  69. clearable
  70. filterable>
  71. <el-option
  72. v-for="staff in staffOptions"
  73. :key="staff.staffid"
  74. :label="`${staff.name} (${staff.staffid})`"
  75. :value="staff.staffid">
  76. </el-option>
  77. <div v-if="staffOptions.length === 0" style="padding: 10px; text-align: center; color: #909399;">
  78. 暂无人员数据
  79. </div>
  80. </el-select>
  81. </el-form-item>
  82. </el-col>
  83. </el-row>
  84. <el-row :gutter="20">
  85. <el-col :span="12">
  86. <el-form-item label="审批人" prop="approver">
  87. <el-select
  88. v-model="formData.approver"
  89. placeholder="请选择审批人"
  90. style="width: 100%"
  91. clearable
  92. filterable
  93. :disabled="!!formData.planId">
  94. <el-option
  95. v-for="staff in staffOptions"
  96. :key="staff.staffid"
  97. :label="`${staff.name} (${staff.staffid})`"
  98. :value="staff.staffid">
  99. </el-option>
  100. <div v-if="staffOptions.length === 0" style="padding: 10px; text-align: center; color: #909399;">
  101. 暂无人员数据
  102. </div>
  103. </el-select>
  104. </el-form-item>
  105. </el-col>
  106. <el-col :span="12">
  107. <el-form-item label="备注" prop="remarks">
  108. <el-input v-model="formData.remarks" type="textarea" :rows="2" placeholder="请输入备注" />
  109. </el-form-item>
  110. </el-col>
  111. </el-row>
  112. </div>
  113. <!-- 设备信息展示 -->
  114. <div class="form-section" v-if="selectedDevice">
  115. <div class="section-header">
  116. <i class="el-icon-s-platform"></i>
  117. <span class="section-title">设备信息</span>
  118. </div>
  119. <el-descriptions :column="3" border size="small">
  120. <el-descriptions-item label="装置">{{ selectedDevice.plant }}</el-descriptions-item>
  121. <el-descriptions-item label="设备位号">{{ selectedDevice.devTag }}</el-descriptions-item>
  122. <el-descriptions-item label="设备名称">{{ selectedDevice.devName }}</el-descriptions-item>
  123. <el-descriptions-item label="位置">{{ selectedDevice.devLoc }}</el-descriptions-item>
  124. <el-descriptions-item label="设备类型">{{ selectedDevice.devType }}</el-descriptions-item>
  125. <el-descriptions-item label="区域负责人">{{ selectedDevice.areaResponsible }}</el-descriptions-item>
  126. </el-descriptions>
  127. </div>
  128. <!-- 部件列表及维修记录选择 -->
  129. <div class="form-section" v-if="compoList.length > 0">
  130. <div class="section-header">
  131. <i class="el-icon-s-grid"></i>
  132. <span class="section-title">部件维修选择</span>
  133. </div>
  134. <el-table
  135. :data="compoList"
  136. border
  137. size="small"
  138. :height="500"
  139. style="margin-top: 10px">
  140. <el-table-column type="index" label="序号" width="60" align="center" />
  141. <el-table-column label="部件名称" prop="compoName" width="150" :show-overflow-tooltip="true" />
  142. <el-table-column label="检查频率/日期" width="120" align="center">
  143. <template slot-scope="scope">
  144. <div style="line-height: 1.2;">
  145. <div style="font-weight: bold; margin-bottom: 2px;">{{ translateFrequency(scope.row.checkFreq) || '-' }}</div>
  146. <div style="font-size: 12px; color: #666;">{{ scope.row.lastCheckDate ? parseTime(scope.row.lastCheckDate, '{y}-{m}-{d}') : '-' }}</div>
  147. </div>
  148. </template>
  149. </el-table-column>
  150. <el-table-column label="维修频率/日期" width="120" align="center">
  151. <template slot-scope="scope">
  152. <div style="line-height: 1.2;">
  153. <div style="font-weight: bold; margin-bottom: 2px;">{{ translateFrequency(scope.row.maintFreq) || '-' }}</div>
  154. <div style="font-size: 12px; color: #666;">{{ scope.row.lastMaintDate ? parseTime(scope.row.lastMaintDate, '{y}-{m}-{d}') : '-' }}</div>
  155. </div>
  156. </template>
  157. </el-table-column>
  158. <el-table-column label="更换频率/日期" width="120" align="center">
  159. <template slot-scope="scope">
  160. <div style="line-height: 1.2;">
  161. <div style="font-weight: bold; margin-bottom: 2px;">{{ translateFrequency(scope.row.replaceFreq) || '-' }}</div>
  162. <div style="font-size: 12px; color: #666;">{{ scope.row.lastReplaceDate ? parseTime(scope.row.lastReplaceDate, '{y}-{m}-{d}') : '-' }}</div>
  163. </div>
  164. </template>
  165. </el-table-column>
  166. <el-table-column label="本次维修" width="100" align="center">
  167. <template slot-scope="scope">
  168. <el-checkbox
  169. v-model="scope.row.needMaint"
  170. :disabled="scope.row.recordStatus === 2 || scope.row.recordStatus === '2'"
  171. @change="handleMaintCheckChange(scope.row)"
  172. >需要维修</el-checkbox>
  173. </template>
  174. </el-table-column>
  175. <el-table-column label="维修形式" width="200" align="center">
  176. <template slot-scope="scope">
  177. <el-radio-group
  178. v-model="scope.row.maintType"
  179. :disabled="!scope.row.needMaint || scope.row.recordStatus === 2 || scope.row.recordStatus === '2'"
  180. @change="handleMaintTypeChange(scope.row)"
  181. style="display: flex; flex-direction: row; gap: 0px;">
  182. <el-radio label="1" style="margin-right: 0; margin-left: 0;">检查</el-radio>
  183. <el-radio label="2" style="margin-right: 0; margin-left: 0;">维修</el-radio>
  184. <el-radio label="3" style="margin-right: 0; margin-left: 0;">更换</el-radio>
  185. </el-radio-group>
  186. </template>
  187. </el-table-column>
  188. <el-table-column label="负责人" width="150" align="center">
  189. <template slot-scope="scope">
  190. <el-select
  191. v-model="scope.row.maintResponsible"
  192. :placeholder="getResponsiblePlaceholder(scope.row.maintType)"
  193. style="width: 100%"
  194. :disabled="!scope.row.needMaint || scope.row.recordStatus === 2 || scope.row.recordStatus === '2'"
  195. clearable
  196. filterable>
  197. <el-option
  198. v-for="staff in staffOptions"
  199. :key="staff.staffid"
  200. :label="`${staff.name} (${staff.staffid})`"
  201. :value="staff.staffid">
  202. </el-option>
  203. </el-select>
  204. </template>
  205. </el-table-column>
  206. <el-table-column label="维修状态" width="100" align="center">
  207. <template slot-scope="scope">
  208. <el-tag
  209. v-if="scope.row.recordStatus !== undefined && scope.row.recordStatus !== null"
  210. :type="getRecordStatusTagType(scope.row.recordStatus)"
  211. size="small"
  212. >
  213. {{ getRecordStatusText(scope.row.recordStatus) }}
  214. </el-tag>
  215. <span v-else>-</span>
  216. </template>
  217. </el-table-column>
  218. </el-table>
  219. </div>
  220. </el-form>
  221. <div slot="footer" class="dialog-footer">
  222. <el-button type="primary" @click="handleSubmit" v-if="!formData.planId">提交申请</el-button>
  223. <el-button type="primary" @click="handleSubmit" v-else-if="formData.approvalStatus !== '1'">确 定</el-button>
  224. <el-button type="primary" @click="handleSubmit" v-else>再次提交申请</el-button>
  225. <el-button @click="handleCancel">取 消</el-button>
  226. </div>
  227. </el-dialog>
  228. </template>
  229. <script>
  230. import { listRel_device, getRel_device } from "@/api/reliability/rel_device";
  231. import { listRel_compo } from "@/api/reliability/rel_compo";
  232. import { listStaffmgrAll } from "@/api/plant/staffmgr";
  233. import { parseTime as formatTime } from "@/utils/ruoyi";
  234. export default {
  235. name: "MaintPlanForm",
  236. props: {
  237. visible: {
  238. type: Boolean,
  239. default: false
  240. },
  241. title: {
  242. type: String,
  243. default: "设备维修计划"
  244. },
  245. form: {
  246. type: Object,
  247. default: () => ({})
  248. }
  249. },
  250. data() {
  251. return {
  252. dialogVisible: this.visible,
  253. formData: {},
  254. rules: {
  255. devId: [
  256. { required: true, message: "请选择设备", trigger: "change" }
  257. ],
  258. planTime: [
  259. { required: true, message: "请选择计划开始时间", trigger: "change" }
  260. ],
  261. approver: [
  262. { required: true, message: "请选择审批人", trigger: "change" }
  263. ]
  264. },
  265. // 设备相关
  266. deviceOptions: [],
  267. deviceLoading: false,
  268. selectedDevice: null,
  269. // 部件相关
  270. compoList: [],
  271. // 所有人员选项
  272. staffOptions: []
  273. };
  274. },
  275. watch: {
  276. visible(newVal) {
  277. this.dialogVisible = newVal;
  278. if (newVal) {
  279. this.initForm();
  280. }
  281. },
  282. dialogVisible(newVal) {
  283. if (!newVal) {
  284. this.$emit('update:visible', false);
  285. }
  286. },
  287. form: {
  288. handler(newVal) {
  289. if (newVal && Object.keys(newVal).length > 0) {
  290. this.formData = { ...newVal };
  291. if (this.formData.relDevice) {
  292. this.selectedDevice = this.formData.relDevice;
  293. if (this.formData.relDevice.devId && !this.formData.devId) {
  294. this.formData.devId = this.formData.relDevice.devId;
  295. }
  296. if (this.formData.planId && this.formData.relDevice.devId) {
  297. this.deviceOptions = [this.formData.relDevice];
  298. }
  299. // 自动填充设备负责人(如果还没有设置责任人)
  300. if (this.formData.relDevice.areaResponsible && this.staffOptions.length > 0 && !this.formData.responsible) {
  301. const staff = this.staffOptions.find(s => s.staffid === this.formData.relDevice.areaResponsible);
  302. if (staff) {
  303. this.formData.responsible = staff.name;
  304. }
  305. }
  306. if (this.formData.compoList && this.formData.compoList.length > 0) {
  307. this.initCompoListFromData(this.formData.compoList);
  308. } else if (this.selectedDevice.devTag) {
  309. this.loadCompoList(this.selectedDevice.devTag);
  310. }
  311. } else if (this.formData.devId) {
  312. // 当从外部传入 devId 时,需要加载设备信息并添加到 deviceOptions
  313. this.loadDeviceInfo(this.formData.devId);
  314. getRel_device(this.formData.devId).then(response => {
  315. // 确保 deviceOptions 中包含该设备,以便下拉框能正确显示
  316. const deviceExists = this.deviceOptions.find(d => d.devId === this.formData.devId);
  317. if (!deviceExists) {
  318. this.deviceOptions = [response.data];
  319. }
  320. });
  321. }
  322. const convertIdsToNames = () => {
  323. // 审批人和责任人都已经是staffId,无需转换,直接使用
  324. // 显示时通过 el-option 的 label 显示"名称 (员工号)"格式
  325. };
  326. if (this.staffOptions.length > 0) {
  327. this.$nextTick(convertIdsToNames);
  328. } else {
  329. const checkStaffOptions = () => {
  330. if (this.staffOptions.length > 0) {
  331. this.$nextTick(convertIdsToNames);
  332. } else {
  333. setTimeout(checkStaffOptions, 100);
  334. }
  335. };
  336. checkStaffOptions();
  337. }
  338. } else if (!newVal || Object.keys(newVal).length === 0) {
  339. this.resetForm();
  340. }
  341. },
  342. deep: true,
  343. immediate: true
  344. }
  345. },
  346. created() {
  347. this.getStaffList();
  348. },
  349. methods: {
  350. /** 查询人员列表 */
  351. getStaffList() {
  352. listStaffmgrAll().then(response => {
  353. this.staffOptions = response.rows || response.data || [];
  354. }).catch(error => {
  355. console.error('加载人员数据失败:', error);
  356. });
  357. },
  358. /** 初始化表单 */
  359. initForm() {
  360. if (!this.formData.planId && (!this.formData.devId && !this.formData.planTime)) {
  361. this.resetForm();
  362. }
  363. },
  364. /** 表单重置 */
  365. resetForm() {
  366. this.formData = {
  367. planId: null,
  368. devId: null,
  369. plant: null,
  370. devName: null,
  371. devTag: null,
  372. planTime: null,
  373. approvalStatus: "0",
  374. responsible: null,
  375. completionStatus: "0",
  376. processId: null,
  377. approver: null,
  378. delFlag: null,
  379. createrCode: null,
  380. createdate: null,
  381. updaterCode: null,
  382. updatedate: null,
  383. deptId: null,
  384. remarks: null,
  385. maintComponents: []
  386. };
  387. this.selectedDevice = null;
  388. this.compoList = [];
  389. this.deviceOptions = [];
  390. this.$nextTick(() => {
  391. if (this.$refs.form) {
  392. this.$refs.form.clearValidate();
  393. }
  394. });
  395. },
  396. /** 设备下拉框获得焦点 */
  397. handleDeviceFocus() {
  398. // 预留方法,可在此处加载默认设备列表
  399. },
  400. /** 设备选择改变 */
  401. handleDeviceChange(devId) {
  402. if (!devId) {
  403. this.selectedDevice = null;
  404. this.compoList = [];
  405. return;
  406. }
  407. // 获取设备详情
  408. getRel_device(devId).then(response => {
  409. this.selectedDevice = response.data;
  410. this.formData.plant = response.data.plant;
  411. this.formData.devName = response.data.devName;
  412. this.formData.devTag = response.data.devTag;
  413. // 自动填充设备负责人(areaResponsible)
  414. if (response.data.areaResponsible && this.staffOptions.length > 0) {
  415. const staff = this.staffOptions.find(s => s.staffid === response.data.areaResponsible);
  416. if (staff) {
  417. this.formData.responsible = staff.name;
  418. }
  419. }
  420. // 加载该设备的部件列表(使用devTag)
  421. if (this.selectedDevice.devTag) {
  422. this.loadCompoList(this.selectedDevice.devTag);
  423. }
  424. });
  425. },
  426. /** 搜索设备 */
  427. searchDevice(query) {
  428. if (query !== '') {
  429. this.deviceLoading = true;
  430. listRel_device({
  431. devTag: query,
  432. devName: query,
  433. pageNum: 1,
  434. pageSize: 50
  435. }).then(response => {
  436. this.deviceOptions = response.rows || [];
  437. this.deviceLoading = false;
  438. }).catch(() => {
  439. this.deviceLoading = false;
  440. this.deviceOptions = [];
  441. });
  442. } else {
  443. this.deviceOptions = [];
  444. }
  445. },
  446. /** 加载设备信息 */
  447. loadDeviceInfo(devId) {
  448. getRel_device(devId).then(response => {
  449. this.selectedDevice = response.data;
  450. // 将当前设备添加到deviceOptions中,以便下拉框显示
  451. const deviceExists = this.deviceOptions.find(d => d.devId === devId);
  452. if (!deviceExists) {
  453. this.deviceOptions = [response.data];
  454. }
  455. // 自动填充设备负责人(areaResponsible),如果还没有设置责任人
  456. if (response.data.areaResponsible && this.staffOptions.length > 0 && !this.formData.responsible) {
  457. const staff = this.staffOptions.find(s => s.staffid === response.data.areaResponsible);
  458. if (staff) {
  459. this.formData.responsible = staff.name;
  460. }
  461. }
  462. // 使用selectedDevice的devTag来加载部件列表
  463. if (this.selectedDevice && this.selectedDevice.devTag) {
  464. this.loadCompoList(this.selectedDevice.devTag);
  465. }
  466. });
  467. },
  468. /** 从后端数据初始化部件列表 */
  469. initCompoListFromData(compoListData) {
  470. this.compoList = compoListData.map(compo => ({
  471. ...compo,
  472. needMaint: false,
  473. maintType: '',
  474. maintResponsible: '',
  475. recordStatus: null,
  476. checkFreq: compo.inspFreq || '',
  477. lastCheckDate: compo.lastInspDate || '',
  478. maintFreq: compo.fixFreq || '',
  479. lastMaintDate: compo.lastFixDate || '',
  480. replaceFreq: compo.replaceFreq || '',
  481. lastReplaceDate: compo.lastReplaceDate || '',
  482. inspector: compo.inspector || '',
  483. fixer: compo.fixer || '',
  484. inspectorName: compo.inspectorName || '',
  485. fixerName: compo.fixerName || '',
  486. }));
  487. this.$nextTick(() => {
  488. setTimeout(() => {
  489. this.markSelectedComponents();
  490. }, 100);
  491. });
  492. },
  493. /** 加载部件列表 */
  494. loadCompoList(devTag) {
  495. const targetDevTag = devTag || (this.selectedDevice ? this.selectedDevice.devTag : null);
  496. if (!targetDevTag) {
  497. return;
  498. }
  499. listRel_compo({
  500. devTag: targetDevTag,
  501. pageNum: 1,
  502. pageSize: 1000
  503. }).then(response => {
  504. const compos = response.rows || [];
  505. this.initCompoListFromData(compos);
  506. });
  507. },
  508. /** 标记已选择的部件(根据维修记录) */
  509. markSelectedComponents() {
  510. if (!this.compoList || this.compoList.length === 0) {
  511. return;
  512. }
  513. const maintRecords = this.formData.maintRecordsList || this.formData.maintRecords || [];
  514. if (!this.formData.planId || !maintRecords || maintRecords.length === 0) {
  515. return;
  516. }
  517. const markComponents = () => {
  518. this.compoList.forEach(compo => {
  519. const record = maintRecords.find(r => r.compoId == compo.compoId);
  520. if (record) {
  521. compo.recordStatus = record.recordStatus;
  522. // 如果recordStatus为-1(删除申请中),则不勾选维修
  523. if (record.recordStatus === -1 || record.recordStatus === '-1') {
  524. compo.needMaint = false;
  525. compo.maintType = '';
  526. compo.maintResponsible = '';
  527. } else {
  528. compo.needMaint = true;
  529. compo.maintType = record.maintType;
  530. // 责任人存储staffId
  531. if (record.responsible) {
  532. compo.maintResponsible = record.responsible;
  533. } else {
  534. // 没有记录的responsible,根据维修类型使用默认值
  535. if (compo.maintType === '1') {
  536. compo.maintResponsible = compo.inspector || '';
  537. } else if (compo.maintType === '2' || compo.maintType === '3') {
  538. compo.maintResponsible = compo.fixer || '';
  539. }
  540. }
  541. }
  542. }
  543. });
  544. };
  545. if (this.staffOptions.length > 0) {
  546. this.$nextTick(markComponents);
  547. } else {
  548. const checkStaffOptions = () => {
  549. if (this.staffOptions.length > 0) {
  550. this.$nextTick(markComponents);
  551. } else {
  552. setTimeout(checkStaffOptions, 100);
  553. }
  554. };
  555. checkStaffOptions();
  556. }
  557. },
  558. /** 维修选择改变 */
  559. handleMaintCheckChange(compo) {
  560. if (!compo.needMaint) {
  561. compo.maintType = '';
  562. compo.maintResponsible = '';
  563. }
  564. },
  565. /** 维修形式改变 */
  566. handleMaintTypeChange(compo) {
  567. if (compo.maintType === '1') {
  568. compo.maintResponsible = compo.inspector || '';
  569. } else if (compo.maintType === '2' || compo.maintType === '3') {
  570. compo.maintResponsible = compo.fixer || '';
  571. } else {
  572. compo.maintResponsible = '';
  573. }
  574. },
  575. /** 根据姓名获取工号 */
  576. getStaffIdByName(name) {
  577. if (!name) return '';
  578. const staff = this.staffOptions.find(s => s.name === name);
  579. return staff ? staff.staffid : '';
  580. },
  581. getResponsiblePlaceholder(maintType) {
  582. switch(maintType) {
  583. case '1': return '选择检查人';
  584. case '2': return '选择维修人';
  585. case '3': return '选择更换人';
  586. default: return '选择负责人';
  587. }
  588. },
  589. /** 翻译频率字段 */
  590. translateFrequency(frequency) {
  591. if (!frequency) return '';
  592. const match = frequency.match(/^(\d+)([ym])$/);
  593. if (match) {
  594. const number = match[1];
  595. const unit = match[2];
  596. switch (unit) {
  597. case 'y':
  598. return `${number}年一次`;
  599. case 'm':
  600. return `${number}月一次`;
  601. default:
  602. return frequency;
  603. }
  604. }
  605. return frequency;
  606. },
  607. /** 时间格式化 */
  608. parseTime(time, pattern) {
  609. return formatTime(time, pattern);
  610. },
  611. /** 获取维修状态文本 */
  612. getRecordStatusText(status) {
  613. if (status === -1 || status === '-1') return '删除申请中';
  614. if (status === 0 || status === '0') return '新增申请中';
  615. if (status === 1 || status === '1') return '待完成';
  616. if (status === 2 || status === '2') return '已完成';
  617. return status != null ? status : '-';
  618. },
  619. /** 获取维修状态标签类型 */
  620. getRecordStatusTagType(status) {
  621. if (status === -1 || status === '-1') return 'danger';
  622. if (status === 0 || status === '0') return 'warning';
  623. if (status === 1 || status === '1') return 'info';
  624. if (status === 2 || status === '2') return 'success';
  625. return '';
  626. },
  627. /** 提交表单 */
  628. handleSubmit() {
  629. this.$refs.form.validate(valid => {
  630. if (valid) {
  631. if (this.compoList.length > 0) {
  632. const maintComponents = this.compoList
  633. .filter(compo => compo.needMaint)
  634. .map(compo => ({
  635. compoId: compo.compoId,
  636. compoName: compo.compoName,
  637. maintType: compo.maintType,
  638. responsible: compo.maintResponsible,
  639. inspectContent: '',
  640. maintContent: '',
  641. maintResult: '',
  642. maintCost: null,
  643. maintDuration: null,
  644. processLoss: '',
  645. attachments: '',
  646. remarks: ''
  647. }));
  648. this.formData.maintComponents = maintComponents;
  649. }
  650. // 审批人和责任人都已经是staffId格式,无需转换
  651. this.$emit('submit', this.formData);
  652. }
  653. });
  654. },
  655. /** 取消 */
  656. handleCancel() {
  657. this.handleClose();
  658. },
  659. /** 关闭弹窗 */
  660. handleClose() {
  661. this.resetForm();
  662. this.$emit('update:visible', false);
  663. this.$emit('cancel');
  664. }
  665. }
  666. };
  667. </script>
  668. <style scoped lang="scss">
  669. .form-section {
  670. margin-bottom: 20px;
  671. .section-header {
  672. display: flex;
  673. align-items: center;
  674. margin-bottom: 15px;
  675. padding-bottom: 10px;
  676. border-bottom: 1px solid #e4e7ed;
  677. .el-icon-info,
  678. .el-icon-s-platform,
  679. .el-icon-s-grid,
  680. .el-icon-setting {
  681. font-size: 18px;
  682. color: #409EFF;
  683. margin-right: 8px;
  684. }
  685. .section-title {
  686. font-size: 16px;
  687. font-weight: 600;
  688. color: #303133;
  689. }
  690. }
  691. }
  692. .dialog-footer {
  693. text-align: right;
  694. }
  695. // 紧凑的radio按钮样式
  696. ::v-deep .el-table .el-radio__label {
  697. padding-left: 2px !important;
  698. }
  699. </style>