index.vue 105 KB

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