index.vue 106 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999
  1. <template>
  2. <div class="app-container">
  3. <!-- 查询条件区域 -->
  4. <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="100px" label-position="top">
  5. <el-form-item label="工单编码" prop="workOrderProjectNo" label-position="top">
  6. <el-input
  7. v-model="queryParams.workOrderProjectNo"
  8. placeholder="请输入工单编码"
  9. clearable
  10. @keyup.enter="handleQuery"
  11. />
  12. </el-form-item>
  13. <el-form-item label="风机编号" prop="pcsDeviceName" label-position="top">
  14. <el-input
  15. v-model="queryParams.pcsDeviceName"
  16. placeholder="请输入风机编号"
  17. clearable
  18. @keyup.enter="handleQuery"
  19. />
  20. </el-form-item>
  21. <el-form-item label="维保中心" prop="gxtCenter" label-position="top">
  22. <el-select
  23. v-model="queryParams.gxtCenter"
  24. placeholder="请选择维保中心"
  25. clearable
  26. @change="handleMaintenanceCenterChange"
  27. >
  28. <el-option
  29. v-for="item in maintenanceCenterOptions"
  30. :key="item.deptId"
  31. :label="item.deptName"
  32. :value="item.deptName">
  33. </el-option>
  34. </el-select>
  35. </el-form-item>
  36. <el-form-item label="场站" prop="pcsStationName" label-position="top">
  37. <el-select
  38. v-model="queryParams.pcsStationName"
  39. placeholder="请选择场站"
  40. clearable
  41. :disabled="!queryParams.gxtCenter"
  42. >
  43. <el-option
  44. v-for="item in stationOptions"
  45. :key="item.deptId"
  46. :label="item.deptName"
  47. :value="item.deptName">
  48. </el-option>
  49. </el-select>
  50. </el-form-item>
  51. <el-form-item label="工单状态" prop="workOrderStatus" label-position="top">
  52. <el-select v-model="queryParams.workOrderStatus" placeholder="请选择工单状态" clearable>
  53. <el-option
  54. v-for="dict in gxt_work_order_status"
  55. :key="dict.value"
  56. :label="dict.label"
  57. :value="dict.value"
  58. />
  59. </el-select>
  60. </el-form-item>
  61. <el-form-item label-position="top">
  62. <div class="item-search">&nbsp;</div>
  63. <div class="item-search">
  64. <el-button icon="Refresh" @click="resetQuery">重置</el-button>
  65. <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
  66. </div>
  67. </el-form-item>
  68. </el-form>
  69. <!-- 操作按钮区域 -->
  70. <el-row :gutter="10" class="mb8">
  71. <!-- 空的按钮区域,保持与其他页面一致的间距 -->
  72. </el-row>
  73. <!-- 工单列表 -->
  74. <el-table
  75. v-loading="loading"
  76. :data="orderList"
  77. style="width: 100%"
  78. :max-height="tableHeight"
  79. >
  80. <el-table-column label="工单类型" align="center" prop="orderType" width="100">
  81. <template #default="scope">
  82. <el-tag v-if="scope.row.orderType === 1" type="danger">维修工单</el-tag>
  83. <el-tag v-else type="success">维保工单</el-tag>
  84. </template>
  85. </el-table-column>
  86. <el-table-column label="工单编码" align="center" prop="workOrderProjectNo" width="160" fixed>
  87. <template #default="scope">
  88. <el-button link type="primary" @click="handleView(scope.row)">
  89. {{ scope.row.workOrderProjectNo }}
  90. </el-button>
  91. </template>
  92. </el-table-column>
  93. <el-table-column label="风机编号" align="center" prop="pcsDeviceName" width="120" :show-overflow-tooltip="true">
  94. <template #default="scope">
  95. {{ scope.row.pcsDeviceName || '-' }}
  96. </template>
  97. </el-table-column>
  98. <el-table-column label="工单状态" align="center" prop="workOrderStatus" min-width="100">
  99. <template #default="scope">
  100. <dict-tag :options="gxt_work_order_status" :value="scope.row.workOrderStatus" />
  101. </template>
  102. </el-table-column>
  103. <el-table-column label="维保中心" align="center" prop="gxtCenter" width="150" :show-overflow-tooltip="true">
  104. <template #default="scope">
  105. {{ scope.row.gxtCenter || '-' }}
  106. </template>
  107. </el-table-column>
  108. <el-table-column label="场站" align="center" prop="pcsStationName" width="150" :show-overflow-tooltip="true">
  109. <template #default="scope">
  110. {{ scope.row.pcsStationName || '-' }}
  111. </template>
  112. </el-table-column>
  113. <el-table-column label="品牌" align="center" prop="brand" width="120" :show-overflow-tooltip="true">
  114. <template #default="scope">
  115. {{ scope.row.brand || '-' }}
  116. </template>
  117. </el-table-column>
  118. <el-table-column label="机型" align="center" prop="model" width="120" :show-overflow-tooltip="true">
  119. <template #default="scope">
  120. {{ scope.row.model || '-' }}
  121. </template>
  122. </el-table-column>
  123. <el-table-column label="接单人" align="center" prop="acceptUserName" width="100" >
  124. <template #default="scope">
  125. {{ scope.row.acceptUserName || '-' }}
  126. </template>
  127. </el-table-column>
  128. <el-table-column label="接单时间" align="center" prop="acceptTime" width="150">
  129. <template #default="scope">
  130. <span>{{ scope.row.acceptTime ? parseTime(scope.row.acceptTime, '{y}-{m}-{d} {h}:{i}') : '-' }}</span>
  131. </template>
  132. </el-table-column>
  133. <el-table-column label="工作负责人" align="center" prop="teamLeaderName" width="100" >
  134. <template #default="scope">
  135. {{ scope.row.teamLeaderName || '-' }}
  136. </template>
  137. </el-table-column>
  138. <el-table-column label="开始时间" align="center" prop="realStartTime" width="150">
  139. <template #default="scope">
  140. <span>{{ scope.row.realStartTime ? parseTime(scope.row.realStartTime, '{y}-{m}-{d} {h}:{i}') : '-' }}</span>
  141. </template>
  142. </el-table-column>
  143. <el-table-column label="结束时间" align="center" prop="realEndTime" width="150">
  144. <template #default="scope">
  145. <span>{{ scope.row.realEndTime ? parseTime(scope.row.realEndTime, '{y}-{m}-{d} {h}:{i}') : '-' }}</span>
  146. </template>
  147. </el-table-column>
  148. <el-table-column label="操作" align="center" class-name="small-padding fixed-width" min-width="200" fixed="right">
  149. <template #default="scope">
  150. <!-- 维修工单操作按钮 -->
  151. <template v-if="scope.row.orderType === 1">
  152. <el-button
  153. v-if="scope.row.workOrderStatus === 'to_issue' || scope.row.workOrderStatus === 'accept_return'"
  154. type="primary"
  155. link
  156. @click="handleUpdate(scope.row)"
  157. v-hasPermi="['gxt:repairOrder:edit']"
  158. ><i class="fa fa-user-plus"></i>下发</el-button>
  159. <el-button
  160. v-if="scope.row.workOrderStatus === 'assigned'"
  161. type="primary"
  162. link
  163. @click="handleAccept(scope.row)"
  164. v-hasPermi="['gxt:repairOrder:accept']"
  165. ><i class="fa fa-check"></i>接单</el-button>
  166. <el-button
  167. v-if="(scope.row.workOrderStatus === 'to_finish') && (scope.row.teamLeaderId == userStore.id || userStore.roles.includes('admin'))"
  168. type="danger"
  169. link
  170. @click="handleRepairSuspend(scope.row)"
  171. v-hasPermi="['gxt:repairOrder:suspend']"
  172. ><i class="fa fa-stop"></i>挂起</el-button>
  173. <el-button
  174. v-if="(scope.row.workOrderStatus === 'to_finish') && (scope.row.teamLeaderId == userStore.id || userStore.roles.includes('admin'))"
  175. type="warning"
  176. link
  177. @click="handleReturn(scope.row)"
  178. v-hasPermi="['gxt:repairOrder:return']"
  179. ><i class="fa fa-sign-in"></i>退回</el-button> <!--结单退回,负责人退回至班长 -->
  180. <el-button
  181. v-if="scope.row.workOrderStatus === 'return'|| scope.row.workOrderStatus === 'assigned'"
  182. type="warning"
  183. link
  184. @click="handleReturn(scope.row)"
  185. v-hasPermi="['gxt:repairOrder:acceptReturn']"
  186. ><i class="fa fa-sign-in"></i>退回</el-button> <!--接单退回,班长退回至下发环节 -->
  187. <el-button
  188. v-if="scope.row.workOrderStatus === 'to_finish' && (scope.row.teamLeaderId == userStore.id || userStore.roles.includes('admin'))"
  189. type="success"
  190. link
  191. @click="handleRepairOrderFinalize(scope.row)"
  192. v-hasPermi="['gxt:repairOrder:finalize']"
  193. ><i class="fa fa-check"></i>结单</el-button>
  194. <el-button
  195. v-if="scope.row.workOrderStatus === 'to_finish' && (scope.row.teamLeaderId == userStore.id || userStore.roles.includes('admin'))"
  196. type="primary"
  197. link
  198. @click="handleReset(scope.row)"
  199. v-hasPermi="['gxt:repairOrder:finalize']"
  200. ><i class="fa fa-refresh"></i>复启</el-button>
  201. <el-button
  202. v-if="scope.row.workOrderStatus === 'to_approve'"
  203. type="primary"
  204. link
  205. @click="handleApprove(scope.row)"
  206. v-hasPermi="['gxt:repairOrder:approve']"
  207. ><i class="fa fa-check-circle"></i>审批</el-button>
  208. <el-button
  209. v-if="scope.row.restartTime == null && scope.row.workOrderStatus != 'to_issue' && scope.row.workOrderStatus != 'auto_suspend' && scope.row.workOrderStatus != 'accept_return'"
  210. type="success"
  211. link
  212. @click="handleRestart(scope.row)"
  213. v-hasPermi="['gxt:repairOrder:restart']"
  214. ><i class="fa fa-refresh"></i>复运</el-button>
  215. </template>
  216. <!-- 维保工单操作按钮 -->
  217. <template v-else>
  218. <el-button
  219. v-if="scope.row.workOrderStatus === 'to_issue'"
  220. type="primary"
  221. link
  222. @click="handleUpdate(scope.row)"
  223. v-hasPermi="['gxt:maintenance:order:edit']"
  224. ><i class="fa fa-user-plus"></i>下发</el-button>
  225. <el-button
  226. v-if="scope.row.workOrderStatus === 'assigned'"
  227. type="primary"
  228. link
  229. @click="handleAccept(scope.row)"
  230. v-hasPermi="['gxt:maintenance:order:accept']"
  231. ><i class="fa fa-check"></i>接单</el-button>
  232. <el-button
  233. v-if="(scope.row.workOrderStatus === 'to_finish') && (scope.row.teamLeaderId == userStore.id || userStore.roles.includes('admin')) "
  234. type="danger"
  235. link
  236. @click="handleSuspend(scope.row)"
  237. v-hasPermi="['gxt:maintenance:order:suspend']"
  238. ><i class="fa fa-stop"></i>挂起</el-button>
  239. <el-button
  240. v-if="(scope.row.workOrderStatus === 'to_finish') && (scope.row.teamLeaderId == userStore.id || userStore.roles.includes('admin'))"
  241. type="success"
  242. link
  243. @click="handleFinish(scope.row)"
  244. v-hasPermi="['gxt:maintenance:order:complete']"
  245. ><i class="fa fa-check"></i>结单</el-button>
  246. <el-button
  247. v-if="scope.row.workOrderStatus === 'to_approve'"
  248. type="primary"
  249. link
  250. @click="handleApprove(scope.row)"
  251. v-hasPermi="['gxt:maintenance:order:approve']"
  252. ><i class="fa fa-check-circle"></i>审批</el-button>
  253. <el-button
  254. link type="success"
  255. @click="handleRestart(scope.row)"
  256. v-if="scope.row.restartTime == null && scope.row.workOrderStatus != 'to_issue' && scope.row.workOrderStatus != 'auto_suspend'"
  257. v-hasPermi="['gxt:maintenance:order:restart']">
  258. <i class="fa fa-refresh"></i>复运
  259. </el-button>
  260. </template>
  261. <el-button
  262. type="info"
  263. link
  264. @click="handleView(scope.row)"
  265. ><i class="fa fa-eye"></i>查看</el-button>
  266. </template>
  267. </el-table-column>
  268. </el-table>
  269. <pagination
  270. v-show="total>0"
  271. :total="total"
  272. v-model:page="queryParams.pageNum"
  273. v-model:limit="queryParams.pageSize"
  274. @pagination="getList"
  275. />
  276. <!-- 维修工单详情对话框 -->
  277. <ViewDialog
  278. v-model="repairDetailDialogVisible"
  279. :data="detailData"
  280. :work-order-status-options="gxt_work_order_status"
  281. :reset-method-options="gxt_reset_method"
  282. :repair-order-flow-action-type-options="gxt_repair_order_flow_action_type"
  283. :work-area-options="gxt_work_area"
  284. :return-type-options="gxt_return_type"
  285. />
  286. <!-- 维保工单详情对话框 -->
  287. <ViewWorkOrderDialog
  288. v-model="workDetailDialogVisible"
  289. :data="detailData"
  290. :work-order-status-options="gxt_work_order_status"
  291. :repair-order-flow-action-type-options="gxt_repair_order_flow_action_type"
  292. />
  293. <!-- 接单对话框 (维修工单) -->
  294. <el-dialog title="接单" v-model="acceptRepairDialogVisible" width="800px" append-to-body>
  295. <el-form ref="acceptRepairFormRef" :model="acceptRepairForm" :rules="acceptRepairRules" label-width="120px" label-position="top">
  296. <el-row>
  297. <el-col :span="12">
  298. <el-form-item label="工单编码"><el-input v-model="acceptRepairForm.workOrderProjectNo" disabled /></el-form-item>
  299. </el-col>
  300. <el-col :span="12">
  301. <el-form-item label="风机编号"><el-input v-model="acceptRepairForm.pcsDeviceName" disabled /></el-form-item>
  302. </el-col>
  303. <el-col :span="12">
  304. <el-form-item label="工单状态">
  305. <el-select v-model="acceptRepairForm.workOrderStatus" style="width: 100%" disabled>
  306. <el-option
  307. v-for="dict in gxt_work_order_status"
  308. :key="dict.value"
  309. :label="dict.label"
  310. :value="dict.value"
  311. />
  312. </el-select>
  313. </el-form-item>
  314. </el-col>
  315. <el-col :span="12">
  316. <el-form-item label="维保中心"><el-input v-model="acceptRepairForm.gxtCenter" disabled /> </el-form-item>
  317. </el-col>
  318. <el-col :span="12">
  319. <el-form-item label="场站"><el-input v-model="acceptRepairForm.pcsStationName" disabled /> </el-form-item>
  320. </el-col>
  321. <el-col :span="12">
  322. <el-form-item label="品牌"><el-input v-model="acceptRepairForm.brand" disabled /> </el-form-item>
  323. </el-col>
  324. <el-col :span="12">
  325. <el-form-item label="故障代码"><el-input v-model="acceptRepairForm.faultCode" disabled /></el-form-item>
  326. </el-col>
  327. <el-col :span="24">
  328. <el-form-item label="故障信息">
  329. <el-input
  330. v-model="acceptRepairForm.faultBarcode"
  331. type="textarea"
  332. placeholder="请输入故障信息"
  333. maxlength="100"
  334. show-word-limit
  335. :rows="3"
  336. disabled
  337. />
  338. </el-form-item>
  339. </el-col>
  340. </el-row>
  341. <el-row>
  342. <el-col :span="12">
  343. <el-form-item label="工作负责人" prop="teamLeaderId">
  344. <el-input
  345. v-model="acceptRepairForm.teamLeaderName"
  346. placeholder="请输入工作负责人姓名或点击选择"
  347. clearable
  348. @focus="handleTeamLeaderInputFocus"
  349. @blur="handleTeamLeaderInputBlur"
  350. @input="handleTeamLeaderInput"
  351. @clear="handleTeamLeaderClear"
  352. >
  353. </el-input>
  354. <!-- 快速检索下拉框 -->
  355. <div class="quick-select-dropdown" v-show="showTeamLeaderQuickSelect && quickTeamLeaderList.length > 0">
  356. <div
  357. v-for="item in quickTeamLeaderList"
  358. :key="item.userId"
  359. class="quick-select-item"
  360. @click="handleTeamLeaderQuickSelect(item)">
  361. <span class="user-name">{{ item.nickName }}</span>
  362. <span class="user-dept">{{ item.dept?.deptName }}</span>
  363. </div>
  364. </div>
  365. <div class="quick-select-dropdown no-data" v-show="showTeamLeaderQuickSelect && quickTeamLeaderList.length === 0 && acceptRepairForm.teamLeaderName && !teamLeaderLoading">
  366. <div>未找到匹配的人员</div>
  367. </div>
  368. <div class="quick-select-dropdown no-data" v-show="showTeamLeaderQuickSelect && teamLeaderLoading">
  369. <div>
  370. <i class="el-icon-loading"></i>
  371. 搜索中...
  372. </div>
  373. </div>
  374. </el-form-item>
  375. </el-col>
  376. </el-row>
  377. </el-form>
  378. <template #footer>
  379. <div class="dialog-footer">
  380. <el-button @click="acceptRepairDialogVisible = false">取 消</el-button>
  381. <el-button type="primary" @click="submitAcceptRepair">确认接单</el-button>
  382. </div>
  383. </template>
  384. </el-dialog>
  385. <!-- 接单对话框 (维保工单) -->
  386. <el-dialog title="接单" v-model="acceptWorkDialogVisible" width="800px" append-to-body>
  387. <el-form ref="acceptWorkFormRef" :model="acceptWorkForm" :rules="acceptWorkRules" label-width="120px" label-position="top">
  388. <el-row>
  389. <el-col :span="12">
  390. <el-form-item label="工单编码"><el-input v-model="acceptWorkForm.workOrderProjectNo" disabled /></el-form-item>
  391. </el-col>
  392. <el-col :span="12">
  393. <el-form-item label="风机编号"><el-input v-model="acceptWorkForm.pcsDeviceName" disabled /></el-form-item>
  394. </el-col>
  395. <el-col :span="12">
  396. <el-form-item label="工单状态">
  397. <el-select v-model="acceptWorkForm.workOrderStatus" style="width: 100%" disabled>
  398. <el-option
  399. v-for="dict in gxt_work_order_status"
  400. :key="dict.value"
  401. :label="dict.label"
  402. :value="dict.value"
  403. />
  404. </el-select>
  405. </el-form-item>
  406. </el-col>
  407. <el-col :span="12">
  408. <el-form-item label="维保中心"><el-input v-model="acceptWorkForm.gxtCenter" disabled /> </el-form-item>
  409. </el-col>
  410. <el-col :span="12">
  411. <el-form-item label="场站"><el-input v-model="acceptWorkForm.pcsStationName" disabled /> </el-form-item>
  412. </el-col>
  413. <el-col :span="12">
  414. <el-form-item label="品牌"><el-input v-model="acceptWorkForm.brand" disabled /> </el-form-item>
  415. </el-col>
  416. <el-col :span="12">
  417. <el-form-item label="MIS工单编码"><el-input v-model="acceptWorkForm.misNo" disabled /></el-form-item>
  418. </el-col>
  419. </el-row>
  420. <el-row>
  421. <el-col :span="24">
  422. <el-form-item label="维保内容" prop="content">
  423. <el-input v-model="acceptWorkForm.content" type="textarea" :rows="3" disabled />
  424. </el-form-item>
  425. </el-col>
  426. </el-row>
  427. <el-row>
  428. <el-col :span="12">
  429. <el-form-item label="工作负责人" prop="teamLeaderId">
  430. <el-input
  431. v-model="acceptWorkForm.teamLeaderName"
  432. placeholder="请输入工作负责人姓名或点击选择"
  433. clearable
  434. @focus="handleTeamLeaderInputFocus"
  435. @blur="handleTeamLeaderInputBlur"
  436. @input="handleTeamLeaderInput"
  437. @clear="handleTeamLeaderClear"
  438. >
  439. </el-input>
  440. <!-- 快速检索下拉框 -->
  441. <div class="quick-select-dropdown" v-show="showTeamLeaderQuickSelect && quickTeamLeaderList.length > 0">
  442. <div
  443. v-for="item in quickTeamLeaderList"
  444. :key="item.userId"
  445. class="quick-select-item"
  446. @click="handleTeamLeaderQuickSelect(item)">
  447. <span class="user-name">{{ item.nickName }}</span>
  448. <span class="user-dept">{{ item.dept?.deptName }}</span>
  449. </div>
  450. </div>
  451. <div class="quick-select-dropdown no-data" v-show="showTeamLeaderQuickSelect && quickTeamLeaderList.length === 0 && acceptWorkForm.teamLeaderName && !teamLeaderLoading">
  452. <div>未找到匹配的人员</div>
  453. </div>
  454. <div class="quick-select-dropdown no-data" v-show="showTeamLeaderQuickSelect && teamLeaderLoading">
  455. <div>
  456. <i class="el-icon-loading"></i>
  457. 搜索中...
  458. </div>
  459. </div>
  460. </el-form-item>
  461. </el-col>
  462. </el-row>
  463. </el-form>
  464. <template #footer>
  465. <div class="dialog-footer">
  466. <el-button @click="acceptWorkDialogVisible = false">取 消</el-button>
  467. <el-button type="primary" @click="submitAcceptWork">确认接单</el-button>
  468. </div>
  469. </template>
  470. </el-dialog>
  471. <!-- 结单对话框 (维修工单) -->
  472. <el-dialog title="结单" v-model="finalizeRepairDialogVisible" width="800px" append-to-body>
  473. <el-alert type="info" :closable="false" style="border-color: #14b8a6; background-color: #f0fdfa; color: #0d9488; height: 35px;">
  474. <template #default>
  475. <i class="fa fa-file-text-o mr-2" style="color: #0d9488;"> 请选择信息录入方式,并上传相关附件完成结单。</i>
  476. </template>
  477. </el-alert>
  478. <el-form ref="finalizeRepairFormRef" :model="finalizeRepairForm" :rules="finalizeRepairRules" label-width="120px" label-position="top">
  479. <el-row>
  480. <el-col :span="12">
  481. <el-form-item label="工单编码"><el-input v-model="finalizeRepairForm.workOrderProjectNo" disabled /></el-form-item>
  482. </el-col>
  483. <el-col :span="12">
  484. <el-form-item label="风机编号"><el-input v-model="finalizeRepairForm.pcsDeviceName" disabled /></el-form-item>
  485. </el-col>
  486. <el-col :span="12">
  487. <el-form-item label="工单状态">
  488. <el-select v-model="finalizeRepairForm.workOrderStatus" style="width: 100%" disabled>
  489. <el-option
  490. v-for="dict in gxt_work_order_status"
  491. :key="dict.value"
  492. :label="dict.label"
  493. :value="dict.value"
  494. />
  495. </el-select>
  496. </el-form-item>
  497. </el-col>
  498. <el-col :span="12">
  499. <el-form-item label="维保中心"><el-input v-model="finalizeRepairForm.gxtCenter" disabled /> </el-form-item>
  500. </el-col>
  501. <el-col :span="12">
  502. <el-form-item label="场站"><el-input v-model="finalizeRepairForm.pcsStationName" disabled /> </el-form-item>
  503. </el-col>
  504. <el-col :span="12">
  505. <el-form-item label="品牌"><el-input v-model="finalizeRepairForm.brand" disabled /> </el-form-item>
  506. </el-col>
  507. <el-col :span="12">
  508. <el-form-item label="故障代码"><el-input v-model="finalizeRepairForm.faultCode" disabled /> </el-form-item>
  509. </el-col>
  510. <el-col :span="24">
  511. <el-form-item label="故障信息">
  512. <el-input
  513. v-model="finalizeRepairForm.faultBarcode"
  514. type="textarea"
  515. placeholder="请输入故障信息"
  516. maxlength="100"
  517. show-word-limit
  518. :rows="3"
  519. disabled
  520. />
  521. </el-form-item>
  522. </el-col>
  523. <el-col :span="12">
  524. <el-form-item label="下发人"><el-input v-model="finalizeRepairForm.assignUserName" disabled /> </el-form-item>
  525. </el-col>
  526. <el-col :span="12">
  527. <el-form-item label="下发时间"><el-input v-model="finalizeRepairForm.assignTime" disabled /> </el-form-item>
  528. </el-col>
  529. <el-col :span="12">
  530. <el-form-item label="接单人"><el-input v-model="finalizeRepairForm.acceptUserName" disabled /> </el-form-item>
  531. </el-col>
  532. <el-col :span="12">
  533. <el-form-item label="接单时间"><el-input v-model="finalizeRepairForm.acceptTime" disabled /> </el-form-item>
  534. </el-col>
  535. <el-col :span="12">
  536. <el-form-item label="工作负责人"><el-input v-model="finalizeRepairForm.teamLeaderName" disabled /> </el-form-item>
  537. </el-col>
  538. <!-- <el-col :span="12">-->
  539. <!-- <el-form-item label="维修方式" prop="repairMethod">-->
  540. <!-- <el-select-->
  541. <!-- v-model="finalizeRepairForm.repairMethod"-->
  542. <!-- placeholder="请选择维修方式"-->
  543. <!-- style="width: 100%"-->
  544. <!-- @change="handleRepairMethodChange"-->
  545. <!-- >-->
  546. <!-- <el-option-->
  547. <!-- v-for="dict in gxt_repair_method"-->
  548. <!-- :key="dict.value"-->
  549. <!-- :label="dict.label"-->
  550. <!-- :value="dict.value"-->
  551. <!-- />-->
  552. <!-- </el-select>-->
  553. <!-- </el-form-item>-->
  554. <!-- </el-col>-->
  555. </el-row>
  556. <el-row>
  557. <el-col :span="12">
  558. <el-form-item label="信息录入" prop="infoEntry">
  559. <el-radio-group v-model="finalizeRepairForm.infoEntry" @change="handleInfoEntryChange">
  560. <el-radio
  561. v-for="dict in gxt_info_entry"
  562. :key="dict.value"
  563. :label="dict.value"
  564. >
  565. {{ dict.label }}
  566. </el-radio>
  567. </el-radio-group>
  568. </el-form-item>
  569. </el-col>
  570. <!-- 正常维修时显示的字段 -->
  571. <!-- <template v-if="!finalizeRepairForm.repairMethod || finalizeRepairForm.repairMethod === '1'">-->
  572. <el-col :span="12" v-if="finalizeRepairForm.infoEntry == 1">
  573. <el-form-item label="MIS工单编码" prop="misOrderNo">
  574. <el-input
  575. v-model="finalizeRepairForm.misOrderNo"
  576. placeholder="请输入MIS工单编码或点击搜索选择"
  577. clearable
  578. @focus="handleMisNoInputFocus"
  579. @blur="handleMisNoInputBlur"
  580. @input="handleMisNoInput"
  581. @clear="handleMisNoClear"
  582. >
  583. <template #append>
  584. <el-button @click="handleSelectMisInfo" icon="Search"></el-button>
  585. </template>
  586. </el-input>
  587. <!-- 快速检索下拉框 -->
  588. <div class="quick-select-dropdown" v-show="showMisNoQuickSelect && quickMisNoList.length > 0">
  589. <div
  590. v-for="item in quickMisNoList"
  591. :key="item.misNo"
  592. class="quick-select-item"
  593. @click="handleMisNoQuickSelect(item)">
  594. <span class="mis-no">{{ item.misNo }}</span>
  595. </div>
  596. </div>
  597. <div class="quick-select-dropdown no-data" v-show="showMisNoQuickSelect && quickMisNoList.length === 0 && finalizeRepairForm.misOrderNo && !misNoLoading">
  598. <div>未找到匹配的MIS工单</div>
  599. </div>
  600. <div class="quick-select-dropdown no-data" v-show="showMisNoQuickSelect && misNoLoading">
  601. <div>
  602. <i class="el-icon-loading"></i>
  603. 搜索中...
  604. </div>
  605. </div>
  606. </el-form-item>
  607. </el-col>
  608. <el-col :span="12" v-if="finalizeRepairForm.infoEntry == 2">
  609. <el-form-item label="工作票编号" prop="workPermitNum">
  610. <el-input v-model="workPermitNumProxy" maxlength="20" show-word-limit />
  611. </el-form-item>
  612. </el-col>
  613. <el-col :span="12">
  614. <el-form-item label="开始时间" prop="realStartTime">
  615. <el-date-picker
  616. v-model="finalizeRepairForm.realStartTime"
  617. type="datetime"
  618. format="YYYY-MM-DD HH:mm"
  619. value-format="YYYY-MM-DD HH:mm"
  620. placeholder="请选择开始时间"
  621. style="width: 100%"
  622. :readonly="finalizeRepairForm.infoEntry == 1"
  623. :disabled-date="disabledStartDate"
  624. />
  625. </el-form-item>
  626. </el-col>
  627. <el-col :span="12">
  628. <el-form-item label="工作部位" prop="workArea">
  629. <el-select
  630. v-model="finalizeRepairForm.workArea"
  631. multiple
  632. placeholder="请选择工作部位"
  633. style="width: 100%"
  634. >
  635. <el-option
  636. v-for="dict in gxt_work_area"
  637. :key="dict.value"
  638. :label="dict.label"
  639. :value="dict.value"
  640. />
  641. </el-select>
  642. </el-form-item>
  643. </el-col>
  644. <!-- <el-col :span="12">-->
  645. <!-- <el-form-item label="开始时间" prop="realStartTime">-->
  646. <!-- <el-date-picker-->
  647. <!-- v-model="finalizeRepairForm.realStartTime"-->
  648. <!-- type="datetime"-->
  649. <!-- format="YYYY-MM-DD HH:mm"-->
  650. <!-- value-format="YYYY-MM-DD HH:mm"-->
  651. <!-- placeholder="请选择开始时间"-->
  652. <!-- style="width: 100%"-->
  653. <!-- :disabled="getMisDataConfig === '1'"-->
  654. <!-- readonly-->
  655. <!-- />-->
  656. <!-- </el-form-item>-->
  657. <!-- </el-col>-->
  658. <el-col :span="12">
  659. <el-form-item label="结束时间" prop="realEndTime">
  660. <el-date-picker
  661. v-model="finalizeRepairForm.realEndTime"
  662. type="datetime"
  663. format="YYYY-MM-DD HH:mm"
  664. value-format="YYYY-MM-DD HH:mm"
  665. placeholder="请选择结束时间"
  666. style="width: 100%"
  667. :readonly="finalizeRepairForm.infoEntry == 1"
  668. :disabled-date="disabledEndDate"
  669. />
  670. </el-form-item>
  671. </el-col>
  672. <el-col :span="12">
  673. <el-form-item label="检修人员" prop="workGroupMemberName">
  674. <el-input
  675. v-model="finalizeRepairForm.workGroupMemberName"
  676. placeholder="请输入检修人员"
  677. maxlength="200"
  678. show-word-limit
  679. :readonly="finalizeRepairForm.infoEntry == 1"
  680. />
  681. </el-form-item>
  682. </el-col>
  683. <!-- </template>-->
  684. <!-- &lt;!&ndash; 复位启机时显示的字段 &ndash;&gt;-->
  685. <!-- <template v-else-if="finalizeRepairForm.repairMethod === '2'">-->
  686. <!-- <el-col :span="12">-->
  687. <!-- <el-form-item label="复位方式" prop="resetMethod">-->
  688. <!-- <el-select-->
  689. <!-- v-model="finalizeRepairForm.resetMethod"-->
  690. <!-- placeholder="请选择复位方式"-->
  691. <!-- style="width: 100%"-->
  692. <!-- >-->
  693. <!-- <el-option-->
  694. <!-- v-for="dict in gxt_reset_method"-->
  695. <!-- :key="dict.value"-->
  696. <!-- :label="dict.label"-->
  697. <!-- :value="dict.value"-->
  698. <!-- />-->
  699. <!-- </el-select>-->
  700. <!-- </el-form-item>-->
  701. <!-- </el-col>-->
  702. <!-- </template>-->
  703. <!-- <el-col :span="24">-->
  704. <!-- <el-form-item label="维修总结" prop="finalizationRemark">-->
  705. <!-- <el-input-->
  706. <!-- v-model="finalizeRepairForm.finalizationRemark"-->
  707. <!-- type="textarea"-->
  708. <!-- placeholder="请输入维修总结"-->
  709. <!-- maxlength="500"-->
  710. <!-- show-word-limit-->
  711. <!-- :rows="3"-->
  712. <!-- />-->
  713. <!-- </el-form-item>-->
  714. <!-- </el-col>-->
  715. <el-col :span="24">
  716. <el-form-item label="真实故障原因" prop="realContent">
  717. <el-input v-model="finalizeRepairForm.realFailureReason"
  718. type="textarea"
  719. placeholder="请输入真实故障原因,最多500字"
  720. maxlength="500"
  721. :rows="5"
  722. show-word-limit />
  723. </el-form-item>
  724. </el-col>
  725. <el-col :span="24">
  726. <el-form-item label="附件(可选)">
  727. <preview :limit="8" v-model="finalizeRepairForm.attachmentUrls" :filesize="5"></preview>
  728. </el-form-item>
  729. </el-col>
  730. </el-row>
  731. </el-form>
  732. <template #footer>
  733. <div class="dialog-footer">
  734. <el-button @click="finalizeRepairDialogVisible = false">取 消</el-button>
  735. <el-button type="primary" @click="submitFinalizeRepair">确认结单</el-button>
  736. </div>
  737. </template>
  738. </el-dialog>
  739. <!-- 结单对话框 (维保工单) -->
  740. <el-dialog title="结单" v-model="finalizeWorkDialogVisible" width="800px" append-to-body>
  741. <el-alert type="info" :closable="false" style="border-color: #14b8a6; background-color: #f0fdfa; color: #0d9488; height: 35px;">
  742. <template #default>
  743. <i class="fa fa-file-text-o mr-2" style="color: #0d9488;"> 请上传相关附件完成结单。</i>
  744. </template>
  745. </el-alert>
  746. <el-form ref="finalizeWorkFormRef" :model="finalizeWorkForm" :rules="finalizeWorkRules" label-width="120px" label-position="top">
  747. <el-row>
  748. <el-col :span="12">
  749. <el-form-item label="工单编码"><el-input v-model="finalizeWorkForm.workOrderProjectNo" disabled /></el-form-item>
  750. </el-col>
  751. <el-col :span="12">
  752. <el-form-item label="风机编号"><el-input v-model="finalizeWorkForm.pcsDeviceName" disabled /></el-form-item>
  753. </el-col>
  754. <el-col :span="12">
  755. <el-form-item label="工单状态">
  756. <el-select v-model="finalizeWorkForm.workOrderStatus" style="width: 100%" disabled>
  757. <el-option
  758. v-for="dict in gxt_work_order_status"
  759. :key="dict.value"
  760. :label="dict.label"
  761. :value="dict.value"
  762. />
  763. </el-select>
  764. </el-form-item>
  765. </el-col>
  766. <el-col :span="12">
  767. <el-form-item label="维保中心"><el-input v-model="finalizeWorkForm.gxtCenter" disabled /> </el-form-item>
  768. </el-col>
  769. <el-col :span="12">
  770. <el-form-item label="场站"><el-input v-model="finalizeWorkForm.pcsStationName" disabled /> </el-form-item>
  771. </el-col>
  772. <el-col :span="12">
  773. <el-form-item label="品牌"><el-input v-model="finalizeWorkForm.brand" disabled /> </el-form-item>
  774. </el-col>
  775. <el-col :span="12">
  776. <el-form-item label="机型"><el-input v-model="finalizeWorkForm.model" disabled /> </el-form-item>
  777. </el-col>
  778. <el-col :span="12">
  779. <el-form-item label="MIS工单编码"><el-input v-model="finalizeWorkForm.misNo" disabled /></el-form-item>
  780. </el-col>
  781. <el-col :span="12">
  782. <el-form-item label="接单人"><el-input v-model="finalizeWorkForm.acceptUserName" disabled /> </el-form-item>
  783. </el-col>
  784. <el-col :span="12">
  785. <el-form-item label="接单时间"><el-input v-model="finalizeWorkForm.acceptTime" disabled /> </el-form-item>
  786. </el-col>
  787. <el-col :span="12">
  788. <el-form-item label="开始时间" prop="realStartTime">
  789. <el-date-picker
  790. v-model="finalizeWorkForm.realStartTime"
  791. type="datetime"
  792. format="YYYY-MM-DD HH:mm"
  793. value-format="YYYY-MM-DD HH:mm"
  794. placeholder="请选择开始时间"
  795. style="width: 100%"
  796. readonly
  797. />
  798. </el-form-item>
  799. </el-col>
  800. <el-col :span="12">
  801. <el-form-item label="结束时间" prop="realEndTime">
  802. <el-date-picker
  803. v-model="finalizeWorkForm.realEndTime"
  804. type="datetime"
  805. format="YYYY-MM-DD HH:mm"
  806. value-format="YYYY-MM-DD HH:mm"
  807. placeholder="请选择结束时间"
  808. style="width: 100%"
  809. readonly
  810. />
  811. </el-form-item>
  812. </el-col>
  813. <el-col :span="24">
  814. <el-form-item label="维保内容" prop="content">
  815. <el-input v-model="finalizeWorkForm.content" type="textarea" :rows="3" disabled />
  816. </el-form-item>
  817. </el-col>
  818. <el-col :span="12">
  819. <el-form-item label="工作负责人">
  820. <el-input v-model="finalizeWorkForm.teamLeaderName" disabled />
  821. </el-form-item>
  822. </el-col>
  823. <el-col :span="24">
  824. <el-form-item label="检修人员">
  825. <el-input v-model="finalizeWorkForm.workGroupMemberName" readonly />
  826. </el-form-item>
  827. </el-col>
  828. <el-col :span="24">
  829. <el-form-item label="附件(可选)">
  830. <preview :limit="8" v-model="finalizeWorkForm.attachmentUrls" :filesize="5"></preview>
  831. </el-form-item>
  832. </el-col>
  833. </el-row>
  834. </el-form>
  835. <template #footer>
  836. <div class="dialog-footer">
  837. <el-button @click="finalizeWorkDialogVisible = false">取 消</el-button>
  838. <el-button type="primary" @click="submitFinalizeWork">确认结单</el-button>
  839. </div>
  840. </template>
  841. </el-dialog>
  842. <!-- 审批对话框 (维修工单) -->
  843. <ApproveRepairDialog
  844. v-model="approveRepairDialogVisible"
  845. :data="approveRepairForm"
  846. :work-order-status-options="gxt_work_order_status"
  847. :suspend-reason-options="gxt_order_suspend_reason"
  848. :on-submit="submitApproveFromParent"
  849. @success="handleApproveSuccess"
  850. />
  851. <!-- 维保审批对话框组件 -->
  852. <ApproveDialog
  853. v-model="approveWorkDialogVisible"
  854. :data="approveWorkForm"
  855. :work-order-status-options="gxt_work_order_status"
  856. :suspend-reason-options="gxt_order_suspend_reason"
  857. :on-submit="submitApproveFromParent"
  858. @success="handleApproveSuccess"
  859. />
  860. <!-- 复运对话框 (维修工单) -->
  861. <el-dialog title="复运" v-model="restartRepairDialogVisible" width="800px" append-to-body>
  862. <el-alert type="info" :closable="false" style="border-color: #0ea5e9; background-color: #ecf7ff; color: #0369a1; height: 35px;">
  863. <template #default>
  864. <i class="fa fa-refresh mr-2" style="color: #0369a1;"> 请填写复运相关信息,完成工单复运。</i>
  865. </template>
  866. </el-alert>
  867. <h4 class="text-sm font-medium text-gray-800 mb-3"></h4>
  868. <el-form ref="restartRepairFormRef" :model="restartRepairForm" :rules="restartRepairRules" label-width="120px" label-position="top">
  869. <el-row>
  870. <el-col :span="12">
  871. <el-form-item label="工单编码"><el-input v-model="restartRepairForm.workOrderProjectNo" disabled /></el-form-item>
  872. </el-col>
  873. <el-col :span="12">
  874. <el-form-item label="风机编号"><el-input v-model="restartRepairForm.pcsDeviceName" disabled /></el-form-item>
  875. </el-col>
  876. <el-col :span="12">
  877. <el-form-item label="维保中心"><el-input v-model="restartRepairForm.gxtCenter" disabled /> </el-form-item>
  878. </el-col>
  879. <el-col :span="12">
  880. <el-form-item label="场站"><el-input v-model="restartRepairForm.pcsStationName" disabled /> </el-form-item>
  881. </el-col>
  882. <el-col :span="12">
  883. <el-form-item label="品牌"><el-input v-model="restartRepairForm.brand" disabled /> </el-form-item>
  884. </el-col>
  885. <el-col :span="12">
  886. <el-form-item label="发生时间"><el-input v-model="restartRepairForm.occurTime" disabled /> </el-form-item>
  887. </el-col>
  888. <el-col :span="12">
  889. <el-form-item label="MIS工单编码"><el-input v-model="restartRepairForm.misOrderNo" disabled /> </el-form-item>
  890. </el-col>
  891. <el-col :span="12">
  892. <el-form-item label="恢复运行时间" prop="restartTime">
  893. <el-date-picker
  894. v-model="restartRepairForm.restartTime"
  895. type="datetime"
  896. format="YYYY-MM-DD HH:mm"
  897. value-format="YYYY-MM-DD HH:mm"
  898. placeholder="请选择恢复运行时间"
  899. style="width: 100%"
  900. />
  901. </el-form-item>
  902. </el-col>
  903. <el-col :span="12">
  904. <el-form-item label="损失电量(kWh)" prop="lostPower">
  905. <el-input-number
  906. v-model="restartRepairForm.lostPower"
  907. controls-position="right"
  908. style="width: 100%"
  909. class="input-number-left"
  910. :min="0"
  911. placeholder="请输入损失电量"
  912. />
  913. </el-form-item>
  914. </el-col>
  915. </el-row>
  916. </el-form>
  917. <template #footer>
  918. <div class="dialog-footer">
  919. <el-button @click="restartRepairDialogVisible = false">取 消</el-button>
  920. <el-button type="primary" @click="submitRestartRepair">确认复运</el-button>
  921. </div>
  922. </template>
  923. </el-dialog>
  924. <!-- 复运对话框 (维保工单) -->
  925. <el-dialog title="复运" v-model="restartWorkDialogVisible" width="800px" append-to-body>
  926. <el-alert type="info" :closable="false" style="border-color: #0ea5e9; background-color: #ecf7ff; color: #0369a1; height: 35px;">
  927. <template #default>
  928. <i class="fa fa-refresh mr-2" style="color: #0369a1;"> 请填写复运相关信息,完成工单复运。</i>
  929. </template>
  930. </el-alert>
  931. <h4 class="text-sm font-medium text-gray-800 mb-3"></h4>
  932. <el-form ref="restartWorkFormRef" :model="restartWorkForm" :rules="restartWorkRules" label-width="120px" label-position="top">
  933. <el-row>
  934. <el-col :span="12">
  935. <el-form-item label="工单编码"><el-input v-model="restartWorkForm.workOrderProjectNo" disabled /></el-form-item>
  936. </el-col>
  937. <el-col :span="12">
  938. <el-form-item label="风机编号"><el-input v-model="restartWorkForm.pcsDeviceName" disabled /></el-form-item>
  939. </el-col>
  940. <el-col :span="12">
  941. <el-form-item label="维保中心"><el-input v-model="restartWorkForm.gxtCenter" disabled /> </el-form-item>
  942. </el-col>
  943. <el-col :span="12">
  944. <el-form-item label="场站"><el-input v-model="restartWorkForm.pcsStationName" disabled /> </el-form-item>
  945. </el-col>
  946. <el-col :span="12">
  947. <el-form-item label="品牌"><el-input v-model="restartWorkForm.brand" disabled /> </el-form-item>
  948. </el-col>
  949. <el-col :span="12">
  950. <el-form-item label="机型"><el-input v-model="restartWorkForm.model" disabled /> </el-form-item>
  951. </el-col>
  952. <el-col :span="12">
  953. <el-form-item label="MIS工单编码"><el-input v-model="restartWorkForm.misNo" disabled /></el-form-item>
  954. </el-col>
  955. <el-col :span="12">
  956. <el-form-item label="恢复运行时间" prop="restartTime">
  957. <el-date-picker
  958. v-model="restartWorkForm.restartTime"
  959. type="datetime"
  960. format="YYYY-MM-DD HH:mm"
  961. value-format="YYYY-MM-DD HH:mm"
  962. placeholder="请选择恢复运行时间"
  963. style="width: 100%"
  964. />
  965. </el-form-item>
  966. </el-col>
  967. <el-col :span="12">
  968. <el-form-item label="损失电量(kWh)" prop="lostPower">
  969. <el-input-number
  970. v-model="restartWorkForm.lostPower"
  971. controls-position="right"
  972. style="width: 100%"
  973. class="input-number-left"
  974. :min="0"
  975. placeholder="请输入损失电量"
  976. />
  977. </el-form-item>
  978. </el-col>
  979. </el-row>
  980. </el-form>
  981. <template #footer>
  982. <div class="dialog-footer">
  983. <el-button @click="restartWorkDialogVisible = false">取 消</el-button>
  984. <el-button type="primary" @click="submitRestartWork">确认复运</el-button>
  985. </div>
  986. </template>
  987. </el-dialog>
  988. <!-- 维修工单下发对话框 -->
  989. <el-dialog title="下发" v-model="assignRepairDialogVisible" width="800px" append-to-body >
  990. <el-form ref="repairOrderRef" :model="assignRepairForm" :rules="assignRepairRules" label-width="120px" label-position="top">
  991. <el-row>
  992. <el-col :span="12">
  993. <el-form-item label="工单编码" prop="workOrderProjectNo" >
  994. <el-input v-model="assignRepairForm.workOrderProjectNo" placeholder="请输入工单编码" disabled readonly maxlength="50" show-word-limit v-chinese-limit/>
  995. </el-form-item>
  996. </el-col>
  997. <el-col :span="12">
  998. <el-form-item label="风机编号" prop="pcsDeviceName">
  999. <el-input v-model="assignRepairForm.pcsDeviceName" placeholder="请选择风机编号" readonly>
  1000. <template #append>
  1001. <el-button @click="handleSelectEquipment" icon="Search"></el-button>
  1002. </template>
  1003. </el-input>
  1004. </el-form-item>
  1005. </el-col>
  1006. </el-row>
  1007. <el-row>
  1008. <el-col :span="12">
  1009. <el-form-item label="维保中心" prop="gxtCenter">
  1010. <el-input v-model="assignRepairForm.gxtCenter" placeholder="请选择风机编号自动填充" readonly />
  1011. </el-form-item>
  1012. </el-col>
  1013. <el-col :span="12">
  1014. <el-form-item label="场站" prop="pcsStationName">
  1015. <el-input v-model="assignRepairForm.pcsStationName" placeholder="请选择风机编号自动填充" readonly />
  1016. </el-form-item>
  1017. </el-col>
  1018. </el-row>
  1019. <el-row>
  1020. <el-col :span="12">
  1021. <el-form-item label="品牌" prop="brand">
  1022. <el-input v-model="assignRepairForm.brand" placeholder="请选择风机编号自动填充" readonly />
  1023. </el-form-item>
  1024. </el-col>
  1025. <el-col :span="12">
  1026. <el-form-item label="机型" prop="model">
  1027. <el-input v-model="assignRepairForm.model" placeholder="请选择风机编号自动填充" readonly />
  1028. </el-form-item>
  1029. </el-col>
  1030. </el-row>
  1031. <el-row>
  1032. <el-col :span="12">
  1033. <el-form-item label="发生时间" prop="occurTime">
  1034. <el-date-picker
  1035. v-model="assignRepairForm.occurTime"
  1036. type="datetime"
  1037. format="YYYY-MM-DD HH:mm"
  1038. value-format="YYYY-MM-DD HH:mm"
  1039. placeholder="请选择发生时间"
  1040. style="width: 100%"
  1041. :disabled-date="disabledDate"
  1042. :disabled-time="disabledTime"
  1043. />
  1044. </el-form-item>
  1045. </el-col>
  1046. <el-col :span="12">
  1047. <el-form-item label="故障代码" prop="faultCode">
  1048. <el-input
  1049. v-model="assignRepairForm.faultCode"
  1050. placeholder="请输入故障代码"
  1051. maxlength="20"
  1052. show-word-limit
  1053. />
  1054. </el-form-item>
  1055. </el-col>
  1056. </el-row>
  1057. <el-row>
  1058. <el-col :span="24">
  1059. <el-form-item label="故障信息" prop="faultBarcode">
  1060. <el-input
  1061. v-model="assignRepairForm.faultBarcode"
  1062. type="textarea"
  1063. placeholder="请输入故障信息"
  1064. maxlength="100"
  1065. show-word-limit
  1066. :rows="3"
  1067. />
  1068. </el-form-item>
  1069. </el-col>
  1070. </el-row>
  1071. </el-form>
  1072. <template #footer>
  1073. <div class="dialog-footer">
  1074. <el-button @click="assignRepairDialogVisible = false">取 消</el-button>
  1075. <el-button type="primary" @click="submitFormAndIssue">确认下发</el-button>
  1076. </div>
  1077. </template>
  1078. </el-dialog>
  1079. <!-- 维保工单下发对话框 -->
  1080. <el-dialog title="下发" v-model="assignWorkDialogVisible" width="800px" append-to-body>
  1081. <div style="max-height: 500px; overflow-y: auto; padding-right: 10px;">
  1082. <el-form ref="workOrderRef" :model="assignWorkForm" :rules="assignWorkRules" label-width="120px" label-position="top">
  1083. <el-row :gutter="20">
  1084. <el-col :span="12">
  1085. <el-form-item label="工单编码" prop="workOrderProjectNo">
  1086. <el-input v-model="assignWorkForm.workOrderProjectNo" maxlength="50" show-word-limit v-chinese-limit readonly/>
  1087. </el-form-item>
  1088. </el-col>
  1089. <el-col :span="12">
  1090. <el-form-item label="风机编号" prop="pcsDeviceName">
  1091. <el-input v-model="assignWorkForm.pcsDeviceName" readonly>
  1092. <template #append>
  1093. <el-button @click="handleSelectEquipment" icon="Search"></el-button>
  1094. </template>
  1095. </el-input>
  1096. </el-form-item>
  1097. </el-col>
  1098. </el-row>
  1099. <el-row :gutter="20">
  1100. <el-col :span="12">
  1101. <el-form-item label="维保中心" prop="gxtCenter">
  1102. <el-input v-model="assignWorkForm.gxtCenter" readonly />
  1103. </el-form-item>
  1104. </el-col>
  1105. <el-col :span="12">
  1106. <el-form-item label="场站" prop="pcsStationName">
  1107. <el-input v-model="assignWorkForm.pcsStationName" readonly />
  1108. </el-form-item>
  1109. </el-col>
  1110. </el-row>
  1111. <el-row :gutter="20">
  1112. <el-col :span="12">
  1113. <el-form-item label="品牌" prop="brand">
  1114. <el-input v-model="assignWorkForm.brand" readonly />
  1115. </el-form-item>
  1116. </el-col>
  1117. <el-col :span="12">
  1118. <el-form-item label="机型" prop="model">
  1119. <el-input v-model="assignWorkForm.model" readonly />
  1120. </el-form-item>
  1121. </el-col>
  1122. </el-row>
  1123. <el-row :gutter="20">
  1124. <el-col :span="12">
  1125. <el-form-item label="MIS工单编码" prop="misNo">
  1126. <el-input v-model="assignWorkForm.misNo"
  1127. placeholder="请输入MIS工单编码或点击搜索选择"
  1128. clearable
  1129. @focus="handleMisNoInputFocus"
  1130. @blur="handleMisNoInputBlur"
  1131. @input="handleMisNoInput"
  1132. @clear="handleMisNoClear"
  1133. >
  1134. <template #append>
  1135. <el-button @click="handleSelectMisInfo" icon="Search"></el-button>
  1136. </template>
  1137. </el-input>
  1138. <!-- 快速检索下拉框 -->
  1139. <div class="quick-select-dropdown" v-show="showMisNoQuickSelect && quickMisNoList.length > 0">
  1140. <div
  1141. v-for="item in quickMisNoList"
  1142. :key="item.misNo"
  1143. class="quick-select-item"
  1144. @click="handleMisNoQuickSelect(item)">
  1145. <span class="mis-no">{{ item.misNo }}</span>
  1146. </div>
  1147. </div>
  1148. <div class="quick-select-dropdown no-data" v-show="showMisNoQuickSelect && quickMisNoList.length === 0 && assignWorkForm.misNo && !misNoLoading">
  1149. <div>未找到匹配的MIS工单</div>
  1150. </div>
  1151. <div class="quick-select-dropdown no-data" v-show="showMisNoQuickSelect && misNoLoading">
  1152. <div>
  1153. <i class="el-icon-loading"></i>
  1154. 搜索中...
  1155. </div>
  1156. </div>
  1157. </el-form-item>
  1158. </el-col>
  1159. </el-row>
  1160. <el-row :gutter="20">
  1161. <el-col :span="24">
  1162. <el-form-item label="维保内容" prop="content">
  1163. <el-input v-model="assignWorkForm.content" type="textarea" :rows="3" readonly />
  1164. </el-form-item>
  1165. </el-col>
  1166. </el-row>
  1167. </el-form>
  1168. </div>
  1169. <template #footer>
  1170. <div class="dialog-footer">
  1171. <el-button @click="assignWorkDialogVisible = false">取 消</el-button>
  1172. <el-button type="primary" @click="submitWorkFormAndIssue">确认下发</el-button>
  1173. </div>
  1174. </template>
  1175. </el-dialog>
  1176. <!-- MIS选择组件 -->
  1177. <MisInfoSelectSingle :key="commonKey" v-model="misInfoSelectVisible" @onSelected="onMisInfoSelected" :pcsStationName="finalizeFormData.pcsStationName || assignWorkForm.pcsStationName" :pcsDeviceName="finalizeFormData.pcsDeviceName || assignWorkForm.pcsDeviceName"></MisInfoSelectSingle>
  1178. <!-- 设备选择组件 -->
  1179. <equipment-select-single v-model="equipmentSelectVisible" @onSelected="onEquipmentSelected"></equipment-select-single>
  1180. <!-- 复启对话框组件 -->
  1181. <ResetDialog
  1182. v-model="resetDialogVisible"
  1183. :data="resetFormData"
  1184. :reset-method-options="gxt_reset_method"
  1185. :on-submit="submitResetFromParent"
  1186. @success="handleResetSuccess"
  1187. />
  1188. <!-- 维修结单对话框组件 -->
  1189. <FinalizeDialog
  1190. v-model="finalizeDialogVisible"
  1191. :data="finalizeFormData"
  1192. :work-order-status-options="gxt_work_order_status"
  1193. :info-entry-options="gxt_info_entry"
  1194. :work-area-options="gxt_work_area"
  1195. :on-submit="submitFinalizeFromParent"
  1196. :list-repair-order="listRepairOrder"
  1197. :list-work-person="listWorkPerson"
  1198. :list-mis-info="listMisInfo"
  1199. :list-user-data="listUserData"
  1200. @success="handleFinalizeSuccess"
  1201. @select-mis-info="handleSelectMisInfo"
  1202. >
  1203. <!-- <template #mis-info-select>-->
  1204. <!-- <MisInfoSelectSingle :key="commonKey" v-model="misInfoSelectVisible" @onSelected="onMisInfoSelected" :pcsStationName="finalizeFormData.pcsStationName" :pcsDeviceName="finalizeFormData.pcsDeviceName"></MisInfoSelectSingle>-->
  1205. <!-- </template>-->
  1206. </FinalizeDialog>
  1207. <!-- 退回对话框 -->
  1208. <ReturnDialog
  1209. v-model="returnDialogVisible"
  1210. :data="returnForm"
  1211. :work-order-status-options="gxt_work_order_status"
  1212. :return-type-options="returnForm.workOrderStatus == 'assigned' ? gxt_accept_return_reason : gxt_return_type "
  1213. :on-submit="submitReturnFromParent"
  1214. @success="handleReturnSuccess"
  1215. />
  1216. <!-- 维保结单对话框组件 -->
  1217. <FinishDialog
  1218. v-model="finishDialogVisible"
  1219. :data="finishForm"
  1220. :work-order-status-options="gxt_work_order_status"
  1221. :info-entry-options="gxt_info_entry"
  1222. :list-gxt-order="listGxtOrder"
  1223. :list-work-person="listWorkPerson"
  1224. :list-mis-info="listMisInfo"
  1225. :list-user-data="listUserData"
  1226. :on-submit="submitFinishFromParent"
  1227. @success="handleFinishSuccess"
  1228. />
  1229. <!-- 维修挂起对话框 -->
  1230. <SuspendDialog
  1231. v-model="suspendRepairDialogVisible"
  1232. :data="suspendForm"
  1233. :suspend-reason-options="gxt_order_suspend_reason"
  1234. :on-submit="submitSuspendFromParent"
  1235. @success="handleSuspendSuccess"
  1236. />
  1237. <!-- 维保挂起对话框 -->
  1238. <SuspendWorkDialog
  1239. v-model="suspendDialogVisible"
  1240. :data="suspendForm"
  1241. :suspend-reason-options="gxt_order_suspend_reason"
  1242. :on-submit="submitSuspendFromParent"
  1243. @success="handleSuspendSuccess"
  1244. />
  1245. </div>
  1246. </template>
  1247. <script setup>
  1248. import { getCurrentInstance, reactive, ref, toRefs, onMounted } from "vue";
  1249. import {
  1250. getOrderInfo,
  1251. listMyTodo,
  1252. // 使用现有的API接口
  1253. acceptRepairOrder,
  1254. acceptWorkOrder,
  1255. // finalizeRepairOrder,
  1256. finalizeWorkOrder,
  1257. approveRepairOrder,
  1258. restartRepairOrder,
  1259. restartWorkOrder,
  1260. listMyRate,
  1261. } from "@/api/gxt/orderMine.js";
  1262. import {listUserNoPermi, listLeader, listUserData} from "@/api/system/user.js";
  1263. import { listEquipment,listMaintenanceCenters, listStationsByMaintenanceCenter } from "@/api/gxt/equipment.js";
  1264. import { listMisInfo, listWorkPerson } from "@/api/gxt/misInfo.js";
  1265. import preview from '@/components/FileUpload/preview.vue'
  1266. import MisInfoSelectSingle from "@/components/misInfoSelect/single.vue";
  1267. import useUserStore from '@/store/modules/user'
  1268. import {
  1269. listRepairOrder,updateRepairOrder,finalizeRepairOrder,getRepairOrder,returnRepairOrder,suspendRepairOrder, approveSuspendRepairOrder
  1270. } from "@/api/gxt/repairOrder";
  1271. import ResetDialog from '@/components/repairOrder/reset.vue'
  1272. import {
  1273. listGxtOrder,
  1274. updateGxtOrder,
  1275. completeWorkOrder,
  1276. getGxtOrder,
  1277. suspendWorkOrder,
  1278. approveWorkOrder
  1279. } from "@/api/gxt/gxtOrder"
  1280. import EquipmentSelectSingle from "@/components/equipmentSelect/single.vue"
  1281. import FinalizeDialog from "@/components/repairOrder/finalize.vue";
  1282. import ReturnDialog from "@/components/repairOrder/return.vue";
  1283. import FinishDialog from "@/components/gxtOrder/finalize.vue";
  1284. import SuspendDialog from "@/components/repairOrder/suspend.vue";
  1285. import SuspendWorkDialog from "@/components/gxtOrder/suspend.vue";
  1286. import ViewDialog from "@/components/repairOrder/view.vue";
  1287. import ViewWorkOrderDialog from "@/components/gxtOrder/view.vue";
  1288. import ApproveRepairDialog from "@/components/repairOrder/approve.vue";
  1289. import ApproveDialog from "@/components/gxtOrder/approve.vue";
  1290. const { proxy } = getCurrentInstance();
  1291. const userStore = useUserStore();
  1292. // 显示搜索栏
  1293. const showSearch = ref(true);
  1294. // 加载状态
  1295. const loading = ref(false);
  1296. // 表格高度
  1297. const tableHeight = ref(window.innerHeight - 300);
  1298. // 数据总数
  1299. const total = ref(0);
  1300. // 维修工单详情对话框可见性
  1301. const repairDetailDialogVisible = ref(false);
  1302. // 维保工单详情对话框可见性
  1303. const workDetailDialogVisible = ref(false);
  1304. // 接单对话框可见性
  1305. const acceptRepairDialogVisible = ref(false);
  1306. const acceptWorkDialogVisible = ref(false);
  1307. // 结单对话框可见性
  1308. const finalizeRepairDialogVisible = ref(false);
  1309. const finalizeWorkDialogVisible = ref(false);
  1310. // 维修结单组件对话框可见性
  1311. const finalizeDialogVisible = ref(false)
  1312. // 维保结单组件对话框可见性
  1313. const finishDialogVisible = ref(false)
  1314. // 审批对话框可见性
  1315. const approveRepairDialogVisible = ref(false);
  1316. const approveWorkDialogVisible = ref(false);
  1317. // 复运对话框可见性
  1318. const restartRepairDialogVisible = ref(false);
  1319. const restartWorkDialogVisible = ref(false);
  1320. // 复启对话框可见性
  1321. const resetDialogVisible = ref(false);
  1322. // 下发对话框可见性
  1323. const assignRepairDialogVisible = ref(false);
  1324. const assignWorkDialogVisible = ref(false);
  1325. // 退回
  1326. const returnDialogVisible = ref(false)
  1327. // 维修挂起
  1328. const suspendRepairDialogVisible = ref(false)
  1329. // 维保挂起
  1330. const suspendDialogVisible = ref(false)
  1331. // 维保中心选项
  1332. const maintenanceCenterOptions = ref([]);
  1333. // 场站选项
  1334. const stationOptions = ref([]);
  1335. // 工单列表
  1336. const orderList = ref([]);
  1337. // 详情数据
  1338. const detailData = ref({});
  1339. // 工单流转记录
  1340. const flowList = ref([]);
  1341. // 接单表单数据
  1342. const acceptRepairForm = ref({});
  1343. const acceptWorkForm = ref({});
  1344. // 结单表单数据
  1345. const finalizeRepairForm = ref({workArea: []});
  1346. const finalizeWorkForm = ref({});
  1347. // 维保结单表单数据
  1348. const finishForm = ref({})
  1349. // 控制结单表单中字段是否可编辑
  1350. const getMisDataConfig = ref("0"); // 默认值为"0",表示可以手动输入
  1351. // 审批表单数据
  1352. const approveRepairForm = ref({});
  1353. const approveWorkForm = ref({});
  1354. // 复运表单数据
  1355. const restartRepairForm = ref({});
  1356. const restartWorkForm = ref({});
  1357. // 复启表单数据
  1358. const resetFormData = ref({});
  1359. // 下发表单数据
  1360. const assignRepairForm = ref({});
  1361. const assignWorkForm = ref({});
  1362. // 退回表单
  1363. const returnForm = ref({})
  1364. // 挂起表单
  1365. const suspendForm = ref({})
  1366. // 工作负责人快速检索相关响应式数据
  1367. const showTeamLeaderQuickSelect = ref(false);
  1368. const quickTeamLeaderList = ref([]);
  1369. const teamLeaderLoading = ref(false);
  1370. const teamLeaderSearchTimer = ref(null);
  1371. const allUserList = ref([]); // 存储所有用户数据用于快速检索
  1372. const lastLoadedCenterId = ref(null); // Track last loaded maintenance center ID
  1373. // MIS工单快速检索相关响应式数据
  1374. const showMisNoQuickSelect = ref(false);
  1375. const quickMisNoList = ref([]);
  1376. const allMisNoList = ref([]); // 存储所有MIS工单数据用于快速检索
  1377. const misNoLoading = ref(false);
  1378. const misNoSearchTimer = ref(null);
  1379. const misInfoSelectVisible = ref(false);
  1380. const equipmentSelectVisible = ref(false)
  1381. let commonKey = 0;
  1382. // 查询参数
  1383. const data = reactive({
  1384. queryParams: {
  1385. pageNum: 1,
  1386. pageSize: 10,
  1387. workOrderProjectNo: undefined,
  1388. workOrderStatus: undefined,
  1389. gxtCenter: undefined,
  1390. pcsStationName: undefined,
  1391. pcsDeviceName: undefined
  1392. }
  1393. });
  1394. const { queryParams } = toRefs(data);
  1395. // 获取字典数据
  1396. const {
  1397. gxt_maintenance_type,
  1398. gxt_work_order_status,
  1399. gxt_order_priority_type,
  1400. gxt_repair_order_flow_action_type,
  1401. gxt_order_suspend_reason,
  1402. gxt_inspection_type,
  1403. gxt_pause_reasons,
  1404. gxt_repair_method,
  1405. gxt_reset_method,
  1406. gxt_info_entry,
  1407. gxt_work_area,
  1408. gxt_return_type,
  1409. gxt_accept_return_reason
  1410. } = proxy.useDict(
  1411. "gxt_maintenance_type",
  1412. "gxt_work_order_status",
  1413. "gxt_order_priority_type",
  1414. "gxt_repair_order_flow_action_type",
  1415. "gxt_order_suspend_reason",
  1416. "gxt_inspection_type",
  1417. "gxt_pause_reasons",
  1418. "gxt_repair_method",
  1419. "gxt_reset_method",
  1420. "gxt_info_entry",
  1421. "gxt_work_area",
  1422. "gxt_return_type",
  1423. "gxt_accept_return_reason"
  1424. );
  1425. // 表单验证规则
  1426. const acceptRepairRules = ref({
  1427. teamLeaderId: [{ required: true, message: "请选择工作负责人", trigger: "change" }]
  1428. });
  1429. const acceptWorkRules = ref({
  1430. teamLeaderId: [{ required: true, message: "请选择工作负责人", trigger: "change" }]
  1431. });
  1432. const finalizeRepairRules = ref({
  1433. misOrderNo: [
  1434. { required: true, message: "MIS工单编码不能为空", trigger: "blur" }
  1435. ],
  1436. realStartTime: [
  1437. { required: true, message: "请选择开始时间", trigger: "change" },
  1438. {
  1439. validator: (rule, value, callback) => {
  1440. if (value && new Date(value) > new Date() && finalizeRepairForm.value.infoEntry == '2') {
  1441. callback(new Error('开始时间不能大于当前时间'));
  1442. } else if(value && new Date(value) < new Date(finalizeRepairForm.value.acceptTime) && finalizeRepairForm.value.infoEntry == '2') {
  1443. callback(new Error('开始时间不能小于接单时间'));
  1444. } else {
  1445. callback();
  1446. }
  1447. },
  1448. trigger: 'change'
  1449. }
  1450. ],
  1451. realEndTime: [
  1452. { required: true, message: "请选择结束时间", trigger: "change" },
  1453. {
  1454. validator: (rule, value, callback) => {
  1455. if (value && new Date(value) > new Date() && finalizeRepairForm.value.infoEntry == '2') {
  1456. callback(new Error('结束时间不能大于当前时间'));
  1457. } else if(value && new Date(value) < new Date(finalizeRepairForm.value.realStartTime) && finalizeRepairForm.value.infoEntry == '2') {
  1458. callback(new Error('结束时间不能小于开始时间'));
  1459. } else {
  1460. callback();
  1461. }
  1462. },
  1463. trigger: 'change'
  1464. }
  1465. ],
  1466. workGroupMemberName: [
  1467. { required: false, message: "请输入检修人员", trigger: "blur" },
  1468. {
  1469. validator: async (rule, value, callback) => {
  1470. // 如果值为空、关联MIS,直接通过验证
  1471. if (!value || finalizeRepairForm.value.infoEntry == '1') {
  1472. return callback();
  1473. }
  1474. try {
  1475. // 将输入的检修人员姓名按逗号分割
  1476. const names = value.split(',').map(name => name.trim());
  1477. // 验证每个检修人员是否存在于组织架构中
  1478. for (const name of names) {
  1479. debugger
  1480. if (name.length > 0) {
  1481. const response = await listUserData({nickName: name});
  1482. if (!response.rows || response.rows.length === 0) {
  1483. return callback(new Error(`检修人员"${name}"非系统内人员,请重新输入`));
  1484. }
  1485. } else {
  1486. return callback(new Error(`请正确输入检修人员名单`));
  1487. }
  1488. }
  1489. callback();
  1490. } catch (error) {
  1491. callback(new Error('验证检修人员时发生错误'));
  1492. }
  1493. },
  1494. trigger: 'blur'
  1495. }
  1496. ],
  1497. workArea: [
  1498. { required: true, message: "请选择工作部位", trigger: "change" }
  1499. ],
  1500. workPermitNum: [
  1501. { required: true, message: "工作票编号不能为空", trigger: "blur" },
  1502. {
  1503. validator: (rule, value, callback) => {
  1504. if (finalizeRepairForm.value.infoEntry == '2') {
  1505. if (!value) {
  1506. callback(new Error('工作票编号不能为空'))
  1507. } else if (!/^[a-zA-Z0-9_\-\.]*$/.test(value)) {
  1508. callback(new Error('仅支持英文、数字、下划线'))
  1509. } else if (value.length > 20) {
  1510. callback(new Error('不能超过20个字符'))
  1511. } else {
  1512. // 验证唯一性
  1513. if (value) {
  1514. listRepairOrder({pageNum: 1, pageSize: 10, workPermitNum: value}).then(response => {
  1515. const gxtOrders = response.rows
  1516. if (gxtOrders.length > 0) {
  1517. if (gxtOrders[0].id != finalizeRepairForm.value.id) {
  1518. callback(new Error('工作票编号已存在!'))
  1519. } else {
  1520. callback()
  1521. }
  1522. } else {
  1523. callback()
  1524. }
  1525. })
  1526. } else {
  1527. callback()
  1528. }
  1529. }
  1530. } else {
  1531. callback()
  1532. }
  1533. },
  1534. trigger: 'blur'
  1535. }
  1536. ]
  1537. });
  1538. const finalizeWorkRules = ref({
  1539. realContent: [
  1540. { required: true, message: "请输入实际维保内容", trigger: "blur" }
  1541. ]
  1542. });
  1543. const approveRepairRules = ref({
  1544. /*rejectionReason: [
  1545. { required: true, message: "请输入审批意见", trigger: "blur" }
  1546. ]*/
  1547. });
  1548. const approveWorkRules = ref({
  1549. rejectionReason: [
  1550. { required: true, message: "请输入审批意见", trigger: "blur" }
  1551. ]
  1552. });
  1553. // 复运表单验证规则
  1554. const restartRepairRules = ref({
  1555. lostPower: [
  1556. { required: true, message: "损失电量不能为空", trigger: "change" }
  1557. ],
  1558. restartTime: [
  1559. { required: true, message: "请选择恢复运行时间", trigger: "change" },
  1560. {
  1561. validator: (rule, value, callback) => {
  1562. if (value && new Date(value) > new Date()) {
  1563. callback(new Error('恢复运行时间不能大于当前时间'));
  1564. // } else if(value && new Date(value) < new Date(restartRepairForm.value.realEndTime)) {
  1565. // callback(new Error('恢复运行时间不能小于结束时间'));
  1566. } else {
  1567. callback();
  1568. }
  1569. },
  1570. trigger: 'change'
  1571. }
  1572. ]
  1573. });
  1574. const restartWorkRules = ref({
  1575. lostPower: [
  1576. { required: true, message: "损失电量不能为空", trigger: "change" }
  1577. ],
  1578. restartTime: [
  1579. { required: true, message: "请选择恢复运行时间", trigger: "change" },
  1580. {
  1581. validator: (rule, value, callback) => {
  1582. if (value && new Date(value) > new Date()) {
  1583. callback(new Error('恢复运行时间不能大于当前时间'));
  1584. // } else if(value && new Date(value) < new Date(restartWorkForm.value.realEndTime)) {
  1585. // callback(new Error('恢复运行时间不能小于结束时间'));
  1586. } else {
  1587. callback();
  1588. }
  1589. },
  1590. trigger: 'change'
  1591. }
  1592. ]
  1593. });
  1594. const assignRepairRules = ref({
  1595. workOrderProjectNo: [
  1596. { required: true, message: "工单编码不能为空", trigger: "blur" }
  1597. ],
  1598. pcsDeviceName: [
  1599. { required: true, message: "风机编号不能为空", trigger: "blur" }
  1600. ],
  1601. occurTime: [
  1602. { required: true, message: "请选择发生时间", trigger: "change" },
  1603. {
  1604. validator: (rule, value, callback) => {
  1605. if (value && new Date(value) > new Date()) {
  1606. callback(new Error('发生时间不能大于当前时间'));
  1607. } else {
  1608. callback();
  1609. }
  1610. },
  1611. trigger: 'change'
  1612. }
  1613. ],
  1614. faultBarcode: [
  1615. { required: true, message: "故障信息不能为空", trigger: "blur" }
  1616. ],
  1617. });
  1618. const assignWorkRules = ref({
  1619. workOrderProjectNo: [{ required: true, message: "工单编码不能为空", trigger: "blur" }],
  1620. misNo: [{ required: true, message: "MIS编码不能为空", trigger: "blur" }],
  1621. pcsDeviceName: [{ required: true, message: "风机编号不能为空", trigger: "blur" }],
  1622. gxtCenter: [{ required: true, message: "维保中心不能为空", trigger: "blur" }],
  1623. pcsStationName: [{ required: true, message: "风电场不能为空", trigger: "blur" }]
  1624. });
  1625. // 页面加载时执行
  1626. onMounted(() => {
  1627. getList();
  1628. getMaintenanceCenterAndStationList();
  1629. window.addEventListener('resize', handleResize);
  1630. });
  1631. // 获取列表数据
  1632. function getList() {
  1633. loading.value = true;
  1634. listMyTodo(queryParams.value).then(response => {
  1635. debugger
  1636. orderList.value = response.rows;
  1637. total.value = response.total;
  1638. loading.value = false;
  1639. });
  1640. }
  1641. // 获取维保中心和场站列表
  1642. function getMaintenanceCenterAndStationList() {
  1643. listMaintenanceCenters().then(response => {
  1644. maintenanceCenterOptions.value = response.data.map(item => {
  1645. return { deptName: item, deptId: item };
  1646. });
  1647. // 如果已选择维保中心,则筛选出该维保中心下的场站
  1648. if (queryParams.value.gxtCenter) {
  1649. listStationsByMaintenanceCenter(queryParams.value.gxtCenter).then(res => {
  1650. stationOptions.value = res.data.map(item => {
  1651. return { deptName: item, deptId: item };
  1652. });
  1653. });
  1654. } else {
  1655. // 如果未选择维保中心,则清空场站选项
  1656. stationOptions.value = [];
  1657. }
  1658. });
  1659. }
  1660. // 处理维保中心变更
  1661. function handleMaintenanceCenterChange(selectedCenter) {
  1662. // 清空场站选择
  1663. queryParams.value.pcsStationName = null;
  1664. // 如果选择了维保中心,则加载对应的场站
  1665. if (selectedCenter) {
  1666. listStationsByMaintenanceCenter(selectedCenter).then(response => {
  1667. stationOptions.value = response.data.map(item => {
  1668. return { deptName: item, deptId: item };
  1669. });
  1670. });
  1671. } else {
  1672. // 如果未选择维保中心,则清空场站选项
  1673. stationOptions.value = [];
  1674. }
  1675. }
  1676. // 搜索按钮操作
  1677. function handleQuery() {
  1678. queryParams.value.pageNum = 1;
  1679. getList();
  1680. }
  1681. // 重置按钮操作
  1682. function resetQuery() {
  1683. proxy.resetForm("queryRef");
  1684. handleQuery();
  1685. }
  1686. // 查看详情
  1687. function handleView(row) {
  1688. // 调用后端接口获取详细信息
  1689. getOrderInfo(row.orderType, row.id).then(response => {
  1690. detailData.value = response.data;
  1691. // 从工单详情中获取流转记录
  1692. flowList.value = response.data.workOrderFlowList || response.data.repairOrderFlowList || [];
  1693. if (row.orderType === 1) {
  1694. // 维修工单
  1695. repairDetailDialogVisible.value = true;
  1696. } else {
  1697. // 维保工单
  1698. workDetailDialogVisible.value = true;
  1699. }
  1700. }).catch(error => {
  1701. proxy.$modal.msgError("获取工单详情失败:" + error.message);
  1702. });
  1703. }
  1704. // 处理窗口大小变化
  1705. function handleResize() {
  1706. tableHeight.value = window.innerHeight - 300;
  1707. }
  1708. // 处理接单
  1709. function handleAccept(row) {
  1710. getOrderInfo(row.orderType, row.id).then(response => {
  1711. if (row.orderType === 1) {
  1712. // 维修工单
  1713. acceptRepairForm.value = { ...response.data, selectedMembers: [] };
  1714. // 获取场站ID用于查询用户
  1715. acceptRepairForm.value.pcsStationId = response.data.pcsStationId;
  1716. acceptRepairForm.value.pcsStationPid = response.data.pcsStationPid;
  1717. if (lastLoadedCenterId.value !== acceptRepairForm.value.gxtCenterId) {
  1718. allUserList.value = [];
  1719. }
  1720. // 预加载工作负责人列表
  1721. loadQuickTeamLeaderList();
  1722. acceptRepairDialogVisible.value = true;
  1723. } else {
  1724. // 维保工单
  1725. acceptWorkForm.value = response.data;
  1726. acceptWorkForm.value.orderId = row.id;
  1727. acceptWorkForm.value.teamLeaderId = undefined;
  1728. acceptWorkForm.value.teamLeaderName = undefined;
  1729. if (row.gxtCenterId) {
  1730. if (lastLoadedCenterId.value !== acceptWorkForm.value.gxtCenterId) {
  1731. allUserList.value = [];
  1732. }
  1733. // 预加载工作负责人列表
  1734. loadQuickTeamLeaderList();
  1735. acceptWorkDialogVisible.value = true;
  1736. } else {
  1737. proxy.$modal.msgWarning("未找到有效的部门信息,无法加载用户列表");
  1738. acceptWorkDialogVisible.value = true;
  1739. }
  1740. }
  1741. });
  1742. }
  1743. // 提交维修工单接单
  1744. function submitAcceptRepair() {
  1745. proxy.$refs["acceptRepairFormRef"].validate(valid => {
  1746. if (valid) {
  1747. // 更新检修人员列表
  1748. //handleMembersChange('acceptForm');
  1749. acceptRepairOrder(acceptRepairForm.value).then(response => {
  1750. proxy.$modal.msgSuccess("接单成功");
  1751. acceptRepairDialogVisible.value = false;
  1752. getList();
  1753. }).catch(error => {
  1754. proxy.$modal.msgError("接单失败: " + error.message);
  1755. });
  1756. }
  1757. });
  1758. }
  1759. // 提交维保工单接单
  1760. function submitAcceptWork() {
  1761. proxy.$refs["acceptWorkFormRef"].validate(valid => {
  1762. if (valid) {
  1763. // 组合acceptForm中的信息,构建完整的GxtWorkOrder对象流转给后端
  1764. const data = {
  1765. id: acceptWorkForm.value.orderId,
  1766. workOrderProjectNo: acceptWorkForm.value.workOrderProjectNo,
  1767. acceptUserId: acceptWorkForm.value.teamLeaderId,
  1768. acceptUserName: acceptWorkForm.value.teamLeaderName,
  1769. teamLeaderId: acceptWorkForm.value.teamLeaderId,
  1770. teamLeaderName: acceptWorkForm.value.teamLeaderName,
  1771. content: acceptWorkForm.value.content,
  1772. workOrderStatus: 'to_finish'
  1773. };
  1774. acceptWorkOrder(data).then(response => {
  1775. proxy.$modal.msgSuccess("接单成功");
  1776. acceptWorkDialogVisible.value = false;
  1777. getList();
  1778. }).catch(error => {
  1779. proxy.$modal.msgError("接单失败: " + error.message);
  1780. });
  1781. }
  1782. });
  1783. }
  1784. // 处理结单
  1785. function handleFinalize(row) {
  1786. getOrderInfo(row.orderType, row.id).then(response => {
  1787. if (row.orderType === 1) {
  1788. // 维修工单
  1789. finalizeRepairForm.value = { ...response.data, selectedMembers: [] };
  1790. // 设置默认维修方式为正常维修(1)
  1791. if (!finalizeRepairForm.value.repairMethod) {
  1792. finalizeRepairForm.value.repairMethod = '1';
  1793. finalizeRepairForm.value.infoEntry = '1'
  1794. }
  1795. finalizeRepairDialogVisible.value = true;
  1796. commonKey++; // 更新key以强制刷新组件
  1797. } else {
  1798. // 维保工单
  1799. finalizeWorkForm.value = response.data;
  1800. if (finalizeWorkForm.value.misNo != null) {
  1801. listMisInfo({misNo: finalizeWorkForm.value.misNo}).then(response => {
  1802. const misInfo = response.rows
  1803. if (misInfo.length > 0) {
  1804. finalizeWorkForm.value.realStartTime = misInfo[0].realStartTime
  1805. finalizeWorkForm.value.realEndTime = misInfo[0].realEndTime
  1806. }
  1807. })
  1808. listWorkPerson({misNo: finalizeWorkForm.value.misNo }).then(response => {
  1809. finalizeWorkForm.value.workOrderPersonList = response.rows;
  1810. if (finalizeWorkForm.value.workOrderPersonList) {
  1811. const nickNames = finalizeWorkForm.value.workOrderPersonList
  1812. .map(person => person.nickName)
  1813. .join(',');
  1814. finalizeWorkForm.value.workGroupMemberName = nickNames
  1815. }
  1816. })
  1817. }
  1818. // 打开对话框后重置表单验证错误
  1819. proxy.$nextTick(() => {
  1820. proxy.$refs["finalizeWorkFormRef"]?.clearValidate()
  1821. })
  1822. finalizeWorkDialogVisible.value = true;
  1823. }
  1824. });
  1825. }
  1826. // 提交维修工单结单
  1827. function submitFinalizeRepair() {
  1828. proxy.$refs["finalizeRepairFormRef"].validate(valid => {
  1829. if (valid) {
  1830. // 根据维修方式执行不同的验证逻辑
  1831. if (finalizeRepairForm.value.repairMethod === '1') {
  1832. // 正常维修需要验证MIS相关字段
  1833. if (!finalizeRepairForm.value.realEndTime) {
  1834. proxy.$modal.msgError("该工单未结束,无法结单!");
  1835. return;
  1836. }
  1837. }
  1838. const data = finalizeRepairForm.value;
  1839. // 根据维修方式清除不需要的字段
  1840. if (data.repairMethod === '1') {
  1841. // 正常维修时清除复位方式
  1842. data.resetMethod = undefined;
  1843. } else if (data.repairMethod === '2') {
  1844. // 复位启机时清除MIS相关字段
  1845. data.misOrderNo = undefined;
  1846. data.realStartTime = undefined;
  1847. data.realEndTime = undefined;
  1848. data.workGroupMemberName = undefined;
  1849. data.repairOrderPersonList = [];
  1850. }
  1851. finalizeRepairOrder(data).then(response => {
  1852. proxy.$modal.msgSuccess("结单成功");
  1853. finalizeRepairDialogVisible.value = false;
  1854. getList();
  1855. }).catch(error => {
  1856. proxy.$modal.msgError("结单失败: " + error.message);
  1857. });
  1858. }
  1859. });
  1860. }
  1861. // 提交维保工单结单
  1862. function submitFinalizeWork() {
  1863. proxy.$refs["finalizeWorkFormRef"].validate(valid => {
  1864. if (valid) {
  1865. if (!finalizeWorkForm.value.realEndTime) {
  1866. proxy.$modal.msgError("该工单未结束,无法结单!");
  1867. return;
  1868. }
  1869. finalizeWorkForm.value.workOrderStatus = 'completed'
  1870. finalizeWorkOrder(finalizeWorkForm.value).then(response => {
  1871. proxy.$modal.msgSuccess("结单成功");
  1872. finalizeWorkDialogVisible.value = false;
  1873. // 清空附件列表
  1874. finalizeWorkForm.value.attachmentUrls = undefined
  1875. getList();
  1876. }).catch(error => {
  1877. proxy.$modal.msgError("结单失败: " + error.message);
  1878. });
  1879. }
  1880. });
  1881. }
  1882. // 处理审批
  1883. function handleApprove(row) {
  1884. getOrderInfo(row.orderType, row.id).then(response => {
  1885. debugger
  1886. if (row.orderType === 1) {
  1887. // 维修工单
  1888. approveRepairForm.value = response.data;
  1889. approveRepairForm.value.rejectionReason = ""; // 清空审批意见
  1890. approveRepairDialogVisible.value = true;
  1891. } else {
  1892. // 维保工单
  1893. approveWorkForm.value = response.data;
  1894. approveWorkForm.value.rejectionReason = ""; // 清空审批意见
  1895. approveWorkDialogVisible.value = true;
  1896. }
  1897. });
  1898. }
  1899. // 提交维修工单审批
  1900. function submitApproveRepair(approvalStatusValue) {
  1901. proxy.$refs["approveRepairFormRef"].validate(valid => {
  1902. if (valid) {
  1903. approveRepairForm.value.approvalStatus = approvalStatusValue
  1904. if (approveRepairForm.value.approvalStatus === 'rejected' && !approveRepairForm.value.rejectionReason) {
  1905. proxy.$modal.msgError("驳回时审批意见不能为空");
  1906. return;
  1907. }
  1908. approveRepairOrder(approveRepairForm.value).then(response => {
  1909. if (approvalStatusValue === "approved") {
  1910. proxy.$modal.msgSuccess("审批通过成功");
  1911. } else {
  1912. proxy.$modal.msgSuccess("审批驳回成功");
  1913. }
  1914. approveRepairDialogVisible.value = false;
  1915. getList();
  1916. }).catch(error => {
  1917. proxy.$modal.msgError("审批失败: " + error.message);
  1918. });
  1919. }
  1920. });
  1921. }
  1922. // 提交维保工单审批
  1923. function submitApproveWork(approvalStatusValue) {
  1924. approveWorkForm.value.workOrderStatus = approvalStatusValue
  1925. proxy.$refs["approveWorkFormRef"].validate(valid => {
  1926. if (valid) {
  1927. approveWorkOrder(approveWorkForm.value).then(response => {
  1928. const msg = approveWorkForm.value.workOrderStatus === 'suspended' ? '挂起审批通过' : '挂起审批驳回'
  1929. proxy.$modal.msgSuccess(msg + "成功")
  1930. approveWorkDialogVisible.value = false;
  1931. getList();
  1932. }).catch(error => {
  1933. proxy.$modal.msgError("审批失败: " + error.message);
  1934. });
  1935. }
  1936. });
  1937. }
  1938. /** 工作负责人输入框获取焦点 */
  1939. const handleTeamLeaderInputFocus = () => {
  1940. showTeamLeaderQuickSelect.value = true;
  1941. // 如果已有输入内容,立即搜索
  1942. if ((acceptRepairForm.value && acceptRepairForm.value.teamLeaderName && acceptRepairForm.value.teamLeaderName.trim()) ||
  1943. (acceptWorkForm.value && acceptWorkForm.value.teamLeaderName && acceptWorkForm.value.teamLeaderName.trim())) {
  1944. const currentForm = acceptRepairDialogVisible.value ? acceptRepairForm.value : acceptWorkForm.value;
  1945. handleTeamLeaderInput(currentForm.teamLeaderName);
  1946. } else {
  1947. // 如果没有输入内容,加载默认列表
  1948. loadQuickTeamLeaderList();
  1949. }
  1950. }
  1951. // 工作负责人输入框失去焦点
  1952. const handleTeamLeaderInputBlur = () => {
  1953. // 延迟隐藏下拉框,确保点击选项能触发
  1954. setTimeout(() => {
  1955. showTeamLeaderQuickSelect.value = false;
  1956. }, 200);
  1957. }
  1958. // 工作负责人输入事件 - 实时搜索
  1959. const handleTeamLeaderInput = (value) => {
  1960. const searchText = value.trim();
  1961. if (!searchText) {
  1962. quickTeamLeaderList.value = [];
  1963. showTeamLeaderQuickSelect.value = false;
  1964. return;
  1965. }
  1966. showTeamLeaderQuickSelect.value = true;
  1967. // 清除之前的定时器
  1968. if (teamLeaderSearchTimer.value) {
  1969. clearTimeout(teamLeaderSearchTimer.value);
  1970. }
  1971. // 设置新的定时器,防抖处理(300ms)
  1972. teamLeaderSearchTimer.value = setTimeout(() => {
  1973. filterQuickUserList(searchText);
  1974. }, 300);
  1975. }
  1976. /** 过滤快速检索用户列表 */
  1977. const filterQuickUserList = (keyword) => {
  1978. if (!allUserList.value.length) {
  1979. loadQuickTeamLeaderList();
  1980. return;
  1981. }
  1982. const lowerKeyword = keyword.toLowerCase();
  1983. quickTeamLeaderList.value = allUserList.value.filter(item =>
  1984. (item.nickName && item.nickName.toLowerCase().includes(lowerKeyword))
  1985. );
  1986. }
  1987. /** 加载快速检索工作负责人列表 */
  1988. const loadQuickTeamLeaderList = async () => {
  1989. // 如果已有所有用户数据,且是同一个维保中心,直接使用
  1990. if (allUserList.value.length > 0) {
  1991. quickTeamLeaderList.value = allUserList.value;
  1992. return;
  1993. }
  1994. // 记录当前维保中心ID
  1995. const currentForm = acceptRepairDialogVisible.value ? acceptRepairForm.value : acceptWorkForm.value;
  1996. // 确保currentForm存在且有gxtCenterId属性
  1997. if (currentForm && currentForm.gxtCenterId) {
  1998. lastLoadedCenterId.value = currentForm.gxtCenterId;
  1999. }
  2000. teamLeaderLoading.value = true;
  2001. try {
  2002. // 加载当前部门下的用户列表
  2003. const response = await listLeader({
  2004. deptId: -1, // 通过后台配置部门
  2005. status: '0'
  2006. });
  2007. allUserList.value = response.data || [];
  2008. quickTeamLeaderList.value = allUserList.value;
  2009. } catch (error) {
  2010. console.error('加载工作负责人列表失败:', error);
  2011. allUserList.value = [];
  2012. } finally {
  2013. teamLeaderLoading.value = false;
  2014. }
  2015. }
  2016. // 快速选择工作负责人
  2017. const handleTeamLeaderQuickSelect = (item) => {
  2018. if (acceptRepairDialogVisible.value && acceptRepairForm.value) {
  2019. acceptRepairForm.value.teamLeaderId = item.userId;
  2020. acceptRepairForm.value.teamLeaderName = item.nickName;
  2021. } else if (acceptWorkDialogVisible.value && acceptWorkForm.value) {
  2022. acceptWorkForm.value.teamLeaderId = item.userId;
  2023. acceptWorkForm.value.teamLeaderName = item.nickName;
  2024. }
  2025. showTeamLeaderQuickSelect.value = false;
  2026. }
  2027. // 清空工作负责人
  2028. const handleTeamLeaderClear = () => {
  2029. if (acceptRepairDialogVisible.value && acceptRepairForm.value) {
  2030. acceptRepairForm.value.teamLeaderId = undefined;
  2031. acceptRepairForm.value.teamLeaderName = '';
  2032. } else if (acceptWorkDialogVisible.value && acceptWorkForm.value) {
  2033. acceptWorkForm.value.teamLeaderId = undefined;
  2034. acceptWorkForm.value.teamLeaderName = '';
  2035. }
  2036. quickTeamLeaderList.value = [];
  2037. showTeamLeaderQuickSelect.value = false;
  2038. }
  2039. /** MIS工单编码输入框获取焦点 */
  2040. const handleMisNoInputFocus = () => {
  2041. showMisNoQuickSelect.value = true;
  2042. debugger
  2043. // 如果已有输入内容,立即搜索
  2044. if ((finalizeRepairForm.value && finalizeRepairForm.value.misOrderNo && finalizeRepairForm.value.misOrderNo.trim()) ||
  2045. (assignWorkForm.value && assignWorkForm.value.misNo && assignWorkForm.value.misNo.trim())) {
  2046. const currentForm = finalizeRepairDialogVisible.value ? finalizeRepairForm.value : assignWorkForm.value;
  2047. handleMisNoInput(currentForm.misOrderNo || currentForm.misNo);
  2048. } else {
  2049. // 如果没有输入内容,加载默认列表
  2050. loadQuickMisNoList();
  2051. }
  2052. }
  2053. // MIS工单编码输入框失去焦点
  2054. const handleMisNoInputBlur = () => {
  2055. // 延迟隐藏下拉框,确保点击选项能触发
  2056. setTimeout(() => {
  2057. showMisNoQuickSelect.value = false;
  2058. }, 200);
  2059. }
  2060. // MIS工单编码输入事件 - 实时搜索
  2061. const handleMisNoInput = (value) => {
  2062. const searchText = value.trim();
  2063. if (!searchText) {
  2064. quickMisNoList.value = [];
  2065. showMisNoQuickSelect.value = false;
  2066. return;
  2067. }
  2068. showMisNoQuickSelect.value = true;
  2069. // 清除之前的定时器
  2070. if (misNoSearchTimer.value) {
  2071. clearTimeout(misNoSearchTimer.value);
  2072. }
  2073. // 设置新的定时器,防抖处理(300ms)
  2074. misNoSearchTimer.value = setTimeout(() => {
  2075. // filterQuickMisNoList(searchText);
  2076. loadQuickMisNoList(searchText)
  2077. }, 300);
  2078. }
  2079. /** 过滤快速检索MIS工单列表 */
  2080. const filterQuickMisNoList = (keyword) => {
  2081. if (!allMisNoList.value.length) {
  2082. loadQuickMisNoList(keyword);
  2083. return;
  2084. }
  2085. debugger
  2086. const lowerKeyword = keyword.toLowerCase();
  2087. quickMisNoList.value = allMisNoList.value.filter(item =>
  2088. (item.misNo && item.misNo.toLowerCase().includes(lowerKeyword))
  2089. );
  2090. }
  2091. /** 加载快速检索MIS工单列表 */
  2092. const loadQuickMisNoList = async (keyword) => {
  2093. // // 如果已有所有MIS工单数据,直接使用
  2094. // if (allMisNoList.value.length > 0) {
  2095. // quickMisNoList.value = allMisNoList.value;
  2096. // return;
  2097. // }
  2098. if (!keyword) {
  2099. quickMisNoList.value = []
  2100. return
  2101. }
  2102. misNoLoading.value = true;
  2103. try {
  2104. // 加载MIS工单列表
  2105. const response = await listMisInfo({
  2106. pageNum: 1,
  2107. // pageSize: 100
  2108. misNo: keyword,
  2109. pcsDeviceName: keyword,
  2110. pcsStationName: keyword
  2111. });
  2112. debugger
  2113. // allMisNoList.value = response.rows || [];
  2114. // quickMisNoList.value = allMisNoList.value;
  2115. quickMisNoList.value = response.rows || []
  2116. // 如果没有找到结果,可以尝试更宽松的搜索
  2117. if (quickMisNoList.value.length === 0 && keyword.length >= 2) {
  2118. // 可以尝试只按MIS工单编码搜索
  2119. const retryResponse = await listMisInfo({
  2120. pageNum: 1,
  2121. // pageSize: 10,
  2122. misNo: keyword
  2123. })
  2124. quickMisNoList.value = retryResponse.rows || []
  2125. }
  2126. } catch (error) {
  2127. console.error('加载MIS工单列表失败:', error);
  2128. allMisNoList.value = [];
  2129. } finally {
  2130. misNoLoading.value = false;
  2131. }
  2132. }
  2133. // 快速选择MIS工单
  2134. const handleMisNoQuickSelect = (item) => {
  2135. onMisInfoSelected(item);
  2136. showMisNoQuickSelect.value = false;
  2137. }
  2138. // 清空MIS工单编码
  2139. const handleMisNoClear = () => {
  2140. // 清空与MIS工单相关的字段
  2141. if (finalizeRepairDialogVisible.value && finalizeRepairForm.value) {
  2142. finalizeRepairForm.value.misOrderNo = undefined;
  2143. finalizeRepairForm.value.realStartTime = undefined;
  2144. finalizeRepairForm.value.realEndTime = undefined;
  2145. finalizeRepairForm.value.workGroupMemberName = undefined;
  2146. finalizeRepairForm.value.repairOrderPersonList = [];
  2147. } else if (assignWorkDialogVisible.value && assignWorkForm.value) {
  2148. assignWorkForm.value.misNo = null;
  2149. assignWorkForm.value.content = null;
  2150. }
  2151. quickMisNoList.value = [];
  2152. showMisNoQuickSelect.value = false;
  2153. }
  2154. const disabledDate = (time) => {
  2155. return time.getTime() > Date.now();
  2156. };
  2157. const disabledTime = (date) => {
  2158. const now = new Date();
  2159. if (date && date.toDateString() === now.toDateString()) {
  2160. const currentHour = now.getHours();
  2161. const currentMinute = now.getMinutes();
  2162. const disabledHours = () => {
  2163. const hours = [];
  2164. for (let i = currentHour + 1; i < 24; i++) {
  2165. hours.push(i);
  2166. }
  2167. return hours;
  2168. };
  2169. const disabledMinutes = (hour) => {
  2170. if (hour === currentHour) {
  2171. const minutes = [];
  2172. for (let i = currentMinute + 1; i < 60; i++) {
  2173. minutes.push(i);
  2174. }
  2175. return minutes;
  2176. }
  2177. return [];
  2178. };
  2179. return {
  2180. disabledHours,
  2181. disabledMinutes
  2182. };
  2183. };
  2184. return {};
  2185. };
  2186. // 打开设备选择对话框
  2187. function handleSelectMisInfo() {
  2188. misInfoSelectVisible.value = true;
  2189. }
  2190. // 设备MIS信息回调
  2191. function onMisInfoSelected(row) {
  2192. if (row) {
  2193. listRepairOrder({pageNum: 1, pageSize: 10, misOrderNo: row.misNo }).then(response => {
  2194. const gxtOrders= response.rows
  2195. if (gxtOrders.length > 0) {
  2196. proxy.$modal.msgWarning('选择工单已存在!请重新选择!')
  2197. return
  2198. }
  2199. // 使用展开运算符创建新对象以确保响应式更新
  2200. finalizeFormData.value = {
  2201. ...finalizeFormData.value,
  2202. misOrderNo: row.misNo,
  2203. realStartTime: row.realStartTime,
  2204. realEndTime: row.realEndTime
  2205. };
  2206. // finalizeFormData.value.content = row.content
  2207. // 使用从属性传入的listWorkPerson方法
  2208. if (typeof listWorkPerson === 'function') {
  2209. listWorkPerson({ misNo: row.misNo }).then(response => {
  2210. debugger
  2211. const updatedData = {
  2212. ...finalizeFormData.value,
  2213. repairOrderPersonList: response.rows
  2214. };
  2215. if (response.rows) {
  2216. const nickNames = response.rows
  2217. .map(person => person.nickName)
  2218. .join(',');
  2219. updatedData.workGroupMemberName = nickNames
  2220. }
  2221. finalizeFormData.value = updatedData;
  2222. })
  2223. }
  2224. misInfoSelectVisible.value = false
  2225. })
  2226. }
  2227. }
  2228. // 维修方式变化处理
  2229. function handleRepairMethodChange(value) {
  2230. // 如果切换到正常维修(1),清除复位方式
  2231. if (value === '1') {
  2232. finalizeRepairForm.value.resetMethod = undefined;
  2233. }
  2234. // 如果切换到复位启机(2),清除MIS相关字段
  2235. else if (value === '2') {
  2236. finalizeRepairForm.value.misOrderNo = undefined;
  2237. finalizeRepairForm.value.realStartTime = undefined;
  2238. finalizeRepairForm.value.realEndTime = undefined;
  2239. }
  2240. }
  2241. // 处理复运
  2242. function handleRestart(row) {
  2243. getOrderInfo(row.orderType, row.id).then(response => {
  2244. if (row.orderType === 1) {
  2245. // 维修工单
  2246. restartRepairForm.value = response.data;
  2247. restartRepairDialogVisible.value = true;
  2248. } else {
  2249. // 维保工单
  2250. restartWorkForm.value = response.data;
  2251. restartWorkDialogVisible.value = true;
  2252. }
  2253. });
  2254. }
  2255. // 提交维修工单复运
  2256. async function submitRestartRepair() {
  2257. proxy.$refs["restartRepairFormRef"].validate(async valid => {
  2258. if (valid) {
  2259. // 判断 restartTime 是否小于 realEndTime
  2260. if (new Date(restartRepairForm.value.restartTime) < new Date(restartRepairForm.value.realEndTime)) {
  2261. // 如果是,弹出确认对话框
  2262. const confirmResult = await proxy.$confirm('复运时间早于实际结束时间,是否继续?', '警告', {
  2263. confirmButtonText: '确定',
  2264. cancelButtonText: '取消',
  2265. type: 'warning'
  2266. }).catch(() => {
  2267. // 如果用户点击了取消按钮,这里会捕获到错误并返回
  2268. return false;
  2269. });
  2270. // 如果用户点击了取消按钮,终止操作
  2271. if (!confirmResult) {
  2272. return;
  2273. }
  2274. }
  2275. restartRepairOrder(restartRepairForm.value).then(response => {
  2276. proxy.$modal.msgSuccess("复运成功");
  2277. restartRepairDialogVisible.value = false;
  2278. getList();
  2279. }).catch(error => {
  2280. proxy.$modal.msgError("复运失败: " + error.message);
  2281. });
  2282. }
  2283. });
  2284. }
  2285. // 提交维保工单复运
  2286. async function submitRestartWork() {
  2287. proxy.$refs["restartWorkFormRef"].validate(async valid => {
  2288. if (valid) {
  2289. // 判断 restartTime 是否小于 realEndTime
  2290. if (new Date(restartWorkForm.value.restartTime) < new Date(restartWorkForm.value.realEndTime)) {
  2291. // 如果是,弹出确认对话框
  2292. const confirmResult = await proxy.$confirm('复运时间早于实际结束时间,是否继续?', '警告', {
  2293. confirmButtonText: '确定',
  2294. cancelButtonText: '取消',
  2295. type: 'warning'
  2296. }).catch(() => {
  2297. // 如果用户点击了取消按钮,这里会捕获到错误并返回
  2298. return false;
  2299. });
  2300. // 如果用户点击了取消按钮,终止操作
  2301. if (!confirmResult) {
  2302. return;
  2303. }
  2304. }
  2305. restartWorkForm.value.workOrderStatus = 'restarted'
  2306. restartWorkOrder(restartWorkForm.value).then(response => {
  2307. restartWorkDialogVisible.value = false
  2308. proxy.$modal.msgSuccess("复运成功")
  2309. getList()
  2310. }).catch(error => {
  2311. proxy.$modal.msgError("复运失败:" + (error?.response?.data?.msg || "未知错误"))
  2312. })
  2313. }
  2314. })
  2315. }
  2316. // 处理下发
  2317. function handleUpdate(row) {
  2318. getOrderInfo(row.orderType, row.id).then(response => {
  2319. if (row.orderType === 1) {
  2320. // 维修工单
  2321. assignRepairForm.value = response.data;
  2322. assignRepairDialogVisible.value = true;
  2323. } else {
  2324. // 维保工单
  2325. assignWorkForm.value = response.data;
  2326. assignWorkDialogVisible.value = true;
  2327. }
  2328. });
  2329. }
  2330. /** 打开设备选择对话框 */
  2331. function handleSelectEquipment() {
  2332. equipmentSelectVisible.value = true
  2333. }
  2334. /** 设备选择回调 */
  2335. function onEquipmentSelected(row) {
  2336. // Determine which form we're updating based on which dialog is visible
  2337. let targetForm = assignRepairForm;
  2338. if (assignWorkDialogVisible.value) {
  2339. targetForm = assignWorkForm;
  2340. }
  2341. if (row) {
  2342. // 检查维保中心ID和场站ID是否存在
  2343. if (!row.maintenanceCenterId) {
  2344. proxy.$modal.msgError("该设备的维保中心没有对应的部门,请完善部门信息后再更新设备数据!");
  2345. return;
  2346. }
  2347. if (!row.stationId) {
  2348. proxy.$modal.msgError("该设备的场站没有对应的部门,请完善部门信息后再更新设备数据!");
  2349. return;
  2350. }
  2351. targetForm.value.pcsDeviceId = row.equipmentId
  2352. targetForm.value.pcsDeviceName = row.equipmentCode
  2353. targetForm.value.gxtCenterId = row.maintenanceCenterId
  2354. targetForm.value.gxtCenter = row.maintenanceCenter
  2355. targetForm.value.pcsStationId = row.stationId
  2356. targetForm.value.pcsStationName = row.station
  2357. targetForm.value.brand = row.brand
  2358. targetForm.value.model = row.model
  2359. }
  2360. equipmentSelectVisible.value = false
  2361. }
  2362. /** 保存并下发维修工单 */
  2363. function submitFormAndIssue() {
  2364. proxy.$refs["repairOrderRef"].validate(valid => {
  2365. if (valid) {
  2366. // 设置状态为待接单
  2367. assignRepairForm.value.workOrderStatus = "assigned"
  2368. updateRepairOrder(assignRepairForm.value).then(response => {
  2369. proxy.$modal.msgSuccess("下发成功")
  2370. assignRepairDialogVisible.value = false
  2371. getList()
  2372. })
  2373. }
  2374. })
  2375. }
  2376. /** 保存并下发维保工单 */
  2377. function submitWorkFormAndIssue() {
  2378. proxy.$refs["workOrderRef"].validate(valid => {
  2379. if (valid) {
  2380. // 设置状态为待接单
  2381. assignWorkForm.value.workOrderStatus = "assigned"
  2382. updateGxtOrder(assignWorkForm.value).then(response => {
  2383. proxy.$modal.msgSuccess("下发成功")
  2384. assignWorkDialogVisible.value = false
  2385. getList()
  2386. })
  2387. }
  2388. })
  2389. }
  2390. const handleInfoEntryChange = (val) => {
  2391. // 选中2工作票编号时修改其他值
  2392. if (val === '2') {
  2393. finalizeRepairForm.value.misOrderNo = undefined;
  2394. finalizeRepairForm.value.realStartTime = undefined;
  2395. finalizeRepairForm.value.realEndTime = undefined;
  2396. finalizeRepairForm.value.workGroupMemberName = undefined;
  2397. finalizeRepairForm.value.repairOrderPersonList = [];
  2398. } else {
  2399. finalizeRepairForm.value.workPermitNum = undefined;
  2400. }
  2401. };
  2402. // 复启操作
  2403. function handleReset(row) {
  2404. getOrderInfo(row.orderType, row.id).then(response => {
  2405. // 使用新的组件方式
  2406. resetFormData.value = { ...response.data }
  2407. resetDialogVisible.value = true
  2408. })
  2409. }
  2410. // 在提交复启成功后的回调函数
  2411. function handleResetSuccess() {
  2412. resetDialogVisible.value = false
  2413. getList()
  2414. }
  2415. // 用于传递给复启组件的提交方法
  2416. async function submitResetFromParent(data) {
  2417. await finalizeRepairOrder(data)
  2418. }
  2419. // 计算属性:双向绑定代理
  2420. const workPermitNumProxy = computed({
  2421. get() {
  2422. return finalizeRepairForm.value.workPermitNum
  2423. },
  2424. set(val) {
  2425. // 1. 去掉首尾空格
  2426. let trimmed = val.trim()
  2427. // 2. 只保留允许的字符:中文、英文字母、数字、下划线
  2428. // 如果你希望更宽松(比如允许横杠 -),可调整正则
  2429. trimmed = trimmed.replace(/[^a-zA-Z0-9_\-\.]/g, '')
  2430. // 3. 截断到 20 个字符(按字符数,不是字节)
  2431. if (trimmed.length > 20) {
  2432. trimmed = trimmed.substring(0, 20)
  2433. }
  2434. // 4. 写回表单
  2435. finalizeRepairForm.value.workPermitNum = trimmed
  2436. }
  2437. })
  2438. const disabledStartDate = (time) => {
  2439. const getYYYYMMDD = (date) => {
  2440. const y = date.getFullYear();
  2441. const m = String(date.getMonth() + 1).padStart(2, '0');
  2442. const d = String(date.getDate()).padStart(2, '0');
  2443. return `${y}-${m}-${d}`;
  2444. };
  2445. const today = getYYYYMMDD(new Date());
  2446. let acceptDateStr = null;
  2447. const acceptStr = finalizeRepairForm.value.acceptTime; // 脚本中用 .value
  2448. if (acceptStr) {
  2449. // 假设 acceptTime 格式是 "2025-12-09 18:01",取前面日期部分
  2450. acceptDateStr = acceptStr.split(' ')[0]; // 得到 "2025-12-09"
  2451. }
  2452. const selectedDateStr = getYYYYMMDD(time);
  2453. // 如果没有 acceptTime,只禁用未来日期
  2454. if (!acceptDateStr) {
  2455. return selectedDateStr > today;
  2456. }
  2457. // 禁用:早于 acceptDate 或 晚于今天
  2458. return selectedDateStr < acceptDateStr || selectedDateStr > today;
  2459. };
  2460. const disabledEndDate = (time) => {
  2461. const getYYYYMMDD = (date) => {
  2462. const y = date.getFullYear();
  2463. const m = String(date.getMonth() + 1).padStart(2, '0');
  2464. const d = String(date.getDate()).padStart(2, '0');
  2465. return `${y}-${m}-${d}`;
  2466. };
  2467. const today = getYYYYMMDD(new Date());
  2468. let acceptDateStr = null;
  2469. const acceptStr = finalizeRepairForm.value.acceptTime; // 脚本中用 .value
  2470. const startStr = finalizeRepairForm.value.realStartTime;
  2471. if (startStr) {
  2472. // 假设 acceptTime 格式是 "2025-12-09 18:01",取前面日期部分
  2473. acceptDateStr = startStr.split(' ')[0]; // 得到 "2025-12-09"
  2474. } else if(acceptStr) {
  2475. acceptDateStr = acceptStr.split(' ')[0];
  2476. }
  2477. const selectedDateStr = getYYYYMMDD(time);
  2478. // 如果没有 acceptTime,只禁用未来日期
  2479. if (!acceptDateStr) {
  2480. return selectedDateStr > today;
  2481. }
  2482. // 禁用:早于 acceptDate 或 晚于今天
  2483. return selectedDateStr < acceptDateStr || selectedDateStr > today;
  2484. };
  2485. // 添加响应式数据用于结单组件
  2486. const finalizeFormData = ref({})
  2487. /** 结单操作 */
  2488. function handleRepairOrderFinalize(row) {
  2489. getRepairOrder(row.id).then(response => {
  2490. finalizeFormData.value = { ...response.data, selectedMembers: [] }
  2491. debugger
  2492. finalizeFormData.value.repairMethod = '1';
  2493. finalizeFormData.value.infoEntry = '1'
  2494. finalizeDialogVisible.value = true
  2495. commonKey++
  2496. })
  2497. }
  2498. // 在提交结单成功后的回调函数
  2499. function handleFinalizeSuccess() {
  2500. finalizeDialogVisible.value = false
  2501. getList()
  2502. }
  2503. // 用于传递给结单组件的提交方法
  2504. async function submitFinalizeFromParent(data) {
  2505. await finalizeRepairOrder(data)
  2506. }
  2507. /** 退回 */
  2508. function handleReturn(row) {
  2509. getRepairOrder(row.id).then(response => {
  2510. returnForm.value = response.data
  2511. if (row.workOrderStatus != 'return') {
  2512. returnForm.value.returnType = undefined
  2513. returnForm.value.returnReason = undefined
  2514. }
  2515. returnDialogVisible.value = true
  2516. })
  2517. }
  2518. // 用于传递给退回组件的提交方法
  2519. async function submitReturnFromParent(data) {
  2520. await returnRepairOrder(data)
  2521. }
  2522. // 在提交退回成功后的回调函数
  2523. function handleReturnSuccess() {
  2524. returnDialogVisible.value = false
  2525. getList()
  2526. }
  2527. /** 待结单状态:结单按钮 */
  2528. function handleFinish(row) {
  2529. getGxtOrder(row.id).then(response => {
  2530. finishForm.value = response.data
  2531. finishForm.value.orderId = row.id
  2532. if (finishForm.value.infoEntry != null && finishForm.value.infoEntry == '1') {
  2533. if (row.misNo != null) {
  2534. listMisInfo({misNo: row.misNo}).then(response => {
  2535. const misInfo = response.rows
  2536. debugger
  2537. if (misInfo.length > 0) {
  2538. finishForm.value.realStartTime = misInfo[0].realStartTime
  2539. finishForm.value.realEndTime = misInfo[0].realEndTime
  2540. }
  2541. })
  2542. }
  2543. listWorkPerson({misNo: row.misNo}).then(response => {
  2544. finishForm.value.workOrderPersonList = response.rows;
  2545. if (finishForm.value.workOrderPersonList) {
  2546. const nickNames = finishForm.value.workOrderPersonList
  2547. .map(person => person.nickName)
  2548. .join(',');
  2549. finishForm.value.workGroupMemberName = nickNames
  2550. finishDialogVisible.value = true
  2551. }
  2552. })
  2553. } else {
  2554. finishForm.value.realStartTime = null
  2555. finishForm.value.realEndTime = null
  2556. finishDialogVisible.value = true
  2557. }
  2558. // 打开对话框后重置表单验证错误
  2559. proxy.$nextTick(() => {
  2560. proxy.$refs["finishRef"]?.clearValidate()
  2561. })
  2562. })
  2563. }
  2564. /** 保存结单工单 */
  2565. function saveFinishWorkOrder() {
  2566. // if (!finishForm.value.realEndTime) {
  2567. // proxy.$modal.msgError("该工单未结束,无法结单!")
  2568. // return
  2569. // }
  2570. finishForm.value.workOrderStatus = 'completed'
  2571. completeWorkOrder(finishForm.value.orderId, finishForm.value).then(response => {
  2572. finishDialogVisible.value = false
  2573. // 清空附件列表
  2574. finishForm.value.attachmentUrls = undefined
  2575. // proxy.$modal.msgSuccess("结单成功")
  2576. getList()
  2577. }).catch(error => {
  2578. console.log("操作失败: " + error.message)
  2579. })
  2580. }
  2581. // 用于传递给结单组件的提交方法
  2582. async function submitFinishFromParent(data) {
  2583. finishForm.value = data
  2584. await saveFinishWorkOrder()
  2585. }
  2586. // 在提交结单成功后的回调函数
  2587. function handleFinishSuccess() {
  2588. finishDialogVisible.value = false
  2589. getList()
  2590. }
  2591. /** 挂起维修工单 */
  2592. function handleRepairSuspend(row) {
  2593. debugger
  2594. suspendForm.value = row
  2595. suspendForm.value.suspendReason = undefined
  2596. suspendRepairDialogVisible.value = true
  2597. proxy.resetForm("suspendFormRef")
  2598. }
  2599. // 用于传递给退回组件的提交方法
  2600. async function submitSuspendFromParent(data) {
  2601. if (data.orderType == '1') {
  2602. await suspendRepairOrder(data)
  2603. }
  2604. if (data.orderType == '2') {
  2605. await suspendWorkOrder(data.id, data)
  2606. }
  2607. }
  2608. // 在提交退回成功后的回调函数
  2609. function handleSuspendSuccess() {
  2610. suspendRepairDialogVisible.value = false
  2611. suspendDialogVisible.value = false
  2612. getList()
  2613. }
  2614. /** 维保挂起 */
  2615. function handleSuspend(row) {
  2616. getGxtOrder(row.id).then(response => {
  2617. suspendForm.value = response.data
  2618. suspendForm.value.orderId = row.id
  2619. suspendDialogVisible.value = true
  2620. // 打开对话框后重置表单验证错误
  2621. proxy.resetForm("suspendFormRef")
  2622. })
  2623. }
  2624. // 在提交审批成功后的回调函数
  2625. async function submitApproveFromParent(data) {
  2626. if (data.orderType == '1') {
  2627. await approveSuspendRepairOrder(data)
  2628. }
  2629. if (data.orderType == '2') {
  2630. await approveWorkOrder(data.id, data)
  2631. }
  2632. }
  2633. // 在提交审批成功后的回调函数
  2634. function handleApproveSuccess() {
  2635. approveRepairDialogVisible.value = false
  2636. approveWorkDialogVisible.value = false
  2637. getList()
  2638. }
  2639. </script>
  2640. <style scoped>
  2641. /* 表单字段间距调整 */
  2642. .el-form-item {
  2643. margin-bottom: 18px;
  2644. }
  2645. .text-gray-500 {
  2646. color: #6b7280;
  2647. }
  2648. .card-header {
  2649. font-weight: bold;
  2650. font-size: 16px;
  2651. }
  2652. .info-section {
  2653. padding: 16px 0;
  2654. height: 100%;
  2655. box-sizing: border-box;
  2656. }
  2657. .section-title {
  2658. font-weight: bold;
  2659. font-size: 16px;
  2660. margin-bottom: 15px;
  2661. padding-bottom: 10px;
  2662. border-bottom: 1px solid #ebeef5;
  2663. }
  2664. .info-content {
  2665. height: calc(100% - 30px);
  2666. overflow-y: auto;
  2667. overflow-x: hidden; /* 防止横向滚动 */
  2668. padding: 0 10px; /* 添加内边距防止内容贴边 */
  2669. }
  2670. .info-item {
  2671. margin-bottom: 12px;
  2672. }
  2673. .info-item label {
  2674. display: block;
  2675. font-size: 12px;
  2676. color: #999;
  2677. margin-bottom: 4px;
  2678. }
  2679. .info-item p {
  2680. font-size: 14px;
  2681. color: #333;
  2682. margin: 0;
  2683. line-height: 1.4;
  2684. }
  2685. .flow-history {
  2686. height: 100%;
  2687. padding: 0 10px; /* 添加内边距防止内容贴边 */
  2688. }
  2689. .flow-history .el-timeline {
  2690. margin-left: 0;
  2691. padding-left: 0;
  2692. }
  2693. .flow-item {
  2694. /*padding: 10px;
  2695. border-radius: 4px;*/
  2696. }
  2697. .flow-item h4 {
  2698. margin: 0 0 5px 0;
  2699. font-size: 14px;
  2700. font-weight: bold;
  2701. }
  2702. .flow-item p {
  2703. margin: 0;
  2704. font-size: 12px;
  2705. line-height: 1.4;
  2706. color: #606266;
  2707. }
  2708. /* 修复对话框底部按钮点击区域问题 */
  2709. :deep(.el-dialog__footer) {
  2710. padding: 20px !important;
  2711. position: relative;
  2712. z-index: 10;
  2713. }
  2714. /* 确保关闭按钮有完整的点击区域 */
  2715. .dialog-footer :deep(.el-button) {
  2716. padding: 12px 20px;
  2717. min-width: 80px;
  2718. z-index: 20;
  2719. position: relative;
  2720. }
  2721. /* 表单字段间距调整 */
  2722. :deep(.el-form-item) {
  2723. margin-bottom: 18px;
  2724. }
  2725. .content-text {
  2726. white-space: pre-wrap;
  2727. word-break: break-word;
  2728. line-height: 1.5;
  2729. }
  2730. /* 快速检索下拉框样式 */
  2731. .quick-select-dropdown {
  2732. position: absolute;
  2733. top: 100%;
  2734. left: 0;
  2735. right: 0;
  2736. z-index: 1000;
  2737. max-height: 200px;
  2738. overflow-y: auto;
  2739. background: #fff;
  2740. border: 1px solid #e4e7ed;
  2741. border-radius: 4px;
  2742. box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  2743. padding: 6px 0;
  2744. }
  2745. .quick-select-dropdown .quick-select-item {
  2746. padding: 8px 12px;
  2747. cursor: pointer;
  2748. display: flex;
  2749. justify-content: space-between;
  2750. }
  2751. .quick-select-dropdown .quick-select-item:hover {
  2752. background-color: #f5f7fa;
  2753. }
  2754. .quick-select-dropdown .user-name {
  2755. font-size: 14px;
  2756. color: #606266;
  2757. }
  2758. .quick-select-dropdown.no-data {
  2759. text-align: center;
  2760. padding: 12px;
  2761. color: #909399;
  2762. font-size: 14px;
  2763. }
  2764. /* 表单字段间距调整 */
  2765. :deep(.el-form-item) {
  2766. margin-bottom: 18px;
  2767. }
  2768. /* 表单中的列间距调整 */
  2769. :deep(.el-col) {
  2770. padding-left: 5px;
  2771. padding-right: 5px;
  2772. }
  2773. /* 表单行间距调整 */
  2774. :deep(.el-row) {
  2775. margin-left: -5px;
  2776. margin-right: -5px;
  2777. }
  2778. /* 穿透修改组件内部输入框的对齐方式(关键) */
  2779. :deep(.input-number-left .el-input__inner) {
  2780. text-align: left !important; /* !important 覆盖组件默认的居中 */
  2781. }
  2782. </style>