index.vue 114 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297
  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="maintenanceType" label-position="top">-->
  22. <!-- <el-select v-model="queryParams.maintenanceType" placeholder="请选择检修类型" clearable>-->
  23. <!-- <el-option-->
  24. <!-- v-for="dict in gxt_maintenance_type"-->
  25. <!-- :key="dict.value"-->
  26. <!-- :label="dict.label"-->
  27. <!-- :value="dict.value"-->
  28. <!-- />-->
  29. <!-- </el-select>-->
  30. <!-- </el-form-item>-->
  31. <el-form-item label="维保中心" prop="gxtCenter" label-position="top">
  32. <el-select
  33. v-model="queryParams.gxtCenter"
  34. placeholder="请选择维保中心"
  35. clearable
  36. @change="handleMaintenanceCenterChange"
  37. >
  38. <el-option
  39. v-for="item in maintenanceCenterOptions"
  40. :key="item.deptId"
  41. :label="item.deptName"
  42. :value="item.deptName">
  43. </el-option>
  44. </el-select>
  45. </el-form-item>
  46. <el-form-item label="场站" prop="pcsStationName" label-position="top">
  47. <el-select
  48. v-model="queryParams.pcsStationName"
  49. placeholder="请选择场站"
  50. clearable
  51. :disabled="!queryParams.gxtCenter"
  52. >
  53. <el-option
  54. v-for="item in stationOptions"
  55. :key="item.deptId"
  56. :label="item.deptName"
  57. :value="item.deptName">
  58. </el-option>
  59. </el-select>
  60. </el-form-item>
  61. <el-form-item label="工单状态" prop="workOrderStatus" label-position="top">
  62. <el-select v-model="queryParams.workOrderStatus" placeholder="请选择工单状态" clearable>
  63. <el-option
  64. v-for="dict in gxt_work_order_status"
  65. :key="dict.value"
  66. :label="dict.label"
  67. :value="dict.value"
  68. />
  69. </el-select>
  70. </el-form-item>
  71. <el-form-item label="故障代码" prop="faultCode" label-position="top">
  72. <el-input
  73. v-model="queryParams.faultCode"
  74. placeholder="请输入故障代码"
  75. clearable
  76. @keyup.enter="handleQuery"
  77. />
  78. </el-form-item>
  79. </el-form>
  80. <div style="float: right;">
  81. <el-button icon="Refresh" @click="resetQuery">重置</el-button>
  82. <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
  83. </div>
  84. <!-- 操作按钮区域 -->
  85. <el-row :gutter="10" class="mb8">
  86. <el-col :span="1.5">
  87. <el-button
  88. type="primary"
  89. plain
  90. icon="Plus"
  91. @click="handleAdd"
  92. v-hasPermi="['gxt:repairOrder:add']"
  93. >新建工单</el-button>
  94. </el-col>
  95. <el-col :span="1.5">
  96. <el-button
  97. type="info"
  98. icon="Upload"
  99. @click="handleImport"
  100. v-hasPermi="['gxt:repairOrder:import']"
  101. >导入维修工单</el-button>
  102. </el-col>
  103. <el-col :span="1.5">
  104. <el-button
  105. type="info"
  106. icon="Upload"
  107. @click="handleImportMis"
  108. v-hasPermi="['gxt:repairOrder:importMis']"
  109. >导入MIS工单</el-button>
  110. </el-col>
  111. <el-col :span="1.5">
  112. <el-button
  113. type="warning"
  114. icon="Download"
  115. @click="handleExport"
  116. v-hasPermi="['gxt:repairOrder:export']"
  117. >导出</el-button>
  118. </el-col>
  119. <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
  120. </el-row>
  121. <!-- 工单列表 -->
  122. <el-table
  123. v-loading="loading"
  124. :data="repairOrderList"
  125. @selection-change="handleSelectionChange"
  126. style="width: 100%"
  127. :max-height="tableHeight"
  128. >
  129. <el-table-column type="selection" width="55" align="center" fixed />
  130. <el-table-column label="工单编码" align="center" prop="workOrderProjectNo" width="160" fixed>
  131. <template #default="scope">
  132. <el-button link type="primary" @click="handleView(scope.row)">
  133. {{ scope.row.workOrderProjectNo }}
  134. </el-button>
  135. </template>
  136. </el-table-column>
  137. <el-table-column label="风机编号" align="center" prop="pcsDeviceName" width="120" :show-overflow-tooltip="true">
  138. <template #default="scope">
  139. {{ scope.row.pcsDeviceName || '-' }}
  140. </template>
  141. </el-table-column>
  142. <!-- <el-table-column label="检修类型" align="center" prop="maintenanceType" min-width="100">-->
  143. <!-- <template #default="scope">-->
  144. <!-- <dict-tag :options="gxt_maintenance_type" :value="scope.row.maintenanceType" />-->
  145. <!-- </template>-->
  146. <!-- </el-table-column>-->
  147. <el-table-column label="工单状态" align="center" prop="workOrderStatus" min-width="100">
  148. <template #default="scope">
  149. <dict-tag :options="gxt_work_order_status" :value="scope.row.workOrderStatus" />
  150. </template>
  151. </el-table-column>
  152. <el-table-column label="维保中心" align="center" prop="gxtCenter" width="150" :show-overflow-tooltip="true">
  153. <template #default="scope">
  154. {{ scope.row.gxtCenter || '-' }}
  155. </template>
  156. </el-table-column>
  157. <el-table-column label="场站" align="center" prop="pcsStationName" width="150" :show-overflow-tooltip="true">
  158. <template #default="scope">
  159. {{ scope.row.pcsStationName || '-' }}
  160. </template>
  161. </el-table-column>
  162. <el-table-column label="品牌" align="center" prop="brand" width="120" :show-overflow-tooltip="true">
  163. <template #default="scope">
  164. {{ scope.row.brand || '-' }}
  165. </template>
  166. </el-table-column>
  167. <el-table-column label="机型" align="center" prop="model" width="120" :show-overflow-tooltip="true">
  168. <template #default="scope">
  169. {{ scope.row.model || '-' }}
  170. </template>
  171. </el-table-column>
  172. <el-table-column label="故障代码" align="center" prop="faultCode" width="120" :show-overflow-tooltip="true">
  173. <template #default="scope">
  174. {{ scope.row.faultCode || '-' }}
  175. </template>
  176. </el-table-column>
  177. <el-table-column label="发生时间" align="center" prop="occurTime" width="150" >
  178. <template #default="scope">
  179. <span>{{ scope.row.occurTime ? parseTime(scope.row.occurTime, '{y}-{m}-{d} {h}:{i}') : '-' }}</span>
  180. </template>
  181. </el-table-column>
  182. <el-table-column label="MIS工单编码" align="center" prop="misOrderNo" width="150" :show-overflow-tooltip="true">
  183. <template #default="scope">
  184. {{ scope.row.misOrderNo || '-' }}
  185. </template>
  186. </el-table-column>
  187. <el-table-column label="下发人" align="center" prop="assignUserName" width="100" >
  188. <template #default="scope">
  189. {{ scope.row.assignUserName || '-' }}
  190. </template>
  191. </el-table-column>
  192. <el-table-column label="下发时间" align="center" prop="assignTime" width="150">
  193. <template #default="scope">
  194. <span>{{ scope.row.assignTime ? parseTime(scope.row.assignTime, '{y}-{m}-{d} {h}:{i}') : '-' }}</span>
  195. </template>
  196. </el-table-column>
  197. <el-table-column label="接单人" align="center" prop="acceptUserName" width="100" >
  198. <template #default="scope">
  199. {{ scope.row.acceptUserName || '-' }}
  200. </template>
  201. </el-table-column>
  202. <el-table-column label="接单时间" align="center" prop="acceptTime" width="150">
  203. <template #default="scope">
  204. <span>{{ scope.row.acceptTime ? parseTime(scope.row.acceptTime, '{y}-{m}-{d} {h}:{i}') : '-' }}</span>
  205. </template>
  206. </el-table-column>
  207. <el-table-column label="工作负责人" align="center" prop="teamLeaderName" width="100" >
  208. <template #default="scope">
  209. {{ scope.row.teamLeaderName || '-' }}
  210. </template>
  211. </el-table-column>
  212. <el-table-column label="开始时间" align="center" prop="realStartTime" width="150">
  213. <template #default="scope">
  214. <span>{{ scope.row.realStartTime ? parseTime(scope.row.realStartTime, '{y}-{m}-{d} {h}:{i}') : '-' }}</span>
  215. </template>
  216. </el-table-column>
  217. <el-table-column label="结束时间" align="center" prop="realEndTime" width="150">
  218. <template #default="scope">
  219. <span>{{ scope.row.realEndTime ? parseTime(scope.row.realEndTime, '{y}-{m}-{d} {h}:{i}') : '-' }}</span>
  220. </template>
  221. </el-table-column>
  222. <!-- <el-table-column label="优先级" align="center" prop="priorityType" min-width="100">
  223. <template #default="scope">
  224. <dict-tag :options="gxt_order_priority_type" :value="scope.row.priorityType" />
  225. </template>
  226. </el-table-column>-->
  227. <el-table-column label="操作" align="center" class-name="small-padding fixed-width" min-width="250" fixed="right">
  228. <template #default="scope">
  229. <!-- <el-button-->
  230. <!-- v-if="scope.row.workOrderStatus === 'to_issue'"-->
  231. <!-- type="primary"-->
  232. <!-- link-->
  233. <!-- @click="handleEdit(scope.row)"-->
  234. <!-- v-hasPermi="['gxt:repairOrder:edit']"-->
  235. <!-- ><i class="fa fa-edit"></i>编辑</el-button>-->
  236. <!-- <el-button-->
  237. <!-- v-if="scope.row.workOrderStatus === 'to_issue'"-->
  238. <!-- type="primary"-->
  239. <!-- link-->
  240. <!-- @click="handleAssign(scope.row)"-->
  241. <!-- v-hasPermi="['gxt:repairOrder:assign']"-->
  242. <!-- ><i class="fa fa-user-plus"></i>下发</el-button>-->
  243. <el-button
  244. v-if="scope.row.workOrderStatus === 'to_issue'"
  245. type="primary"
  246. link
  247. @click="handleEdit(scope.row)"
  248. v-hasPermi="['gxt:repairOrder:edit']"
  249. ><i class="fa fa-user-plus"></i>下发</el-button>
  250. <el-button
  251. v-if="scope.row.workOrderStatus === 'assigned'"
  252. type="primary"
  253. link
  254. @click="handleAccept(scope.row)"
  255. v-hasPermi="['gxt:repairOrder:accept']"
  256. ><i class="fa fa-check"></i>接单</el-button>
  257. <el-button
  258. v-if="scope.row.workOrderStatus === 'suspended'"
  259. type="primary"
  260. link
  261. @click="handleResume(scope.row)"
  262. v-hasPermi="['gxt:repairOrder:resume']"
  263. ><i class="fa fa-play"></i>恢复</el-button>
  264. <el-button
  265. v-if="scope.row.workOrderStatus === 'to_finish'"
  266. type="danger"
  267. link
  268. @click="handleSuspend(scope.row)"
  269. v-hasPermi="['gxt:repairOrder:suspend']"
  270. ><i class="fa fa-stop"></i>挂起</el-button>
  271. <!-- <el-button
  272. v-if="scope.row.workOrderStatus === 'processing'"
  273. type="warning"
  274. link
  275. @click="handlePause(scope.row)"
  276. >暂停</el-button>-->
  277. <!-- <el-button
  278. v-if="scope.row.workOrderStatus === 'processing'"
  279. type="success"
  280. link
  281. @click="handleProcessDone(scope.row)"
  282. >结束</el-button>-->
  283. <el-button
  284. v-if="scope.row.workOrderStatus === 'to_finish' && (scope.row.teamLeaderId == userStore.id || userStore.roles.includes('admin'))"
  285. type="success"
  286. link
  287. @click="handleFinalize(scope.row)"
  288. v-hasPermi="['gxt:repairOrder:finalize']"
  289. ><i class="fa fa-check"></i>结单</el-button>
  290. <el-button
  291. v-if="scope.row.workOrderStatus === 'to_approve'"
  292. type="primary"
  293. link
  294. @click="handleApprove(scope.row)"
  295. v-hasPermi="['gxt:repairOrder:approve']"
  296. ><i class="fa fa-check-circle"></i>审批</el-button>
  297. <!-- <el-button
  298. v-if="scope.row.workOrderStatus === 'paused' || scope.row.workOrderStatus === 'suspended'"
  299. type="primary"
  300. link
  301. @click="handleResume(scope.row)"
  302. >恢复</el-button>-->
  303. <!-- <el-button-->
  304. <!-- v-if="scope.row.workOrderStatus === 'completed' && !scope.row.score"-->
  305. <!-- type="warning"-->
  306. <!-- link-->
  307. <!-- @click="handleRating(scope.row)"-->
  308. <!-- v-hasPermi="['gxt:repairOrder:rating']"-->
  309. <!-- ><i class="fa fa-star"></i>评分</el-button>-->
  310. <el-button
  311. v-if="scope.row.workOrderStatus === 'completed'"
  312. type="success"
  313. link
  314. @click="handleRestart(scope.row)"
  315. v-hasPermi="['gxt:repairOrder:restart']"
  316. ><i class="fa fa-refresh"></i>复运</el-button>
  317. <el-button
  318. type="info"
  319. link
  320. @click="handleView(scope.row)"
  321. v-hasPermi="['gxt:repairOrder:query']"
  322. ><i class="fa fa-eye"></i>查看</el-button>
  323. <el-button
  324. v-if="scope.row.workOrderStatus === 'to_issue'"
  325. type="danger"
  326. link
  327. @click="handleDelete(scope.row)"
  328. v-hasPermi="['gxt:repairOrder:remove']"
  329. ><i class="fa fa-trash"></i>删除</el-button>
  330. </template>
  331. </el-table-column>
  332. </el-table>
  333. <pagination
  334. v-show="total>0"
  335. :total="total"
  336. v-model:page="queryParams.pageNum"
  337. v-model:limit="queryParams.pageSize"
  338. @pagination="getList"
  339. />
  340. <!-- 新建/编辑工单对话框 -->
  341. <el-dialog :title="dialogTitle" v-model="openDialog" width="800px" append-to-body @close="cancel">
  342. <el-form ref="repairOrderRef" :model="form" :rules="rules" label-width="120px" label-position="top">
  343. <el-row>
  344. <el-col :span="12">
  345. <el-form-item label="工单编码" prop="workOrderProjectNo" >
  346. <el-input v-model="form.workOrderProjectNo" placeholder="请输入工单编码" :disabled="!!form.id" readonly maxlength="50" show-word-limit v-chinese-limit/>
  347. </el-form-item>
  348. </el-col>
  349. <el-col :span="12">
  350. <el-form-item label="风机编号" prop="pcsDeviceName">
  351. <el-input v-model="form.pcsDeviceName" placeholder="请选择风机编号" readonly>
  352. <template #append>
  353. <el-button @click="handleSelectEquipment" icon="Search"></el-button>
  354. </template>
  355. </el-input>
  356. </el-form-item>
  357. </el-col>
  358. </el-row>
  359. <el-row>
  360. <el-col :span="12">
  361. <el-form-item label="维保中心" prop="gxtCenter">
  362. <el-input v-model="form.gxtCenter" placeholder="请选择风机编号自动填充" readonly />
  363. </el-form-item>
  364. </el-col>
  365. <el-col :span="12">
  366. <el-form-item label="场站" prop="pcsStationName">
  367. <el-input v-model="form.pcsStationName" placeholder="请选择风机编号自动填充" readonly />
  368. </el-form-item>
  369. </el-col>
  370. </el-row>
  371. <el-row>
  372. <el-col :span="12">
  373. <el-form-item label="品牌" prop="brand">
  374. <el-input v-model="form.brand" placeholder="请选择风机编号自动填充" readonly />
  375. </el-form-item>
  376. </el-col>
  377. <el-col :span="12">
  378. <el-form-item label="机型" prop="model">
  379. <el-input v-model="form.model" placeholder="请选择风机编号自动填充" readonly />
  380. </el-form-item>
  381. </el-col>
  382. </el-row>
  383. <el-row>
  384. <el-col :span="12">
  385. <el-form-item label="发生时间" prop="occurTime">
  386. <el-date-picker
  387. v-model="form.occurTime"
  388. type="datetime"
  389. format="YYYY-MM-DD HH:mm"
  390. value-format="YYYY-MM-DD HH:mm"
  391. placeholder="请选择发生时间"
  392. style="width: 100%"
  393. />
  394. </el-form-item>
  395. </el-col>
  396. <el-col :span="12">
  397. <el-form-item label="故障代码" prop="faultCode">
  398. <el-input
  399. v-model="form.faultCode"
  400. placeholder="请输入故障代码"
  401. maxlength="20"
  402. show-word-limit
  403. />
  404. </el-form-item>
  405. </el-col>
  406. </el-row>
  407. <el-row>
  408. <el-col :span="24">
  409. <el-form-item label="故障信息" prop="faultBarcode">
  410. <el-input
  411. v-model="form.faultBarcode"
  412. type="textarea"
  413. placeholder="请输入故障信息"
  414. maxlength="100"
  415. show-word-limit
  416. :rows="3"
  417. />
  418. </el-form-item>
  419. </el-col>
  420. </el-row>
  421. <!-- <el-row>
  422. <el-col :span="24">
  423. <el-form-item label="故障描述" prop="faultDesc">
  424. <el-input
  425. v-model="form.faultDesc"
  426. type="textarea"
  427. placeholder="请输入故障描述"
  428. maxlength="500"
  429. show-word-limit
  430. :rows="3"
  431. />
  432. </el-form-item>
  433. </el-col>
  434. </el-row>-->
  435. <!-- <el-row>
  436. <el-col :span="24">
  437. <el-form-item label="图片">
  438. <image-upload :limit="10" v-model="form.workUrl" :fileSize="5"></image-upload>
  439. </el-form-item>
  440. </el-col>
  441. </el-row> -->
  442. </el-form>
  443. <template #footer>
  444. <div class="dialog-footer">
  445. <el-button @click="cancel">取 消</el-button>
  446. <el-button type="primary" @click="submitForm" v-if="optType == 'add'">保 存</el-button>
  447. <el-button type="primary" @click="submitFormAndIssue" v-if="!form.workOrderStatus">保存并下发</el-button>
  448. <el-button type="primary" @click="submitFormAndIssue" v-if="optType == 'edit'">确认下发</el-button>
  449. </div>
  450. </template>
  451. </el-dialog>
  452. <!-- 下发对话框 -->
  453. <el-dialog title="下发" v-model="assignDialogVisible" width="800px" append-to-body @close="closeAssignDialog">
  454. <el-form ref="assignFormRef" :model="assignForm" label-width="120px" label-position="top">
  455. <el-row>
  456. <el-col :span="12">
  457. <el-form-item label="工单编码"><el-input v-model="assignForm.workOrderProjectNo" disabled /></el-form-item>
  458. </el-col>
  459. <el-col :span="12">
  460. <el-form-item label="风机编号"><el-input v-model="assignForm.pcsDeviceName" disabled /></el-form-item>
  461. </el-col>
  462. <!-- <el-col :span="12">
  463. <el-form-item label="检修类型">
  464. <dict-tag :options="gxt_maintenance_type" :value="assignForm.maintenanceType" />
  465. </el-form-item>
  466. </el-col>-->
  467. <el-col :span="12">
  468. <el-form-item label="工单状态">
  469. <el-select v-model="assignForm.workOrderStatus" style="width: 100%" disabled>
  470. <el-option
  471. v-for="dict in gxt_work_order_status"
  472. :key="dict.value"
  473. :label="dict.label"
  474. :value="dict.value"
  475. />
  476. </el-select>
  477. </el-form-item>
  478. </el-col>
  479. <el-col :span="12">
  480. <el-form-item label="维保中心"><el-input v-model="assignForm.gxtCenter" disabled /></el-form-item>
  481. </el-col>
  482. <el-col :span="12">
  483. <el-form-item label="场站"><el-input v-model="assignForm.pcsStationName" disabled /></el-form-item>
  484. </el-col>
  485. <el-col :span="12">
  486. <el-form-item label="品牌"><el-input v-model="assignForm.brand" disabled /> </el-form-item>
  487. </el-col>
  488. <el-col :span="12">
  489. <el-form-item label="故障代码"><el-input v-model="assignForm.faultCode" disabled /></el-form-item>
  490. </el-col>
  491. <el-col :span="24">
  492. <el-form-item label="故障信息">
  493. <el-input
  494. v-model="assignForm.faultBarcode"
  495. type="textarea"
  496. placeholder="请输入故障信息"
  497. maxlength="100"
  498. show-word-limit
  499. :rows="3"
  500. disabled
  501. /></el-form-item>
  502. </el-col>
  503. </el-row>
  504. <!-- <el-form-item label="关联维保工单">
  505. <el-select
  506. v-model="assignForm.relatedOrderCode"
  507. filterable
  508. remote
  509. reserve-keyword
  510. placeholder="请输入关联维保工单编码"
  511. :remote-method="searchWorkOrders"
  512. :loading="workOrderSearchLoading"
  513. @change="handleWorkOrderChange"
  514. >
  515. <el-option
  516. v-for="item in workOrderOptions"
  517. :key="item.id"
  518. :label="item.workOrderProjectNo"
  519. :value="item.workOrderProjectNo"
  520. :data-content="item.content"
  521. >
  522. <span style="float: left">{{ item.workOrderProjectNo }}</span>
  523. <span style="float: right; color: #8492a6; font-size: 13px">{{ item.content }}</span>
  524. </el-option>
  525. </el-select>
  526. </el-form-item>
  527. <el-form-item
  528. v-if="assignForm.relatedOrderCode"
  529. label="维保内容"
  530. prop="relatedOrderContent">
  531. <el-input
  532. v-model="assignForm.relatedOrderContent"
  533. type="textarea"
  534. placeholder="请输入维保内容"
  535. maxlength="500"
  536. show-word-limit
  537. :rows="3"
  538. readonly
  539. />
  540. </el-form-item>-->
  541. </el-form>
  542. <template #footer>
  543. <div class="dialog-footer">
  544. <el-button @click="closeAssignDialog">取 消</el-button>
  545. <el-button type="primary" @click="submitAssign">确认下发</el-button>
  546. </div>
  547. </template>
  548. </el-dialog>
  549. <!-- 接单对话框 -->
  550. <el-dialog title="接单" v-model="acceptDialogVisible" width="800px" append-to-body @close="closeAcceptDialog">
  551. <el-form ref="acceptFormRef" :model="acceptForm" :rules="acceptRules" label-width="120px" label-position="top">
  552. <el-row>
  553. <el-col :span="12">
  554. <el-form-item label="工单编码"><el-input v-model="acceptForm.workOrderProjectNo" disabled /></el-form-item>
  555. </el-col>
  556. <el-col :span="12">
  557. <el-form-item label="风机编号"><el-input v-model="acceptForm.pcsDeviceName" disabled /></el-form-item>
  558. </el-col>
  559. <el-col :span="12">
  560. <el-form-item label="工单状态">
  561. <el-select v-model="acceptForm.workOrderStatus" style="width: 100%" disabled>
  562. <el-option
  563. v-for="dict in gxt_work_order_status"
  564. :key="dict.value"
  565. :label="dict.label"
  566. :value="dict.value"
  567. />
  568. </el-select>
  569. </el-form-item>
  570. </el-col>
  571. <el-col :span="12">
  572. <el-form-item label="维保中心"><el-input v-model="acceptForm.gxtCenter" disabled /> </el-form-item>
  573. </el-col>
  574. <el-col :span="12">
  575. <el-form-item label="场站"><el-input v-model="acceptForm.pcsStationName" disabled /> </el-form-item>
  576. </el-col>
  577. <el-col :span="12">
  578. <el-form-item label="品牌"><el-input v-model="acceptForm.brand" disabled /> </el-form-item>
  579. </el-col>
  580. <el-col :span="12">
  581. <el-form-item label="故障代码"><el-input v-model="acceptForm.faultCode" disabled /></el-form-item>
  582. </el-col>
  583. <el-col :span="24">
  584. <el-form-item label="故障信息">
  585. <el-input
  586. v-model="acceptForm.faultBarcode"
  587. type="textarea"
  588. placeholder="请输入故障信息"
  589. maxlength="100"
  590. show-word-limit
  591. :rows="3"
  592. disabled
  593. />
  594. </el-form-item>
  595. </el-col>
  596. </el-row>
  597. <el-row>
  598. <el-col :span="12">
  599. <el-form-item label="工作负责人" prop="teamLeaderId">
  600. <!-- <el-select v-model="acceptForm.teamLeaderId" placeholder="请选择工作负责人" style="width: 100%" @change="(userId) => acceptForm.teamLeaderName = userList.find(u => u.userId === userId)?.nickName">-->
  601. <!-- <el-option-->
  602. <!-- v-for="user in userList"-->
  603. <!-- :key="user.userId"-->
  604. <!-- :label="user.nickName"-->
  605. <!-- :value="user.userId"-->
  606. <!-- />-->
  607. <!-- </el-select>-->
  608. <el-input
  609. v-model="acceptForm.teamLeaderName"
  610. placeholder="请输入工作负责人姓名或点击选择"
  611. clearable
  612. @focus="handleTeamLeaderInputFocus"
  613. @blur="handleTeamLeaderInputBlur"
  614. @input="handleTeamLeaderInput"
  615. @clear="handleTeamLeaderClear"
  616. >
  617. </el-input>
  618. <!-- 快速检索下拉框 -->
  619. <div class="quick-select-dropdown" v-show="showTeamLeaderQuickSelect && quickTeamLeaderList.length > 0">
  620. <div
  621. v-for="item in quickTeamLeaderList"
  622. :key="item.userId"
  623. class="quick-select-item"
  624. @click="handleTeamLeaderQuickSelect(item)">
  625. <span class="user-name">{{ item.nickName }}</span>
  626. <span class="user-name">{{ item.dept.deptName }}</span>
  627. </div>
  628. </div>
  629. <div class="quick-select-dropdown no-data" v-show="showTeamLeaderQuickSelect && quickTeamLeaderList.length === 0 && acceptForm.teamLeaderName && !teamLeaderLoading">
  630. <div>未找到匹配的人员</div>
  631. </div>
  632. <div class="quick-select-dropdown no-data" v-show="showTeamLeaderQuickSelect && teamLeaderLoading">
  633. <div>
  634. <i class="el-icon-loading"></i>
  635. 搜索中...
  636. </div>
  637. </div>
  638. </el-form-item>
  639. </el-col>
  640. </el-row>
  641. </el-form>
  642. <template #footer>
  643. <div class="dialog-footer">
  644. <el-button @click="closeAcceptDialog">取 消</el-button>
  645. <el-button type="primary" @click="submitAccept">确认接单</el-button>
  646. </div>
  647. </template>
  648. </el-dialog>
  649. <!-- 挂起对话框 -->
  650. <el-dialog title="申请挂起工单" v-model="suspendDialogVisible" width="800px" append-to-body @close="closeSuspendDialog">
  651. <el-form ref="suspendFormRef" :model="suspendForm" :rules="suspendRules" label-width="120px" label-position="top">
  652. <el-alert type="warning" :closable="false" title="请选择挂起原因,提交后需等待班长审批。" show-icon />
  653. <el-row>
  654. <el-col :span="12">
  655. <el-form-item label="工单编码">
  656. <el-input v-model="suspendForm.workOrderProjectNo" disabled />
  657. </el-form-item>
  658. </el-col>
  659. <el-col :span="12">
  660. <el-form-item label="风机编号">
  661. <el-input v-model="suspendForm.pcsDeviceName" disabled />
  662. </el-form-item>
  663. </el-col>
  664. <el-col :span="24" v-if="suspendForm.faultBarcode">
  665. <el-form-item label="故障信息">
  666. <el-input v-model="suspendForm.faultBarcode" type="textarea" :rows="3" disabled />
  667. </el-form-item>
  668. </el-col>
  669. <!-- <el-form-item label="挂起原因" prop="suspendReason">
  670. <el-input
  671. v-model="suspendForm.suspendReason"
  672. type="textarea"
  673. placeholder="请输入挂起原因"
  674. maxlength="100"
  675. show-word-limit
  676. :rows="3"
  677. />
  678. </el-form-item>-->
  679. <el-col :span="12">
  680. <el-form-item label="挂起原因" prop="suspendReason">
  681. <el-select v-model="suspendForm.suspendReason" placeholder="请选择挂起原因" style="width: 100%">
  682. <el-option
  683. v-for="dict in gxt_order_suspend_reason"
  684. :key="dict.value"
  685. :label="dict.label"
  686. :value="dict.value"
  687. />
  688. </el-select>
  689. </el-form-item>
  690. </el-col>
  691. </el-row>
  692. <!--
  693. <el-form-item label="详细说明" prop="suspendDescription">
  694. <el-input
  695. v-model="suspendForm.suspendDescription"
  696. type="textarea"
  697. placeholder="请输入详细说明"
  698. maxlength="100"
  699. show-word-limit
  700. :rows="3"
  701. />
  702. </el-form-item>-->
  703. </el-form>
  704. <template #footer>
  705. <div class="dialog-footer">
  706. <el-button @click="closeSuspendDialog">取 消</el-button>
  707. <el-button type="primary" @click="submitSuspend">提交申请</el-button>
  708. </div>
  709. </template>
  710. </el-dialog>
  711. <!-- 审批对话框 -->
  712. <el-dialog title="审批挂起申请" v-model="approveDialogVisible" width="800px" append-to-body @close="closeApproveDialog">
  713. <el-alert type="info" :closable="false" style="border-color: #a855f7; background-color: #f8f5ff; color: #6d28d9; height: 35px;">
  714. <template #default>
  715. <i class="fa fa-edit mr-2" style="color: #6d28d9;"> 请审批该工单的挂起申请,选择通过或驳回。</i>
  716. </template>
  717. </el-alert>
  718. <!-- 工单信息 -->
  719. <h3 class="text-sm font-medium text-gray-800 mb-3"></h3>
  720. <el-form ref="approveFormRef" :model="approveForm" :rules="approveRules" label-width="120px" label-position="top">
  721. <el-row>
  722. <el-col :span="12">
  723. <el-form-item label="工单编码"><el-input v-model="approveForm.workOrderProjectNo" disabled /></el-form-item>
  724. </el-col>
  725. <el-col :span="12">
  726. <el-form-item label="风机编号"><el-input v-model="approveForm.pcsDeviceName" disabled /> </el-form-item>
  727. </el-col>
  728. <el-col :span="12">
  729. <el-form-item label="工单状态">
  730. <el-select v-model="approveForm.workOrderStatus" style="width: 100%" disabled>
  731. <el-option
  732. v-for="dict in gxt_work_order_status"
  733. :key="dict.value"
  734. :label="dict.label"
  735. :value="dict.value"
  736. />
  737. </el-select>
  738. </el-form-item>
  739. </el-col>
  740. <el-col :span="12">
  741. <el-form-item label="维保中心"><el-input v-model="approveForm.gxtCenter" disabled /> </el-form-item>
  742. </el-col>
  743. <el-col :span="12">
  744. <el-form-item label="场站"><el-input v-model="approveForm.pcsStationName" disabled /> </el-form-item>
  745. </el-col>
  746. <el-col :span="12">
  747. <el-form-item label="品牌"><el-input v-model="approveForm.brand" disabled /> </el-form-item>
  748. </el-col>
  749. <el-col :span="12">
  750. <el-form-item label="故障代码"><el-input v-model="approveForm.faultCode" disabled /> </el-form-item>
  751. </el-col>
  752. <el-col :span="24">
  753. <el-form-item label="故障信息">
  754. <el-input
  755. v-model="approveForm.faultBarcode"
  756. type="textarea"
  757. placeholder="请输入故障信息"
  758. maxlength="100"
  759. show-word-limit
  760. :rows="3"
  761. disabled
  762. />
  763. </el-form-item>
  764. </el-col>
  765. <!-- <el-col :span="12">-->
  766. <!-- <el-form-item label="下发人"><el-input v-model="approveForm.assignUserName" disabled /></el-form-item>-->
  767. <!-- </el-col>-->
  768. <!-- <el-col :span="12">-->
  769. <!-- <el-form-item label="下发时间"><el-input v-model="approveForm.assignTime" disabled /></el-form-item>-->
  770. <!-- </el-col>-->
  771. <!-- <el-col :span="12">-->
  772. <!-- <el-form-item label="接单人"><el-input v-model="approveForm.acceptUserName" disabled /> </el-form-item>-->
  773. <!-- </el-col>-->
  774. <!-- <el-col :span="12">-->
  775. <!-- <el-form-item label="接单时间"><el-input v-model="approveForm.acceptTime" disabled /> </el-form-item>-->
  776. <!-- </el-col>-->
  777. <el-col :span="12">
  778. <el-form-item label="工作负责人"><el-input v-model="approveForm.teamLeaderName" disabled /> </el-form-item>
  779. </el-col>
  780. <el-col :span="12">
  781. <el-form-item label="挂起原因">
  782. <el-select v-model="approveForm.suspendReason" style="width: 100%" disabled>
  783. <el-option
  784. v-for="dict in gxt_order_suspend_reason"
  785. :key="dict.value"
  786. :label="dict.label"
  787. :value="dict.value"
  788. />
  789. </el-select>
  790. </el-form-item>
  791. </el-col>
  792. </el-row>
  793. <!-- <el-form-item label="审批决定" prop="approvalStatus">
  794. <el-radio-group v-model="approveForm.approvalStatus" @change="toggleRejectionReason">
  795. <el-radio label="approved">通过</el-radio>
  796. <el-radio label="rejected">驳回</el-radio>
  797. </el-radio-group>
  798. </el-form-item>-->
  799. <el-form-item label="审批意见" prop="rejectionReason">
  800. <el-input
  801. v-model="approveForm.rejectionReason"
  802. type="textarea"
  803. placeholder="请输入审批意见"
  804. maxlength="100"
  805. show-word-limit
  806. :rows="3"
  807. />
  808. </el-form-item>
  809. </el-form>
  810. <template #footer>
  811. <div class="dialog-footer">
  812. <el-button @click="closeApproveDialog">取 消</el-button>
  813. <el-button type="primary" @click="submitApprove('rejected')">驳 回</el-button>
  814. <el-button type="primary" @click="submitApprove('approved')">通 过</el-button>
  815. </div>
  816. </template>
  817. </el-dialog>
  818. <!-- 结单对话框 -->
  819. <el-dialog title="结单" v-model="finalizeDialogVisible" width="800px" append-to-body @close="closeFinalizeDialog">
  820. <el-alert type="info" :closable="false" style="border-color: #14b8a6; background-color: #f0fdfa; color: #0d9488; height: 35px;">
  821. <template #default>
  822. <i class="fa fa-file-text-o mr-2" style="color: #0d9488;"> 请上传相关附件完成结单。</i>
  823. </template>
  824. </el-alert>
  825. <h4 class="text-sm font-medium text-gray-800 mb-3"></h4>
  826. <el-form ref="finalizeFormRef" :model="finalizeForm" :rules="finalizeRules" label-width="120px" label-position="top">
  827. <el-row>
  828. <el-col :span="12">
  829. <el-form-item label="工单编码"><el-input v-model="finalizeForm.workOrderProjectNo" disabled /></el-form-item>
  830. </el-col>
  831. <el-col :span="12">
  832. <el-form-item label="风机编号"><el-input v-model="finalizeForm.pcsDeviceName" disabled /></el-form-item>
  833. </el-col>
  834. <el-col :span="12">
  835. <el-form-item label="工单状态">
  836. <el-select v-model="finalizeForm.workOrderStatus" style="width: 100%" disabled>
  837. <el-option
  838. v-for="dict in gxt_work_order_status"
  839. :key="dict.value"
  840. :label="dict.label"
  841. :value="dict.value"
  842. />
  843. </el-select>
  844. </el-form-item>
  845. </el-col>
  846. <el-col :span="12">
  847. <el-form-item label="维保中心"><el-input v-model="finalizeForm.gxtCenter" disabled /> </el-form-item>
  848. </el-col>
  849. <el-col :span="12">
  850. <el-form-item label="场站"><el-input v-model="finalizeForm.pcsStationName" disabled /> </el-form-item>
  851. </el-col>
  852. <el-col :span="12">
  853. <el-form-item label="品牌"><el-input v-model="finalizeForm.brand" disabled /> </el-form-item>
  854. </el-col>
  855. <el-col :span="12">
  856. <el-form-item label="故障代码"><el-input v-model="finalizeForm.faultCode" disabled /> </el-form-item>
  857. </el-col>
  858. <el-col :span="24">
  859. <el-form-item label="故障信息">
  860. <el-input
  861. v-model="finalizeForm.faultBarcode"
  862. type="textarea"
  863. placeholder="请输入故障信息"
  864. maxlength="100"
  865. show-word-limit
  866. :rows="3"
  867. disabled
  868. />
  869. </el-form-item>
  870. </el-col>
  871. <el-col :span="12">
  872. <el-form-item label="下发人"><el-input v-model="finalizeForm.assignUserName" disabled /> </el-form-item>
  873. </el-col>
  874. <el-col :span="12">
  875. <el-form-item label="下发时间"><el-input v-model="finalizeForm.assignTime" disabled /> </el-form-item>
  876. </el-col>
  877. <el-col :span="12">
  878. <el-form-item label="接单人"><el-input v-model="finalizeForm.acceptUserName" disabled /> </el-form-item>
  879. </el-col>
  880. <el-col :span="12">
  881. <el-form-item label="接单时间"><el-input v-model="finalizeForm.acceptTime" disabled /> </el-form-item>
  882. </el-col>
  883. <el-col :span="12">
  884. <el-form-item label="工作负责人"><el-input v-model="finalizeForm.teamLeaderName" disabled /> </el-form-item>
  885. </el-col>
  886. <!-- <el-col :span="12">-->
  887. <!-- <el-form-item label="MIS工单编码" prop="misOrderNo">-->
  888. <!-- <el-input-->
  889. <!-- v-model="finalizeForm.misOrderNo"-->
  890. <!-- placeholder="请输入MIS工单编码"-->
  891. <!-- maxlength="50"-->
  892. <!-- show-word-limit-->
  893. <!-- v-chinese-limit-->
  894. <!-- @blur="handleMisOrderNoBlur"-->
  895. <!-- />-->
  896. <!-- </el-form-item>-->
  897. <!-- </el-col>-->
  898. <el-col :span="12">
  899. <el-form-item label="MIS工单编码" prop="misOrderNo">
  900. <el-input
  901. v-model="finalizeForm.misOrderNo"
  902. placeholder="请输入MIS工单编码或点击搜索选择"
  903. clearable
  904. @focus="handleMisNoInputFocus"
  905. @blur="handleMisNoInputBlur"
  906. @input="handleMisNoInput"
  907. @clear="handleMisNoClear"
  908. >
  909. <template #append>
  910. <el-button @click="handleSelectMisInfo" icon="Search"></el-button>
  911. </template>
  912. </el-input>
  913. <!-- 快速检索下拉框 -->
  914. <div class="quick-select-dropdown" v-show="showMisNoQuickSelect && quickMisNoList.length > 0">
  915. <div
  916. v-for="item in quickMisNoList"
  917. :key="item.misNo"
  918. class="quick-select-item"
  919. @click="handleMisNoQuickSelect(item)">
  920. <span class="mis-no">{{ item.misNo }}</span>
  921. </div>
  922. </div>
  923. <div class="quick-select-dropdown no-data" v-show="showMisNoQuickSelect && quickMisNoList.length === 0 && form.misNo">
  924. <div>未找到匹配的MIS工单</div>
  925. </div>
  926. </el-form-item>
  927. </el-col>
  928. <!-- MIS选择组件 -->
  929. <MisInfoSelectSingle :key="commonKey" v-model="misInfoSelectVisible" @onSelected="onMisInfoSelected" :pcsStationName="finalizeForm.pcsStationName" :pcsDeviceName="finalizeForm.pcsDeviceName"></MisInfoSelectSingle>
  930. <el-col :span="12">
  931. <!-- <el-form-item label="开始时间">{{ parseTime(finalizeForm.realStartTime, '{y}-{m}-{d} {h}:{i}') }}</el-form-item>-->
  932. <el-form-item label="开始时间" prop="realStartTime">
  933. <el-date-picker
  934. v-model="finalizeForm.realStartTime"
  935. type="datetime"
  936. format="YYYY-MM-DD HH:mm"
  937. value-format="YYYY-MM-DD HH:mm"
  938. placeholder="请选择开始时间"
  939. style="width: 100%"
  940. :disabled="getMisDataConfig === '1'"
  941. readonly
  942. />
  943. </el-form-item>
  944. </el-col>
  945. <el-col :span="12">
  946. <!-- <el-form-item label="结束时间">{{ parseTime(finalizeForm.realEndTime, '{y}-{m}-{d} {h}:{i}') }}</el-form-item>-->
  947. <el-form-item label="结束时间" prop="realEndTime">
  948. <el-date-picker
  949. v-model="finalizeForm.realEndTime"
  950. type="datetime"
  951. format="YYYY-MM-DD HH:mm"
  952. value-format="YYYY-MM-DD HH:mm"
  953. placeholder="请选择结束时间"
  954. style="width: 100%"
  955. :disabled="getMisDataConfig === '1'"
  956. readonly
  957. />
  958. </el-form-item>
  959. </el-col>
  960. <!-- <el-col :span="12">
  961. <el-form-item label="故障描述">{{ finalizeForm.faultDesc || '无' }}</el-form-item>
  962. </el-col>-->
  963. <!-- <el-col :span="12">-->
  964. <!-- <el-form-item label="检修类型" prop="maintenanceType">-->
  965. <!-- <el-select v-model="finalizeForm.maintenanceType" placeholder="请选择检修类型" style="width: 100%">-->
  966. <!-- <el-option-->
  967. <!-- v-for="dict in gxt_maintenance_type"-->
  968. <!-- :key="dict.value"-->
  969. <!-- :label="dict.label"-->
  970. <!-- :value="dict.value"-->
  971. <!-- />-->
  972. <!-- </el-select>-->
  973. <!-- </el-form-item>-->
  974. <!-- </el-col>-->
  975. <!-- <el-col :span="24">
  976. <el-form-item label="检修人员" prop="selectedMembers">
  977. <el-checkbox-group v-model="finalizeForm.selectedMembers" style="width: 100%" @change="() => handleMembersChange('finalizeForm')">
  978. <el-row :gutter="10">
  979. <el-col :span="6" v-for="user in userList" :key="user.userId">
  980. <el-checkbox :label="user.userId">{{ user.nickName }}</el-checkbox>
  981. </el-col>
  982. </el-row>
  983. </el-checkbox-group>
  984. </el-form-item>
  985. </el-col>-->
  986. <el-col :span="12">
  987. <el-form-item label="检修人员" prop="workGroupMemberName">
  988. <el-input
  989. v-model="finalizeForm.workGroupMemberName"
  990. placeholder="请输入检修人员"
  991. maxlength="200"
  992. show-word-limit
  993. :disabled="getMisDataConfig === '1'"
  994. readonly
  995. />
  996. </el-form-item>
  997. </el-col>
  998. <!-- <el-col :span="24">-->
  999. <!-- <el-form-item label="维修总结" prop="content">-->
  1000. <!-- <el-input-->
  1001. <!-- v-model="finalizeForm.content"-->
  1002. <!-- type="textarea"-->
  1003. <!-- placeholder="请输入维修总结"-->
  1004. <!-- maxlength="200"-->
  1005. <!-- show-word-limit-->
  1006. <!-- :rows="4"-->
  1007. <!-- />-->
  1008. <!-- </el-form-item>-->
  1009. <!-- </el-col>-->
  1010. <el-col :span="24">
  1011. <el-form-item label="附件(可选)">
  1012. <preview :limit="8" v-model="finalizeForm.attachmentUrls" :filesize="5"></preview>
  1013. </el-form-item>
  1014. </el-col>
  1015. </el-row>
  1016. </el-form>
  1017. <template #footer>
  1018. <div class="dialog-footer">
  1019. <el-button @click="closeFinalizeDialog">取 消</el-button>
  1020. <el-button type="primary" @click="submitFinalize">确认结单</el-button>
  1021. </div>
  1022. </template>
  1023. </el-dialog>
  1024. <!-- 结束工单对话框 -->
  1025. <el-dialog title="结束工单" v-model="completeDialogVisible" width="600px" append-to-body @close="closeCompleteDialog">
  1026. <el-form ref="completeFormRef" :model="completeForm" :rules="completeRules" label-width="120px" label-position="top">
  1027. <el-form-item label="处理结果描述" prop="completeDescription">
  1028. <el-input
  1029. v-model="completeForm.completeDescription"
  1030. type="textarea"
  1031. placeholder="请输入处理结果描述"
  1032. maxlength="200"
  1033. show-word-limit
  1034. :rows="4"
  1035. />
  1036. </el-form-item>
  1037. </el-form>
  1038. <template #footer>
  1039. <div class="dialog-footer">
  1040. <el-button @click="closeCompleteDialog">取 消</el-button>
  1041. <el-button type="primary" @click="submitComplete">确认结束</el-button>
  1042. </div>
  1043. </template>
  1044. </el-dialog>
  1045. <!-- 评分对话框 -->
  1046. <el-dialog title="工单评分" v-model="ratingDialogVisible" width="800px" append-to-body @close="closeRatingDialog">
  1047. <el-form ref="ratingFormRef" :model="ratingForm" :rules="ratingRules" label-width="120px" label-position="top">
  1048. <el-row>
  1049. <el-col :span="12">
  1050. <el-form-item label="工单编码"><el-input v-model="ratingForm.workOrderProjectNo" disabled /> </el-form-item>
  1051. </el-col>
  1052. <el-col :span="12">
  1053. <el-form-item label="风机编号"><el-input v-model="ratingForm.pcsDeviceName" disabled /> </el-form-item>
  1054. </el-col>
  1055. <el-col :span="12">
  1056. <el-form-item label="工单状态">
  1057. <el-select v-model="ratingForm.workOrderStatus" style="width: 100%" disabled>
  1058. <el-option
  1059. v-for="dict in gxt_work_order_status"
  1060. :key="dict.value"
  1061. :label="dict.label"
  1062. :value="dict.value"
  1063. />
  1064. </el-select>
  1065. </el-form-item>
  1066. </el-col>
  1067. <el-col :span="12">
  1068. <el-form-item label="维保中心"><el-input v-model="ratingForm.gxtCenter" disabled /> </el-form-item>
  1069. </el-col>
  1070. <el-col :span="12">
  1071. <el-form-item label="场站"><el-input v-model="ratingForm.pcsStationName" disabled /> </el-form-item>
  1072. </el-col>
  1073. <el-col :span="12">
  1074. <el-form-item label="品牌"><el-input v-model="ratingForm.brand" disabled /> </el-form-item>
  1075. </el-col>
  1076. <el-col :span="12">
  1077. <el-form-item label="故障代码"><el-input v-model="ratingForm.faultCode" disabled /> </el-form-item>
  1078. </el-col>
  1079. <el-col :span="24">
  1080. <el-form-item label="故障信息">
  1081. <el-input
  1082. v-model="ratingForm.faultBarcode"
  1083. type="textarea"
  1084. placeholder="请输入故障信息"
  1085. maxlength="100"
  1086. show-word-limit
  1087. :rows="3"
  1088. disabled
  1089. />
  1090. </el-form-item>
  1091. </el-col>
  1092. <el-col :span="12">
  1093. <el-form-item label="MIS工单编码">
  1094. <el-input v-model="ratingForm.misOrderNo" disabled />
  1095. </el-form-item>
  1096. </el-col>
  1097. <el-col :span="12">
  1098. <el-form-item label="下发人"><el-input v-model="ratingForm.assignUserName" disabled /> </el-form-item>
  1099. </el-col>
  1100. <el-col :span="12">
  1101. <el-form-item label="下发时间"><el-input v-model="ratingForm.assignTime" disabled /> </el-form-item>
  1102. </el-col>
  1103. <el-col :span="12">
  1104. <el-form-item label="接单人"><el-input v-model="ratingForm.acceptUserName" disabled /> </el-form-item>
  1105. </el-col>
  1106. <el-col :span="12">
  1107. <el-form-item label="接单时间"><el-input v-model="ratingForm.acceptTime" disabled /> </el-form-item>
  1108. </el-col>
  1109. <el-col :span="12">
  1110. <el-form-item label="工作负责人"><el-input v-model="ratingForm.teamLeaderName" disabled /> </el-form-item>
  1111. </el-col>
  1112. <el-col :span="12">
  1113. <el-form-item label="开始时间"><el-input v-model="ratingForm.realStartTime" disabled /> </el-form-item>
  1114. </el-col>
  1115. <el-col :span="12">
  1116. <el-form-item label="结束时间"><el-input v-model="ratingForm.realEndTime" disabled /> </el-form-item>
  1117. </el-col>
  1118. <!-- <el-col :span="12">
  1119. <el-form-item label="故障描述">{{ ratingForm.faultDesc || '无' }}</el-form-item>
  1120. </el-col>-->
  1121. <!-- <el-col :span="24">-->
  1122. <!-- <el-form-item label="维修总结">-->
  1123. <!-- <el-input-->
  1124. <!-- v-model="ratingForm.content"-->
  1125. <!-- type="textarea"-->
  1126. <!-- :rows="3"-->
  1127. <!-- disabled-->
  1128. <!-- />-->
  1129. <!-- </el-form-item>-->
  1130. <!-- </el-col>-->
  1131. <!-- <el-col :span="12">-->
  1132. <!-- <el-form-item label="检修类型">-->
  1133. <!-- <el-select v-model="ratingForm.maintenanceType" style="width: 100%" disabled>-->
  1134. <!-- <el-option-->
  1135. <!-- v-for="dict in gxt_maintenance_type"-->
  1136. <!-- :key="dict.value"-->
  1137. <!-- :label="dict.label"-->
  1138. <!-- :value="dict.value"-->
  1139. <!-- />-->
  1140. <!-- </el-select>-->
  1141. <!-- </el-form-item>-->
  1142. <!-- </el-col>-->
  1143. <el-col :span="12">
  1144. <el-form-item label="检修人员"><el-input v-model="ratingForm.workGroupMemberName" disabled /></el-form-item>
  1145. </el-col>
  1146. <el-col :span="24">
  1147. <el-form-item label="附件">
  1148. <preview :limit="8" v-model="ratingForm.attachmentUrls" :filesize="5" disabled></preview>
  1149. </el-form-item>
  1150. </el-col>
  1151. <el-col :span="12">
  1152. <el-form-item label="评分" prop="score">
  1153. <el-input-number
  1154. v-model="ratingForm.score"
  1155. :min="1"
  1156. :max="10"
  1157. controls-position="right"
  1158. style="width: 100%"
  1159. />
  1160. </el-form-item>
  1161. </el-col>
  1162. <el-col :span="24">
  1163. <el-form-item label="点评">
  1164. <el-input
  1165. v-model="ratingForm.reviewContent"
  1166. type="textarea"
  1167. placeholder="请输入点评"
  1168. maxlength="200"
  1169. show-word-limit
  1170. :rows="3"
  1171. />
  1172. </el-form-item>
  1173. </el-col>
  1174. </el-row>
  1175. </el-form>
  1176. <template #footer>
  1177. <div class="dialog-footer">
  1178. <el-button @click="closeRatingDialog">取 消</el-button>
  1179. <el-button type="primary" @click="submitRating">提交评分</el-button>
  1180. </div>
  1181. </template>
  1182. </el-dialog>
  1183. <!-- 开始处理对话框 -->
  1184. <el-dialog title="开始工单" v-model="startDialogVisible" width="500px" append-to-body @close="closeStartDialog">
  1185. <el-form label-width="120px" label-position="top">
  1186. <el-row>
  1187. <el-col :span="12">
  1188. <el-form-item label="工单编码">
  1189. {{ startForm.workOrderProjectNo }}
  1190. </el-form-item>
  1191. </el-col>
  1192. <el-col :span="12">
  1193. <el-form-item label="风机编号">
  1194. {{ startForm.pcsDeviceName }}
  1195. </el-form-item>
  1196. </el-col>
  1197. </el-row>
  1198. </el-form>
  1199. <template #footer>
  1200. <div class="dialog-footer">
  1201. <el-button @click="closeStartDialog">取 消</el-button>
  1202. <el-button type="primary" @click="submitStart">确认开始</el-button>
  1203. </div>
  1204. </template>
  1205. </el-dialog>
  1206. <!-- 复运对话框 -->
  1207. <el-dialog title="复运" v-model="restartDialogVisible" width="800px" append-to-body @close="closeRestartDialog">
  1208. <el-alert type="info" :closable="false" style="border-color: #0ea5e9; background-color: #ecf7ff; color: #0369a1; height: 35px;">
  1209. <template #default>
  1210. <i class="fa fa-refresh mr-2" style="color: #0369a1;"> 请填写复运相关信息,完成工单复运。</i>
  1211. </template>
  1212. </el-alert>
  1213. <h4 class="text-sm font-medium text-gray-800 mb-3"></h4>
  1214. <el-form ref="restartFormRef" :model="restartForm" :rules="restartRules" label-width="120px" label-position="top">
  1215. <el-row>
  1216. <el-col :span="12">
  1217. <el-form-item label="工单编码"><el-input v-model="restartForm.workOrderProjectNo" disabled /> </el-form-item>
  1218. </el-col>
  1219. <el-col :span="12">
  1220. <el-form-item label="风机编号"><el-input v-model="restartForm.pcsDeviceName" disabled /> </el-form-item>
  1221. </el-col>
  1222. <el-col :span="12">
  1223. <el-form-item label="维保中心"><el-input v-model="restartForm.gxtCenter" disabled /> </el-form-item>
  1224. </el-col>
  1225. <el-col :span="12">
  1226. <el-form-item label="场站"><el-input v-model="restartForm.pcsStationName" disabled /> </el-form-item>
  1227. </el-col>
  1228. <el-col :span="12">
  1229. <el-form-item label="品牌"><el-input v-model="restartForm.brand" disabled /> </el-form-item>
  1230. </el-col>
  1231. <el-col :span="12">
  1232. <el-form-item label="发生时间"><el-input v-model="restartForm.occurTime" disabled /> </el-form-item>
  1233. </el-col>
  1234. <el-col :span="12">
  1235. <el-form-item label="MIS工单编码"><el-input v-model="restartForm.misOrderNo" disabled /> </el-form-item>
  1236. </el-col>
  1237. <!-- <el-col :span="12">-->
  1238. <!-- <el-form-item label="检修类型">-->
  1239. <!-- <el-select v-model="restartForm.maintenanceType" style="width: 100%" disabled>-->
  1240. <!-- <el-option-->
  1241. <!-- v-for="dict in gxt_maintenance_type"-->
  1242. <!-- :key="dict.value"-->
  1243. <!-- :label="dict.label"-->
  1244. <!-- :value="dict.value"-->
  1245. <!-- />-->
  1246. <!-- </el-select>-->
  1247. <!-- </el-form-item>-->
  1248. <!-- </el-col>-->
  1249. <!-- <el-col :span="24">-->
  1250. <!-- <el-form-item label="维修总结">-->
  1251. <!-- <el-input-->
  1252. <!-- v-model="restartForm.content"-->
  1253. <!-- type="textarea"-->
  1254. <!-- :rows="3"-->
  1255. <!-- disabled-->
  1256. <!-- />-->
  1257. <!-- </el-form-item>-->
  1258. <!-- </el-col>-->
  1259. <!-- <el-col :span="24">-->
  1260. <!-- <el-form-item label="附件">-->
  1261. <!-- <preview :limit="8" v-model="restartForm.attachmentUrls" :filesize="5" disabled></preview>-->
  1262. <!-- </el-form-item>-->
  1263. <!-- </el-col>-->
  1264. <el-col :span="12">
  1265. <el-form-item label="恢复运行时间" prop="restartTime">
  1266. <el-date-picker
  1267. v-model="restartForm.restartTime"
  1268. type="datetime"
  1269. format="YYYY-MM-DD HH:mm"
  1270. value-format="YYYY-MM-DD HH:mm"
  1271. placeholder="请选择恢复运行时间"
  1272. style="width: 100%"
  1273. />
  1274. </el-form-item>
  1275. </el-col>
  1276. </el-row>
  1277. </el-form>
  1278. <template #footer>
  1279. <div class="dialog-footer">
  1280. <el-button @click="closeRestartDialog">取 消</el-button>
  1281. <el-button type="primary" @click="submitRestart">确认复运</el-button>
  1282. </div>
  1283. </template>
  1284. </el-dialog>
  1285. <!-- 查看工单详情对话框 -->
  1286. <el-dialog title="查看工单详情" v-model="viewDialogVisible" width="1000px" append-to-body>
  1287. <el-row :gutter="20">
  1288. <!-- 工单信息 -->
  1289. <el-col :span="8">
  1290. <div class="info-section">
  1291. <h3 class="section-title">工单信息</h3>
  1292. <div class="info-content">
  1293. <el-form label-width="100px" label-position="top">
  1294. <el-row :gutter="20">
  1295. <el-col :span="24">
  1296. <el-form-item label="工单编码">{{ viewForm.workOrderProjectNo }}</el-form-item>
  1297. </el-col>
  1298. <el-col :span="24">
  1299. <el-form-item label="工单状态">
  1300. <dict-tag :options="gxt_work_order_status" :value="viewForm.workOrderStatus" />
  1301. </el-form-item>
  1302. </el-col>
  1303. <el-col :span="24">
  1304. <el-form-item label="风机编号">{{ viewForm.pcsDeviceName || '-' }}</el-form-item>
  1305. </el-col>
  1306. <el-col :span="24">
  1307. <el-form-item label="维保中心">{{ viewForm.gxtCenter || '-' }}</el-form-item>
  1308. </el-col>
  1309. <el-col :span="24">
  1310. <el-form-item label="场站">{{ viewForm.pcsStationName || '-' }}</el-form-item>
  1311. </el-col>
  1312. <el-col :span="24">
  1313. <el-form-item label="品牌">{{ viewForm.brand || '-' }}</el-form-item>
  1314. </el-col>
  1315. <el-col :span="24">
  1316. <el-form-item label="机型">{{ viewForm.model || '-' }}</el-form-item>
  1317. </el-col>
  1318. <el-col :span="24">
  1319. <el-form-item label="发生时间">{{ parseTime(viewForm.occurTime, '{y}-{m}-{d} {h}:{i}') || '-' }}</el-form-item>
  1320. </el-col>
  1321. <el-col :span="24">
  1322. <el-form-item label="故障代码">{{ viewForm.faultCode || '-' }}</el-form-item>
  1323. </el-col>
  1324. <!-- <el-col :span="24">
  1325. <el-form-item label="故障描述">{{ viewForm.faultDesc }}</el-form-item>
  1326. </el-col>-->
  1327. </el-row>
  1328. </el-form>
  1329. </div>
  1330. </div>
  1331. </el-col>
  1332. <!-- 处理信息 -->
  1333. <el-col :span="8">
  1334. <div class="info-section">
  1335. <h3 class="section-title">处理信息</h3>
  1336. <div class="info-content">
  1337. <el-form label-width="100px" label-position="top">
  1338. <el-row :gutter="20">
  1339. <el-col :span="24">
  1340. <el-form-item label="下发人">{{ viewForm.assignUserName || '-' }}</el-form-item>
  1341. </el-col>
  1342. <el-col :span="24">
  1343. <el-form-item label="下发时间">{{ parseTime(viewForm.assignTime, '{y}-{m}-{d} {h}:{i}') || '-' }}</el-form-item>
  1344. </el-col>
  1345. <el-col :span="24">
  1346. <el-form-item label="接单人">{{ viewForm.acceptUserName || '-'}}</el-form-item>
  1347. </el-col>
  1348. <el-col :span="24">
  1349. <el-form-item label="接单时间">{{ parseTime(viewForm.acceptTime, '{y}-{m}-{d} {h}:{i}') || '-' }}</el-form-item>
  1350. </el-col>
  1351. <el-col :span="24">
  1352. <el-form-item label="工作负责人">{{ viewForm.teamLeaderName || '-' }}</el-form-item>
  1353. </el-col>
  1354. <el-col :span="24">
  1355. <el-form-item label="检修人员">{{ viewForm.workGroupMemberName || '-' }}</el-form-item>
  1356. </el-col>
  1357. <!-- <el-col :span="24">-->
  1358. <!-- <el-form-item label="检修类型">-->
  1359. <!-- <dict-tag :options="gxt_maintenance_type" :value="viewForm.maintenanceType" />-->
  1360. <!-- </el-form-item>-->
  1361. <!-- </el-col>-->
  1362. <!-- <el-col :span="24">-->
  1363. <!-- <el-form-item label="维修总结">{{ viewForm.content }}</el-form-item>-->
  1364. <!-- </el-col>-->
  1365. <el-col :span="24">
  1366. <el-form-item label="MIS工单编码">{{ viewForm.misOrderNo || '-' }}</el-form-item>
  1367. </el-col>
  1368. <el-col :span="24">
  1369. <el-form-item label="开始时间">{{ parseTime(viewForm.realStartTime, '{y}-{m}-{d} {h}:{i}') || '-' }}</el-form-item>
  1370. </el-col>
  1371. <el-col :span="24">
  1372. <el-form-item label="结束时间">{{ parseTime(viewForm.realEndTime, '{y}-{m}-{d} {h}:{i}') || '-' }}</el-form-item>
  1373. </el-col>
  1374. <el-col :span="24">
  1375. <el-form-item label="恢复运行时间">{{ parseTime(viewForm.restartTime, '{y}-{m}-{d} {h}:{i}') || '-' }}</el-form-item>
  1376. </el-col>
  1377. </el-row>
  1378. </el-form>
  1379. </div>
  1380. </div>
  1381. </el-col>
  1382. <!-- 工单流转记录 -->
  1383. <el-col :span="8">
  1384. <div class="info-section">
  1385. <h3 class="section-title">工单流转</h3>
  1386. <div class="flow-history">
  1387. <el-timeline>
  1388. <el-timeline-item type="primary"
  1389. v-for="(flow, index) in flowList"
  1390. :key="index"
  1391. :timestamp="parseTime(flow.actionTime, '{y}-{m}-{d} {h}:{i}')"
  1392. >
  1393. <div class="flow-item">
  1394. <h4><dict-tag :options="gxt_repair_order_flow_action_type" :value="flow.actionType" /></h4>
  1395. <p>
  1396. <!-- {{ flow.actionRemark }}<br>-->
  1397. {{ flow.operatorName }}
  1398. </p>
  1399. </div>
  1400. </el-timeline-item>
  1401. </el-timeline>
  1402. </div>
  1403. </div>
  1404. </el-col>
  1405. </el-row>
  1406. <el-form label-position="top">
  1407. <el-row>
  1408. <el-col :span="24">
  1409. <el-form-item label="故障信息">
  1410. <div class="content-text">{{ viewForm.faultBarcode || '-' }}</div>
  1411. </el-form-item>
  1412. </el-col>
  1413. </el-row>
  1414. </el-form>
  1415. <!-- 附件信息 -->
  1416. <div class="info-section" v-if="viewForm.attachmentUrls">
  1417. <h3 class="section-title">结单附件</h3>
  1418. <el-row>
  1419. <el-col :span="24">
  1420. <el-form-item label="附件">
  1421. <preview :limit="8" v-model="viewForm.attachmentUrls" :filesize="5" disabled></preview>
  1422. </el-form-item>
  1423. </el-col>
  1424. </el-row>
  1425. </div>
  1426. <template #footer>
  1427. <div class="dialog-footer">
  1428. <el-button @click="closeViewDialog">关 闭</el-button>
  1429. </div>
  1430. </template>
  1431. </el-dialog>
  1432. <!-- MIS工单导入对话框 -->
  1433. <el-dialog :title="uploadMis.title" v-model="uploadMis.open" width="400px" append-to-body>
  1434. <el-upload ref="uploadMisRef" :limit="1" accept=".xlsx, .xls" :headers="uploadMis.headers" :action="uploadMis.url + '?updateSupport=' + uploadMis.updateSupport" :disabled="uploadMis.isUploading" :on-progress="handleFileUploadProgressMis" :on-success="handleFileSuccessMis" :on-change="handleFileChangeMis" :on-remove="handleFileRemoveMis" :auto-upload="false" drag>
  1435. <el-icon class="el-icon--upload"><upload-filled /></el-icon>
  1436. <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
  1437. <template #tip>
  1438. <div class="el-upload__tip text-center">
  1439. <!-- <div class="el-upload__tip">
  1440. <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的工单数据
  1441. </div>-->
  1442. <span>仅允许导入xls、xlsx格式文件。</span>
  1443. <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="importTemplateMis">下载模板</el-link>
  1444. </div>
  1445. </template>
  1446. </el-upload>
  1447. <template #footer>
  1448. <div class="dialog-footer">
  1449. <el-button type="primary" @click="submitFileFormMis">确 定</el-button>
  1450. <el-button @click="uploadMis.open = false">取 消</el-button>
  1451. </div>
  1452. </template>
  1453. </el-dialog>
  1454. <!-- 维修工单导入对话框 -->
  1455. <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
  1456. <el-upload ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :on-change="handleFileChange" :on-remove="handleFileRemove" :auto-upload="false" drag>
  1457. <el-icon class="el-icon--upload"><upload-filled /></el-icon>
  1458. <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
  1459. <template #tip>
  1460. <div class="el-upload__tip text-center">
  1461. <div class="el-upload__tip">
  1462. <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的工单数据
  1463. </div>
  1464. <span>仅允许导入xls、xlsx格式文件。</span>
  1465. <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="importTemplate">下载模板</el-link>
  1466. </div>
  1467. </template>
  1468. </el-upload>
  1469. <template #footer>
  1470. <div class="dialog-footer">
  1471. <el-button type="primary" @click="submitFileForm">确 定</el-button>
  1472. <el-button @click="upload.open = false">取 消</el-button>
  1473. </div>
  1474. </template>
  1475. </el-dialog>
  1476. <!-- 设备选择组件 -->
  1477. <equipment-select-single v-model="equipmentSelectVisible" @onSelected="onEquipmentSelected"></equipment-select-single>
  1478. </div>
  1479. </template>
  1480. <script setup name="RepairOrder">
  1481. import { getToken } from "@/utils/auth"
  1482. import {
  1483. listRepairOrder,
  1484. getRepairOrder,
  1485. delRepairOrder,
  1486. addRepairOrder,
  1487. updateRepairOrder,
  1488. assignRepairOrder,
  1489. acceptRepairOrder,
  1490. startRepairOrder,
  1491. pauseRepairOrder,
  1492. processDoneRepairOrder,
  1493. ratingRepairOrder,
  1494. suspendRepairOrder,
  1495. resumeRepairOrder,
  1496. approveSuspendRepairOrder,
  1497. finalizeRepairOrder,
  1498. restartRepairOrder,
  1499. getRepairOrderByMisOrderNo
  1500. } from "@/api/gxt/repairOrder";
  1501. import { listDept,getDept } from "@/api/system/dept";
  1502. import { listFaultCodes } from "@/api/gxt/faultCodes"
  1503. /*import { listGxtOrder } from "@/api/gxt/gxtOrder";*/
  1504. import { listUser,listUserNoPermi } from "@/api/system/user";
  1505. import EquipmentSelectSingle from "@/components/equipmentSelect/single.vue"
  1506. import { ElMessage, ElMessageBox, ElNotification, ElLoading } from 'element-plus'
  1507. import { listMaintenanceCenters, listStationsByMaintenanceCenter } from "@/api/gxt/equipment"
  1508. import ImageUpload from "@/components/ImageUpload/index.vue"
  1509. import preview from '@/components/FileUpload/preview.vue'
  1510. import { getConfigKey } from "@/api/system/config"
  1511. import {genCode} from "@/api/system/autocode/rule.js";
  1512. import MisInfoSelectSingle from "@/components/misInfoSelect/single.vue";
  1513. import {listMisInfo, listWorkPerson} from "@/api/gxt/misInfo.js";
  1514. import {listGxtOrder} from "@/api/gxt/gxtOrder.js";
  1515. import useUserStore from '@/store/modules/user'
  1516. const { proxy } = getCurrentInstance()
  1517. const { gxt_maintenance_type, gxt_work_order_status, gxt_order_priority_type,gxt_repair_order_flow_action_type,gxt_order_suspend_reason } = proxy.useDict("gxt_maintenance_type", "gxt_work_order_status", "gxt_order_priority_type","gxt_repair_order_flow_action_type","gxt_order_suspend_reason")
  1518. // 数据列表相关
  1519. const repairOrderList = ref([])
  1520. const openDialog = ref(false)
  1521. const viewDialogVisible = ref(false)
  1522. const loading = ref(true)
  1523. const showSearch = ref(true)
  1524. const ids = ref([])
  1525. const single = ref(true)
  1526. const multiple = ref(true)
  1527. const total = ref(0)
  1528. const dialogTitle = ref("")
  1529. const tableHeight = ref(window.innerHeight - 300)
  1530. const startDialogVisible = ref(false) // 添加开始处理对话框控制变量
  1531. const misInfoSelectVisible = ref(false)
  1532. let commonKey = 0
  1533. const optType = ref("")
  1534. // 表单相关
  1535. const repairOrderRef = ref(null)
  1536. const queryRef = ref(null)
  1537. const assignFormRef = ref(null)
  1538. const acceptFormRef = ref(null)
  1539. const suspendFormRef = ref(null)
  1540. const completeFormRef = ref(null)
  1541. const ratingFormRef = ref(null)
  1542. const startFormRef = ref(null) // 添加开始处理表单引用
  1543. const restartFormRef = ref(null) // 添加复运表单引用
  1544. // 各种表单数据
  1545. const form = ref({})
  1546. const viewForm = ref({})
  1547. const assignForm = ref({})
  1548. const acceptForm = ref({
  1549. id: null,
  1550. workOrderProjectNo: null,
  1551. pcsDeviceName: null,
  1552. maintenanceType: null,
  1553. workOrderStatus: null,
  1554. gxtCenter: null,
  1555. pcsStationName: null,
  1556. brand: null,
  1557. faultCode: null,
  1558. faultDesc: null,
  1559. relatedOrderCode: null,
  1560. relatedOrderContent: null,
  1561. teamLeaderName: null,
  1562. selectedMembers: [],
  1563. repairOrderPersonList: [],
  1564. pcsStationId: null // 添加场站ID用于查询用户
  1565. })
  1566. const suspendForm = ref({})
  1567. const approveForm = ref({})
  1568. const completeForm = ref({})
  1569. const finalizeForm = ref({
  1570. repairOrderPersonList: []
  1571. })
  1572. const ratingForm = ref({
  1573. score: null
  1574. })
  1575. const startForm = ref({}) // 添加开始处理表单数据
  1576. const restartForm = ref({}) // 添加复运表单数据
  1577. // 控制结单表单中字段是否可编辑
  1578. const getMisDataConfig = ref("0") // 默认值为"0",表示可以手动输入
  1579. // 下发对话框中的维保工单搜索相关
  1580. const workOrderSearchLoading = ref(false)
  1581. const workOrderOptions = ref([])
  1582. // 文件列表
  1583. const fileList = ref([])
  1584. // 对话框显示控制
  1585. const assignDialogVisible = ref(false);
  1586. const acceptDialogVisible = ref(false);
  1587. const userList = ref([]); // 添加用户列表
  1588. const suspendDialogVisible = ref(false)
  1589. const approveDialogVisible = ref(false)
  1590. const completeDialogVisible = ref(false)
  1591. const finalizeDialogVisible = ref(false)
  1592. const ratingDialogVisible = ref(false)
  1593. const equipmentSelectVisible = ref(false)
  1594. const restartDialogVisible = ref(false) // 添加复运对话框显示控制
  1595. // 工单流转记录
  1596. const flowList = ref([])
  1597. // 维保中心和场站选项
  1598. const maintenanceCenterOptions = ref([])
  1599. const stationOptions = ref([])
  1600. // 故障代码选项
  1601. const faultCodeOptions = ref([])
  1602. // 工作负责人快速检索相关响应式数据
  1603. const showTeamLeaderQuickSelect = ref(false)
  1604. const quickTeamLeaderList = ref([])
  1605. const teamLeaderLoading = ref(false)
  1606. const teamLeaderSearchTimer = ref(null)
  1607. const allUserList = ref([]) // 存储所有设备数据用于快速检索
  1608. const lastLoadedCenterId = ref(null) // Track last loaded maintenance center ID
  1609. const userStore = useUserStore();
  1610. /** 过滤快速检索用户列表 */
  1611. const filterQuickUserList = (keyword) => {
  1612. debugger
  1613. if (!allUserList.value.length) {
  1614. loadQuickTeamLeaderList();
  1615. return;
  1616. }
  1617. const lowerKeyword = keyword.toLowerCase();
  1618. quickTeamLeaderList.value = allUserList.value.filter(item =>
  1619. (item.nickName && item.nickName.toLowerCase().includes(lowerKeyword))
  1620. );
  1621. }
  1622. // 工作负责人快速检索方法
  1623. /** 工作负责人输入框获取焦点 */
  1624. const handleTeamLeaderInputFocus = () => {
  1625. showTeamLeaderQuickSelect.value = true
  1626. // 如果已有输入内容,立即搜索
  1627. if (acceptForm.value.teamLeaderName && acceptForm.value.teamLeaderName.trim()) {
  1628. handleTeamLeaderInput(acceptForm.value.teamLeaderName)
  1629. } else {
  1630. // 如果没有输入内容,加载默认列表
  1631. loadQuickTeamLeaderList()
  1632. }
  1633. }
  1634. /** 工作负责人输入框失去焦点 */
  1635. const handleTeamLeaderInputBlur = () => {
  1636. // 延迟隐藏下拉框,确保点击选项能触发
  1637. setTimeout(() => {
  1638. showTeamLeaderQuickSelect.value = false
  1639. }, 200)
  1640. }
  1641. /** 工作负责人输入事件 - 实时搜索 */
  1642. const handleTeamLeaderInput = (value) => {
  1643. const searchText = value.trim()
  1644. if (!searchText) {
  1645. quickTeamLeaderList.value = []
  1646. showTeamLeaderQuickSelect.value = false
  1647. return
  1648. }
  1649. showTeamLeaderQuickSelect.value = true
  1650. // 清除之前的定时器
  1651. if (teamLeaderSearchTimer.value) {
  1652. clearTimeout(teamLeaderSearchTimer.value)
  1653. }
  1654. filterQuickUserList(searchText)
  1655. // 设置新的定时器,防抖处理(300ms)
  1656. // teamLeaderSearchTimer.value = setTimeout(() => {
  1657. // searchTeamLeaderList(searchText)
  1658. // }, 300)
  1659. }
  1660. /** 搜索工作负责人列表 */
  1661. const searchTeamLeaderList = async (keyword) => {
  1662. if (!keyword) {
  1663. quickTeamLeaderList.value = []
  1664. return
  1665. }
  1666. teamLeaderLoading.value = true
  1667. try {
  1668. const response = await listUserNoPermi({
  1669. nickName: keyword,
  1670. // 可以根据需要添加其他搜索条件
  1671. status: '0' // 只搜索启用状态的用户
  1672. })
  1673. quickTeamLeaderList.value = response.data || []
  1674. } catch (error) {
  1675. console.error('搜索工作负责人失败:', error)
  1676. proxy.$modal.msgError('搜索失败,请重试')
  1677. quickTeamLeaderList.value = []
  1678. } finally {
  1679. teamLeaderLoading.value = false
  1680. }
  1681. }
  1682. /** 加载快速检索工作负责人列表 */
  1683. const loadQuickTeamLeaderList = async () => {
  1684. // 如果已有所有用户数据,且是同一个维保中心,直接使用
  1685. if (allUserList.value.length > 0 && lastLoadedCenterId.value === acceptForm.value.gxtCenterId) {
  1686. quickTeamLeaderList.value = allUserList.value;
  1687. return;
  1688. }
  1689. // 记录当前维保中心ID
  1690. lastLoadedCenterId.value = acceptForm.value.gxtCenterId;
  1691. teamLeaderLoading.value = true
  1692. try {
  1693. // 加载当前部门下的用户列表
  1694. const response = await listUserNoPermi({
  1695. deptId: acceptForm.value.gxtCenterId, // 使用维保中心ID
  1696. status: '0'
  1697. })
  1698. allUserList.value = response.data || []
  1699. quickTeamLeaderList.value = allUserList.value;
  1700. } catch (error) {
  1701. console.error('加载工作负责人列表失败:', error)
  1702. allUserList.value = []
  1703. } finally {
  1704. teamLeaderLoading.value = false
  1705. }
  1706. }
  1707. /** 快速选择工作负责人 */
  1708. const handleTeamLeaderQuickSelect = (item) => {
  1709. acceptForm.value.teamLeaderId = item.userId
  1710. acceptForm.value.teamLeaderName = item.nickName
  1711. showTeamLeaderQuickSelect.value = false
  1712. }
  1713. /** 清空工作负责人 */
  1714. const handleTeamLeaderClear = () => {
  1715. acceptForm.value.teamLeaderId = undefined
  1716. acceptForm.value.teamLeaderName = ''
  1717. quickTeamLeaderList.value = []
  1718. showTeamLeaderQuickSelect.value = false
  1719. }
  1720. // MIS工单快速检索相关响应式数据
  1721. const showMisNoQuickSelect = ref(false)
  1722. const quickMisNoList = ref([])
  1723. const misNoLoading = ref(false)
  1724. const misNoSearchTimer = ref(null)
  1725. // 快速检索方法
  1726. /** MIS工单编码输入框获取焦点 */
  1727. const handleMisNoInputFocus = () => {
  1728. showMisNoQuickSelect.value = true
  1729. // 如果已有输入内容,立即搜索
  1730. if (form.misNo && form.misNo.trim()) {
  1731. handleMisNoInput(form.misNo)
  1732. }
  1733. }
  1734. /** MIS工单编码输入框失去焦点 */
  1735. const handleMisNoInputBlur = () => {
  1736. // 延迟隐藏下拉框,确保点击选项能触发
  1737. setTimeout(() => {
  1738. showMisNoQuickSelect.value = false
  1739. }, 200)
  1740. }
  1741. /** MIS工单编码输入事件 - 实时搜索 */
  1742. const handleMisNoInput = (value) => {
  1743. const searchText = value.trim()
  1744. if (!searchText) {
  1745. quickMisNoList.value = []
  1746. showMisNoQuickSelect.value = false
  1747. return
  1748. }
  1749. showMisNoQuickSelect.value = true
  1750. // 清除之前的定时器
  1751. if (misNoSearchTimer.value) {
  1752. clearTimeout(misNoSearchTimer.value)
  1753. }
  1754. // 设置新的定时器,防抖处理(500ms)
  1755. misNoSearchTimer.value = setTimeout(() => {
  1756. searchMisNoList(searchText)
  1757. }, 500)
  1758. }
  1759. /** 搜索MIS工单列表 */
  1760. const searchMisNoList = async (keyword) => {
  1761. if (!keyword) {
  1762. quickMisNoList.value = []
  1763. return
  1764. }
  1765. misNoLoading.value = true
  1766. try {
  1767. const response = await listMisInfo({
  1768. pageNum: 1,
  1769. // pageSize: 10, // 只显示前10条结果
  1770. misNo: keyword,
  1771. pcsDeviceName: keyword,
  1772. pcsStationName: keyword
  1773. // 注意:这里假设后端API支持这些字段的模糊查询
  1774. // 如果后端不支持多字段同时查询,可能需要调整
  1775. })
  1776. quickMisNoList.value = response.rows || []
  1777. // 如果没有找到结果,可以尝试更宽松的搜索
  1778. if (quickMisNoList.value.length === 0 && keyword.length >= 2) {
  1779. // 可以尝试只按MIS工单编码搜索
  1780. const retryResponse = await listMisInfo({
  1781. pageNum: 1,
  1782. // pageSize: 10,
  1783. misNo: keyword
  1784. })
  1785. quickMisNoList.value = retryResponse.rows || []
  1786. }
  1787. } catch (error) {
  1788. console.error('搜索MIS工单失败:', error)
  1789. proxy.$modal.msgError('搜索失败,请重试')
  1790. quickMisNoList.value = []
  1791. } finally {
  1792. misNoLoading.value = false
  1793. }
  1794. }
  1795. /** 快速选择MIS工单 */
  1796. const handleMisNoQuickSelect = (item) => {
  1797. onMisInfoSelected(item)
  1798. showMisNoQuickSelect.value = false
  1799. }
  1800. /** 清空MIS工单编码 */
  1801. const handleMisNoClear = () => {
  1802. // 清空与MIS工单相关的字段
  1803. finalizeForm.value.misOrderNo = null
  1804. finalizeForm.value.realStartTime = null
  1805. finalizeForm.value.realEndTime = null
  1806. finalizeForm.value.repairOrderPersonList = [];
  1807. finalizeForm.value.workGroupMemberName = null
  1808. quickMisNoList.value = []
  1809. showMisNoQuickSelect.value = false
  1810. }
  1811. /** 查询故障代码列表 */
  1812. function getFaultCodeList() {
  1813. listFaultCodes({ isActive: 0 }).then(response => {
  1814. faultCodeOptions.value = response.rows;
  1815. });
  1816. }
  1817. // 查询参数
  1818. const queryParams = ref({
  1819. pageNum: 1,
  1820. pageSize: 10,
  1821. workOrderProjectNo: null,
  1822. workOrderStatus: null,
  1823. gxtCenterId: null,
  1824. gxtCenter: null,
  1825. pcsStationId: null,
  1826. pcsStationName: null,
  1827. pcsDeviceId: null,
  1828. pcsDeviceName: null,
  1829. brand: null,
  1830. model: null,
  1831. faultCode: null,
  1832. faultBarcode: null,
  1833. assignTime: null,
  1834. assignUserId: null,
  1835. assignUserName: null,
  1836. acceptTime: null,
  1837. acceptUserId: null,
  1838. acceptUserName: null,
  1839. realStartTime: null,
  1840. realEndTime: null,
  1841. teamLeaderId: null,
  1842. teamLeaderName: null,
  1843. workGroupMemberId: null,
  1844. workGroupMemberName: null,
  1845. content: null,
  1846. planHour: null,
  1847. priorityType: null,
  1848. score: null,
  1849. reviewContent: null,
  1850. maintenanceType: null
  1851. })
  1852. // 表单验证规则
  1853. const rules = ref({
  1854. workOrderProjectNo: [
  1855. { required: true, message: "工单编码不能为空", trigger: "blur" }
  1856. ],
  1857. pcsDeviceName: [
  1858. { required: true, message: "风机编号不能为空", trigger: "blur" }
  1859. ],
  1860. /*faultCode: [
  1861. { required: true, message: "请选择故障代码", trigger: "change" }
  1862. ],*/
  1863. occurTime: [
  1864. { required: true, message: "请选择发生时间", trigger: "change" }
  1865. ],
  1866. // maintenanceType: [
  1867. // { required: true, message: "请选择检修类型", trigger: "change" }
  1868. // ],
  1869. /* priorityType: [
  1870. { required: true, message: "请选择优先级", trigger: "change" }
  1871. ],*/
  1872. faultBarcode: [
  1873. { required: true, message: "故障信息不能为空", trigger: "blur" }
  1874. ],
  1875. })
  1876. // 接单表单验证规则
  1877. const acceptRules = ref({
  1878. teamLeaderId: [
  1879. { required: true, message: "请选择工作负责人", trigger: "change" }
  1880. ],
  1881. /*selectedMembers: [
  1882. { required: true, message: "请至少选择一名检修人员", trigger: "change" }
  1883. ]*/
  1884. })
  1885. // 挂起表单验证规则
  1886. const suspendRules = ref({
  1887. suspendReason: [
  1888. { required: true, message: "请选择挂起原因", trigger: "change" }
  1889. ],
  1890. /*suspendDescription: [
  1891. { required: true, message: "请输入详细说明", trigger: "blur" }
  1892. ]*/
  1893. })
  1894. // 审批表单验证规则
  1895. const approveRules = ref({
  1896. /*approvalStatus: [
  1897. { required: true, message: "请选择审批决定", trigger: "change" }
  1898. ],
  1899. rejectionReason: [
  1900. { required: true, message: "请输入驳回原因", trigger: "blur" }
  1901. ]*/
  1902. })
  1903. // 结单表单验证规则
  1904. const finalizeRules = ref({
  1905. // maintenanceType: [
  1906. // { required: true, message: "请选择检修类型", trigger: "change" }
  1907. // ],
  1908. /*selectedMembers: [
  1909. { required: true, message: "请至少选择一名检修人员", trigger: "change" }
  1910. ],*/
  1911. // content: [
  1912. // { required: true, message: "请输入维修总结", trigger: "blur" }
  1913. // ],
  1914. misOrderNo: [
  1915. { required: true, message: "MIS工单编码不能为空", trigger: "blur" }
  1916. ],
  1917. })
  1918. // 评分表单验证规则
  1919. const ratingRules = ref({
  1920. score: [
  1921. { required: true, message: "请评分", trigger: "change" },
  1922. { type: "number", min: 1, max: 10, message: "评分必须在1-10之间", trigger: "change" }
  1923. ]
  1924. })
  1925. // 复运表单验证规则
  1926. const restartRules = ref({
  1927. restartTime: [
  1928. { required: true, message: "请选择恢复运行时间", trigger: "change" }
  1929. ]
  1930. })
  1931. // 监听窗口大小变化
  1932. function handleResize() {
  1933. tableHeight.value = window.innerHeight - 300
  1934. }
  1935. // 关闭接单对话框并重置表单
  1936. function closeAcceptDialog() {
  1937. acceptDialogVisible.value = false
  1938. acceptForm.value = {}
  1939. proxy.resetForm("acceptFormRef")
  1940. }
  1941. // 关闭下发表单对话框并重置表单
  1942. function closeAssignDialog() {
  1943. assignDialogVisible.value = false
  1944. assignForm.value = {}
  1945. proxy.resetForm("assignFormRef")
  1946. }
  1947. // 关闭挂起对话框并重置表单
  1948. function closeSuspendDialog() {
  1949. suspendDialogVisible.value = false
  1950. suspendForm.value = {}
  1951. proxy.resetForm("suspendFormRef")
  1952. }
  1953. // 关闭审批对话框并重置表单
  1954. function closeApproveDialog() {
  1955. approveDialogVisible.value = false
  1956. approveForm.value = {}
  1957. proxy.resetForm("approveFormRef")
  1958. }
  1959. // 关闭结单对话框并重置表单
  1960. function closeFinalizeDialog() {
  1961. finalizeDialogVisible.value = false
  1962. finalizeForm.value = {}
  1963. proxy.resetForm("finalizeFormRef")
  1964. }
  1965. // 关闭结束工单对话框并重置表单
  1966. function closeCompleteDialog() {
  1967. completeDialogVisible.value = false
  1968. completeForm.value = {}
  1969. proxy.resetForm("completeFormRef")
  1970. }
  1971. // 关闭评分对话框并重置表单
  1972. function closeRatingDialog() {
  1973. ratingDialogVisible.value = false
  1974. ratingForm.value = {}
  1975. proxy.resetForm("ratingFormRef")
  1976. }
  1977. // 关闭开始处理对话框并重置表单
  1978. function closeStartDialog() {
  1979. startDialogVisible.value = false
  1980. startForm.value = {}
  1981. proxy.resetForm("startFormRef")
  1982. }
  1983. // 关闭复运对话框并重置表单
  1984. function closeRestartDialog() {
  1985. restartDialogVisible.value = false
  1986. restartForm.value = {}
  1987. proxy.resetForm("restartFormRef")
  1988. }
  1989. // 关闭查看详情对话框并重置表单
  1990. function closeViewDialog() {
  1991. viewDialogVisible.value = false
  1992. viewForm.value = {}
  1993. flowList.value = []
  1994. }
  1995. onMounted(() => {
  1996. getList()
  1997. getMaintenanceCenterAndStationList()
  1998. getFaultCodeList()
  1999. getGetMisDataConfig() // 获取配置参数
  2000. window.addEventListener('resize', handleResize)
  2001. })
  2002. onUnmounted(() => {
  2003. window.removeEventListener('resize', handleResize)
  2004. })
  2005. /** 获取配置参数 gxt.repairOder.getMisData */
  2006. function getGetMisDataConfig() {
  2007. getConfigKey("gxt.repairOder.getMisData").then(response => {
  2008. getMisDataConfig.value = response.msg || "0";
  2009. }).catch(error => {
  2010. console.error("获取配置参数失败:", error);
  2011. getMisDataConfig.value = "0"; // 获取失败时默认为可手动输入
  2012. });
  2013. }
  2014. /** 查询维修工单列表 */
  2015. function getList() {
  2016. loading.value = true
  2017. listRepairOrder(queryParams.value).then(response => {
  2018. repairOrderList.value = response.rows
  2019. total.value = response.total
  2020. loading.value = false
  2021. })
  2022. }
  2023. /** 查询维保中心和场站列表 */
  2024. /*function getMaintenanceCenterAndStationList() {
  2025. listDept({}).then(response => {
  2026. const depts = response.data;
  2027. // 筛选出维保中心(level=2)
  2028. maintenanceCenterOptions.value = depts.filter(dept => dept.level === "2");
  2029. // 筛选出场站(level=3)
  2030. const stations = depts.filter(dept => dept.level === "3");
  2031. // 如果已选择维保中心,则筛选出该维保中心下的场站
  2032. if (queryParams.value.gxtCenter) {
  2033. const selectedMaintenanceCenter = maintenanceCenterOptions.value.find(
  2034. center => center.deptName === queryParams.value.gxtCenter
  2035. );
  2036. if (selectedMaintenanceCenter) {
  2037. stationOptions.value = stations.filter(
  2038. station => station.ancestors.includes(selectedMaintenanceCenter.deptId)
  2039. );
  2040. } else {
  2041. stationOptions.value = [];
  2042. }
  2043. } else {
  2044. // 如果未选择维保中心,则清空场站选项
  2045. stationOptions.value = [];
  2046. }
  2047. });
  2048. }*/
  2049. function getMaintenanceCenterAndStationList() {
  2050. listMaintenanceCenters().then(response => {
  2051. maintenanceCenterOptions.value = response.data.map(item => {
  2052. return { deptName: item, deptId: item };
  2053. });
  2054. // 如果已选择维保中心,则筛选出该维保中心下的场站
  2055. if (queryParams.value.maintenanceCenter) {
  2056. listStationsByMaintenanceCenter(queryParams.value.maintenanceCenter).then(res => {
  2057. stationOptions.value = res.data.map(item => {
  2058. return { deptName: item, deptId: item };
  2059. });
  2060. });
  2061. } else {
  2062. // 如果未选择维保中心,则清空场站选项
  2063. stationOptions.value = [];
  2064. }
  2065. });
  2066. }
  2067. /** 维保中心选择变化时 */
  2068. /*function handleMaintenanceCenterChange(selectedCenter) {
  2069. // 清空场站选择
  2070. queryParams.value.pcsStationName = null;
  2071. // 如果选择了维保中心,则加载对应的场站
  2072. if (selectedCenter) {
  2073. listDept({}).then(response => {
  2074. const depts = response.data;
  2075. const stations = depts.filter(dept => dept.level === "3");
  2076. // 找到选中的维保中心
  2077. const selectedMaintenanceCenter = maintenanceCenterOptions.value.find(
  2078. center => center.deptName === selectedCenter
  2079. );
  2080. if (selectedMaintenanceCenter) {
  2081. // 筛选出该维保中心下的场站
  2082. stationOptions.value = stations.filter(
  2083. station => station.ancestors.includes(selectedMaintenanceCenter.deptId)
  2084. );
  2085. }
  2086. });
  2087. } else {
  2088. // 如果未选择维保中心,则清空场站选项
  2089. stationOptions.value = [];
  2090. }
  2091. }*/
  2092. function handleMaintenanceCenterChange(selectedCenter) {
  2093. // 清空场站选择
  2094. queryParams.value.station = null;
  2095. // 如果选择了维保中心,则加载对应的场站
  2096. if (selectedCenter) {
  2097. listStationsByMaintenanceCenter(selectedCenter).then(response => {
  2098. stationOptions.value = response.data.map(item => {
  2099. return { deptName: item, deptId: item };
  2100. });
  2101. });
  2102. } else {
  2103. // 如果未选择维保中心,则清空场站选项
  2104. stationOptions.value = [];
  2105. }
  2106. }
  2107. /**
  2108. * 根据部门ID获取部门信息,并根据level判断是否需要查找父部门
  2109. * @param {Number} deptId 部门ID
  2110. * @returns {Promise<Number>} 返回level为3的部门ID
  2111. */
  2112. function getDeptAndUserByLevel(deptId) {
  2113. return new Promise((resolve) => {
  2114. // 获取部门信息
  2115. getDeptInfoAndParent(deptId).then(dept => {
  2116. resolve(dept.deptId);
  2117. });
  2118. });
  2119. }
  2120. /**
  2121. * 递归获取部门信息,查找父部门直到level为3
  2122. * @param {Number} deptId 部门ID
  2123. * @returns {Promise<Object>} 返回level为3的部门对象
  2124. */
  2125. function getDeptInfoAndParent(deptId) {
  2126. return new Promise((resolve) => {
  2127. getDept(deptId).then(response => {
  2128. const dept = response.data;
  2129. // 如果部门level为3,直接返回
  2130. if (dept.level === "3") {
  2131. resolve(dept);
  2132. }
  2133. // 如果有祖先部门,则继续向上查找
  2134. else if (dept.ancestors) {
  2135. // 从ancestors中提取父部门ID
  2136. // ancestors格式类似 "0,100,101,102"
  2137. const ancestorIds = dept.ancestors.split(',');
  2138. if (ancestorIds.length <= 1){
  2139. resolve(dept);
  2140. }else {
  2141. const parentDeptId = ancestorIds[ancestorIds.length - 1];
  2142. // 递归获取父部门信息
  2143. getDeptInfoAndParent(parentDeptId).then(parentDept => {
  2144. resolve(parentDept);
  2145. });
  2146. }
  2147. }
  2148. // 其他情况也直接返回
  2149. else {
  2150. resolve(dept);
  2151. }
  2152. }).catch(error => {
  2153. // 如果获取部门信息失败,返回null
  2154. console.error("获取部门信息失败:", error);
  2155. resolve(null);
  2156. });
  2157. });
  2158. }
  2159. // 取消按钮
  2160. function cancel() {
  2161. openDialog.value = false
  2162. reset()
  2163. }
  2164. // 表单重置
  2165. function reset() {
  2166. form.value = {}
  2167. proxy.resetForm("repairOrderRef")
  2168. }
  2169. /** 搜索按钮操作 */
  2170. function handleQuery() {
  2171. queryParams.value.pageNum = 1
  2172. getList()
  2173. }
  2174. /** 打开设备选择对话框 */
  2175. function handleSelectEquipment() {
  2176. equipmentSelectVisible.value = true
  2177. }
  2178. /** 设备选择回调 */
  2179. function onEquipmentSelected(row) {
  2180. if (row) {
  2181. // 检查维保中心ID和场站ID是否存在
  2182. if (!row.maintenanceCenterId) {
  2183. proxy.$modal.msgError("该设备的维保中心没有对应的部门,请完善部门信息后再更新设备数据!");
  2184. return;
  2185. }
  2186. if (!row.stationId) {
  2187. proxy.$modal.msgError("该设备的场站没有对应的部门,请完善部门信息后再更新设备数据!");
  2188. return;
  2189. }
  2190. form.value.pcsDeviceId = row.equipmentId
  2191. form.value.pcsDeviceName = row.equipmentCode
  2192. form.value.gxtCenterId = row.maintenanceCenterId
  2193. form.value.gxtCenter = row.maintenanceCenter
  2194. form.value.pcsStationId = row.stationId
  2195. form.value.pcsStationName = row.station
  2196. form.value.brand = row.brand
  2197. form.value.model = row.model
  2198. }
  2199. equipmentSelectVisible.value = false
  2200. }
  2201. /** 重置按钮操作 */
  2202. function resetQuery() {
  2203. proxy.resetForm("queryRef")
  2204. handleQuery()
  2205. }
  2206. // 多选框选中数据
  2207. function handleSelectionChange(selection) {
  2208. ids.value = selection.map(item => item.id)
  2209. single.value = selection.length != 1
  2210. multiple.value = !selection.length
  2211. }
  2212. /** 新增按钮操作 */
  2213. function handleAdd() {
  2214. reset()
  2215. //生成工单编码
  2216. genCode('REPAIR_ORDER_CODE').then(response =>{
  2217. form.value.workOrderProjectNo = response;
  2218. });
  2219. openDialog.value = true
  2220. dialogTitle.value = "新建维修工单"
  2221. optType.value = "add"
  2222. // 设置默认发生时间
  2223. form.value.occurTime = now
  2224. }
  2225. /** 修改按钮操作 */
  2226. function handleEdit(row) {
  2227. reset()
  2228. const id = row.id || ids.value
  2229. getRepairOrder(id).then(response => {
  2230. form.value = response.data
  2231. openDialog.value = true
  2232. dialogTitle.value = "下发"
  2233. optType.value = "edit"
  2234. })
  2235. }
  2236. /** 提交按钮 */
  2237. function submitForm() {
  2238. proxy.$refs["repairOrderRef"].validate(valid => {
  2239. if (valid) {
  2240. form.value.workOrderStatus = "to_issue"
  2241. if (form.value.id != null) {
  2242. updateRepairOrder(form.value).then(response => {
  2243. proxy.$modal.msgSuccess("修改成功")
  2244. openDialog.value = false
  2245. getList()
  2246. })
  2247. } else {
  2248. addRepairOrder(form.value).then(response => {
  2249. proxy.$modal.msgSuccess("新增成功")
  2250. openDialog.value = false
  2251. getList()
  2252. })
  2253. }
  2254. }
  2255. })
  2256. }
  2257. /** 保存并下发 */
  2258. function submitFormAndIssue() {
  2259. proxy.$refs["repairOrderRef"].validate(valid => {
  2260. if (valid) {
  2261. // 设置状态为待接单
  2262. form.value.workOrderStatus = "assigned"
  2263. if (form.value.id != null) {
  2264. updateRepairOrder(form.value).then(response => {
  2265. proxy.$modal.msgSuccess("修改成功")
  2266. openDialog.value = false
  2267. getList()
  2268. })
  2269. } else {
  2270. addRepairOrder(form.value).then(response => {
  2271. proxy.$modal.msgSuccess("新增成功")
  2272. openDialog.value = false
  2273. getList()
  2274. })
  2275. }
  2276. }
  2277. })
  2278. }
  2279. /** 删除按钮操作 */
  2280. function handleDelete(row) {
  2281. const ids = row.id || ids.value
  2282. const workOrderProjectNo = row.workOrderProjectNo || (repairOrderList.value.find(item => item.id === ids)?.workOrderProjectNo)
  2283. proxy.$modal.confirm('是否确认删除维修工单编码为"' + workOrderProjectNo + '"的数据项?').then(function() {
  2284. return delRepairOrder(ids)
  2285. }).then(() => {
  2286. getList()
  2287. proxy.$modal.msgSuccess("删除成功")
  2288. }).catch(() => {})
  2289. }
  2290. /** 导出按钮操作 */
  2291. function handleExport() {
  2292. proxy.download('gxt/repairOrder/export', {
  2293. ...queryParams.value
  2294. }, `repairOrder_${new Date().getTime()}.xlsx`)
  2295. }
  2296. /** 故障代码变化处理 */
  2297. function handleFaultCodeChange(value) {
  2298. if (value === '无') {
  2299. // 当选择"无"时,故障信息设置为"-"并允许手动输入
  2300. form.value.faultBarcode = "-";
  2301. } else {
  2302. // 当选择具体的故障代码时,自动填充故障信息并设为只读
  2303. const selectedFaultCode = faultCodeOptions.value.find(item => item.faultCode === value);
  2304. if (selectedFaultCode) {
  2305. form.value.faultBarcode = selectedFaultCode.faultBarcode || "";
  2306. } else {
  2307. form.value.faultBarcode = "";
  2308. }
  2309. }
  2310. }
  2311. /** 获取字典标签文本 */
  2312. function getDictLabel(dictOptions, value) {
  2313. const dict = dictOptions.find(item => item.value === value);
  2314. return dict ? dict.label : value;
  2315. }
  2316. /** 下发操作 */
  2317. function handleAssign(row) {
  2318. getRepairOrder(row.id).then(response => {
  2319. assignForm.value = response.data
  2320. // 初始化维保工单选项为空
  2321. workOrderOptions.value = []
  2322. assignDialogVisible.value = true
  2323. })
  2324. }
  2325. /** 关联维保工单变化处理 */
  2326. function handleRelatedOrderChange() {
  2327. // 当关联维保工单编码输入时,如果清空了内容,则清空维保内容
  2328. if (!assignForm.value.relatedOrderCode) {
  2329. assignForm.value.relatedOrderContent = ""
  2330. }
  2331. }
  2332. /** 搜索维保工单 */
  2333. /*function searchWorkOrders(query) {
  2334. if (!query) {
  2335. workOrderOptions.value = []
  2336. return
  2337. }
  2338. workOrderSearchLoading.value = true
  2339. listGxtOrder({ workOrderProjectNo: query }).then(response => {
  2340. workOrderOptions.value = response.rows
  2341. workOrderSearchLoading.value = false
  2342. }).catch(() => {
  2343. workOrderSearchLoading.value = false
  2344. workOrderOptions.value = []
  2345. })
  2346. }*/
  2347. /** 选择维保工单 */
  2348. function handleWorkOrderChange(val) {
  2349. if (!val) {
  2350. assignForm.value.relatedOrderContent = ""
  2351. return
  2352. }
  2353. // 查找选中的维保工单
  2354. const selectedWorkOrder = workOrderOptions.value.find(item => item.workOrderProjectNo === val)
  2355. if (selectedWorkOrder) {
  2356. // 自动填充维保内容
  2357. assignForm.value.relatedOrderContent = selectedWorkOrder.content || ""
  2358. } else {
  2359. assignForm.value.relatedOrderContent = ""
  2360. }
  2361. }
  2362. /** 提交下发 */
  2363. async function submitAssign() {
  2364. proxy.$refs["assignFormRef"].validate(async valid => {
  2365. if (valid) {
  2366. try {
  2367. await assignRepairOrder(assignForm.value)
  2368. proxy.$modal.msgSuccess("下发成功")
  2369. assignDialogVisible.value = false
  2370. getList()
  2371. } catch (error) {
  2372. proxy.$modal.msgError("下发失败: " + error.message)
  2373. }
  2374. }
  2375. })
  2376. }
  2377. /** 接单操作 */
  2378. function handleAccept(row) {
  2379. getRepairOrder(row.id).then(response => {
  2380. acceptForm.value = { ...response.data, selectedMembers: [] }
  2381. // 获取场站ID用于查询用户
  2382. acceptForm.value.pcsStationId = response.data.pcsStationId
  2383. acceptForm.value.pcsStationPid = response.data.pcsStationPid
  2384. if (lastLoadedCenterId.value !== acceptForm.value.gxtCenterId) {
  2385. allUserList.value = [];
  2386. }
  2387. // 预加载工作负责人列表
  2388. loadQuickTeamLeaderList()
  2389. acceptDialogVisible.value = true
  2390. })
  2391. }
  2392. /** 提交接单 */
  2393. async function submitAccept() {
  2394. proxy.$refs["acceptFormRef"].validate(async valid => {
  2395. if (valid) {
  2396. try {
  2397. // 更新检修人员列表
  2398. //handleMembersChange('acceptForm');
  2399. await acceptRepairOrder(acceptForm.value)
  2400. proxy.$modal.msgSuccess("接单成功")
  2401. acceptDialogVisible.value = false
  2402. getList()
  2403. } catch (error) {
  2404. proxy.$modal.msgError("接单失败: " + error.message)
  2405. }
  2406. }
  2407. })
  2408. }
  2409. /** 开始操作 */
  2410. function handleStart(row) {
  2411. /*startForm.value = {
  2412. id: row.id,
  2413. workOrderProjectNo: row.workOrderProjectNo,
  2414. pcsDeviceName: row.pcsDeviceName
  2415. }
  2416. startDialogVisible.value = true*/
  2417. ElMessageBox.confirm('确定要恢复工单"' + row.workOrderProjectNo + '"吗?', '提示', {
  2418. confirmButtonText: '确认恢复',
  2419. cancelButtonText: '取消',
  2420. type: 'warning'
  2421. }).then(function() {
  2422. startRepairOrder(row);
  2423. }).then(() => {
  2424. getList()
  2425. proxy.$modal.msgSuccess("恢复成功")
  2426. }).catch(() => {})
  2427. }
  2428. /** 提交开始处理 */
  2429. async function submitStart() {
  2430. try {
  2431. await startRepairOrder(startForm.value);
  2432. proxy.$modal.msgSuccess("工单已开始处理");
  2433. startDialogVisible.value = false;
  2434. getList();
  2435. } catch (error) {
  2436. proxy.$modal.msgError("操作失败: " + error.message);
  2437. }
  2438. }
  2439. /** 暂停操作 */
  2440. async function handlePause(row) {
  2441. proxy.$modal.confirm('是否确认暂停该工单?').then(async function() {
  2442. try {
  2443. const updateData = {
  2444. id: row.id,
  2445. workOrderStatus: "paused"
  2446. }
  2447. await pauseRepairOrder(updateData)
  2448. proxy.$modal.msgSuccess("工单已暂停")
  2449. getList()
  2450. } catch (error) {
  2451. proxy.$modal.msgError("操作失败: " + error.message)
  2452. }
  2453. }).catch(() => {})
  2454. }
  2455. /** 恢复工单 */
  2456. async function handleResume(row) {
  2457. ElMessageBox.confirm('确定要恢复工单"' + row.workOrderProjectNo + '"吗?', '提示', {
  2458. confirmButtonText: '确认恢复',
  2459. cancelButtonText: '取消',
  2460. type: 'warning'
  2461. }).then(function() {
  2462. const updateData = {
  2463. id: row.id,
  2464. workOrderStatus: "to_finish"
  2465. };
  2466. resumeRepairOrder(updateData);
  2467. }).then(() => {
  2468. getList()
  2469. proxy.$modal.msgSuccess("恢复成功")
  2470. }).catch(() => {})
  2471. }
  2472. /** 驳回工单 */
  2473. function handleReject(row) {
  2474. approveForm.value = {
  2475. id: row.id,
  2476. approvalStatus: "rejected",
  2477. rejectionReason: ""
  2478. };
  2479. approveDialogVisible.value = true;
  2480. }
  2481. /** 处理结束操作 */
  2482. function handleProcessDone(row) {
  2483. completeForm.value = {
  2484. id: row.id,
  2485. completeDescription: ""
  2486. }
  2487. completeDialogVisible.value = true
  2488. }
  2489. /** 处理MIS工单编码失去焦点事件 */
  2490. function handleMisOrderNoBlur() {
  2491. // 只有当配置为1时才自动获取数据
  2492. if (getMisDataConfig.value === "1" && finalizeForm.value.misOrderNo) {
  2493. // 创建一个只包含必要字段的对象,避免传递repairOrderFlowList等复杂对象
  2494. const requestData = {
  2495. id: finalizeForm.value.id,
  2496. misOrderNo: finalizeForm.value.misOrderNo
  2497. };
  2498. getRepairOrderByMisOrderNo(requestData).then(response => {
  2499. const data = response.data;
  2500. if (data) {
  2501. // 填充开始时间
  2502. if (data.realStartTime) {
  2503. finalizeForm.value.realStartTime = data.realStartTime;
  2504. }
  2505. // 填充结束时间
  2506. if (data.realEndTime) {
  2507. finalizeForm.value.realEndTime = data.realEndTime;
  2508. }
  2509. // 填充检修人员列表
  2510. if (data.workGroupMemberName) {
  2511. finalizeForm.value.workGroupMemberName = data.workGroupMemberName;
  2512. }
  2513. if (data.repairOrderPersonList && data.repairOrderPersonList.length > 0) {
  2514. finalizeForm.value.repairOrderPersonList = data.repairOrderPersonList;
  2515. }
  2516. } else {
  2517. finalizeForm.value.realStartTime = null;
  2518. finalizeForm.value.realEndTime = null;
  2519. finalizeForm.value.workGroupMemberName = null;
  2520. finalizeForm.value.repairOrderPersonList = [];
  2521. proxy.$modal.msgWarning("未找到对应的MIS工单信息");
  2522. }
  2523. }).catch(error => {
  2524. finalizeForm.value.realStartTime = null;
  2525. finalizeForm.value.realEndTime = null;
  2526. finalizeForm.value.workGroupMemberName = null;
  2527. finalizeForm.value.repairOrderPersonList = [];
  2528. proxy.$modal.msgError("获取MIS工单信息失败: " + error.message);
  2529. });
  2530. }
  2531. }
  2532. /** 提交完成 */
  2533. async function submitComplete() {
  2534. proxy.$refs["completeFormRef"].validate(async valid => {
  2535. if (valid) {
  2536. try {
  2537. const updateData = {
  2538. id: completeForm.value.id,
  2539. workOrderStatus: "to_be_finalized",
  2540. realEndTime: new Date(),
  2541. completeDescription: completeForm.value.completeDescription
  2542. }
  2543. await processDoneRepairOrder(updateData)
  2544. proxy.$modal.msgSuccess("处理完成,工单进入待结单状态")
  2545. completeDialogVisible.value = false
  2546. getList()
  2547. } catch (error) {
  2548. proxy.$modal.msgError("操作失败: " + error.message)
  2549. }
  2550. }
  2551. })
  2552. }
  2553. /** 评分操作 */
  2554. function handleRating(row) {
  2555. getRepairOrder(row.id).then(response => {
  2556. ratingForm.value = response.data
  2557. ratingForm.value.score = null
  2558. ratingDialogVisible.value = true
  2559. })
  2560. }
  2561. /** 提交评分 */
  2562. async function submitRating() {
  2563. proxy.$refs["ratingFormRef"].validate(async valid => {
  2564. if (valid) {
  2565. try {
  2566. await ratingRepairOrder(ratingForm.value)
  2567. proxy.$modal.msgSuccess("评分成功")
  2568. ratingDialogVisible.value = false
  2569. getList()
  2570. } catch (error) {
  2571. proxy.$modal.msgError("操作失败: " + error.message)
  2572. }
  2573. }
  2574. })
  2575. }
  2576. /** 查看按钮操作 */
  2577. async function handleView(row) {
  2578. try {
  2579. // 获取工单详情
  2580. const response = await getRepairOrder(row.id)
  2581. viewForm.value = response.data
  2582. // 从工单详情中获取流转记录
  2583. flowList.value = response.data.repairOrderFlowList || []
  2584. viewDialogVisible.value = true
  2585. } catch (error) {
  2586. proxy.$modal.msgError("获取工单信息失败: " + error.message)
  2587. }
  2588. }
  2589. /** 挂起工单 */
  2590. function handleSuspend(row) {
  2591. suspendForm.value = row
  2592. suspendForm.value.suspendReason = undefined
  2593. suspendDialogVisible.value = true
  2594. }
  2595. /** 提交挂起 */
  2596. async function submitSuspend() {
  2597. proxy.$refs["suspendFormRef"].validate(async valid => {
  2598. if (valid) {
  2599. try {
  2600. await suspendRepairOrder(suspendForm.value);
  2601. proxy.$modal.msgSuccess("挂起申请已提交");
  2602. suspendDialogVisible.value = false;
  2603. getList();
  2604. } catch (error) {
  2605. proxy.$modal.msgError("挂起申请失败: " + error.message);
  2606. }
  2607. }
  2608. });
  2609. }
  2610. /** 审批挂起 */
  2611. function handleApprove(row) {
  2612. getRepairOrder(row.id).then(response => {
  2613. approveForm.value = response.data
  2614. approveForm.value.approvalStatus = undefined
  2615. approveForm.value.rejectionReason = undefined
  2616. approveDialogVisible.value = true
  2617. })
  2618. }
  2619. /** 切换驳回原因显示 */
  2620. function toggleRejectionReason() {
  2621. // 驳回原因的必填验证由表单规则控制
  2622. }
  2623. /** 提交审批 */
  2624. async function submitApprove(approvalStatusValue) {
  2625. proxy.$refs["approveFormRef"].validate(async valid => {
  2626. if (valid) {
  2627. try {
  2628. approveForm.value.approvalStatus = approvalStatusValue
  2629. /*if (approveForm.value.approvalStatus === 'approved') {
  2630. approveForm.value.rejectionReason = undefined;
  2631. }*/
  2632. if (approveForm.value.approvalStatus === 'rejected' && !approveForm.value.rejectionReason) {
  2633. proxy.$modal.msgError("驳回时审批意见不能为空");
  2634. return;
  2635. }
  2636. await approveSuspendRepairOrder(approveForm.value);
  2637. proxy.$modal.msgSuccess("操作完成");
  2638. approveDialogVisible.value = false;
  2639. getList();
  2640. } catch (error) {
  2641. proxy.$modal.msgError("操作失败: " + error.message);
  2642. }
  2643. }
  2644. });
  2645. }
  2646. /** 结单操作 */
  2647. function handleFinalize(row) {
  2648. getRepairOrder(row.id).then(response => {
  2649. finalizeForm.value = { ...response.data, selectedMembers: [] }
  2650. finalizeDialogVisible.value = true
  2651. commonKey++
  2652. /*// 获取场站ID用于查询用户
  2653. finalizeForm.value.pcsStationId = response.data.pcsStationId
  2654. finalizeForm.value.pcsStationPid = response.data.pcsStationPid
  2655. // 根据场站ID查询该场站的用户列表
  2656. if (finalizeForm.value.pcsStationPid) {
  2657. listUser({ pageNum: 1, pageSize: 100, deptId: finalizeForm.value.pcsStationPid }).then(response => {
  2658. userList.value = response.rows
  2659. finalizeDialogVisible.value = true
  2660. })
  2661. }else if (finalizeForm.value.pcsStationId) {
  2662. // 先获取部门信息,判断level是否为4,如果是则查找其父部门直到level为3
  2663. getDeptAndUserByLevel(finalizeForm.value.pcsStationId).then(deptId => {
  2664. // 确保 deptId 是有效的再调用 listUser
  2665. if (deptId) {
  2666. listUser({ pageNum: 1, pageSize: 100, deptId: deptId }).then(response => {
  2667. userList.value = response.rows
  2668. finalizeDialogVisible.value = true
  2669. })
  2670. } else {
  2671. // 如果没有找到有效的部门ID,仍然打开对话框但给出提示
  2672. proxy.$modal.msgWarning("未找到有效的部门信息,无法加载用户列表");
  2673. finalizeDialogVisible.value = true
  2674. }
  2675. })
  2676. } else {
  2677. proxy.$modal.msgWarning("未找到有效的部门信息,无法加载用户列表");
  2678. finalizeDialogVisible.value = true
  2679. }*/
  2680. })
  2681. }
  2682. /** 提交结单 */
  2683. async function submitFinalize() {
  2684. if (!finalizeForm.value.realEndTime) {
  2685. proxy.$modal.msgError("该工单未结束,无法结单!")
  2686. return
  2687. }
  2688. proxy.$refs["finalizeFormRef"].validate(async valid => {
  2689. if (valid) {
  2690. try {
  2691. // 更新检修人员列表
  2692. //handleMembersChange('finalizeForm');
  2693. await finalizeRepairOrder(finalizeForm.value)
  2694. proxy.$modal.msgSuccess("工单结单成功")
  2695. finalizeDialogVisible.value = false
  2696. getList()
  2697. } catch (error) {
  2698. proxy.$modal.msgError("操作失败: " + error.message)
  2699. }
  2700. }
  2701. })
  2702. }
  2703. /** 检修人员选择变化 */
  2704. function handleMembersChange(formName) {
  2705. // 默认使用 acceptForm,但也支持其他表单
  2706. const targetForm = formName === 'finalizeForm' ? finalizeForm : acceptForm;
  2707. // 清空之前的列表
  2708. targetForm.value.repairOrderPersonList = [];
  2709. // 为每个选中的成员创建 GxtRepairOrderPerson 对象
  2710. targetForm.value.selectedMembers.forEach(userId => {
  2711. const user = userList.value.find(u => u.userId === userId)
  2712. if (user) {
  2713. targetForm.value.repairOrderPersonList.push({
  2714. userId: user.userId,
  2715. nickName: user.nickName,
  2716. orderId: targetForm.value.id,
  2717. orderCode: targetForm.value.workOrderProjectNo,
  2718. status: 1
  2719. });
  2720. }
  2721. });
  2722. }
  2723. /** 复运操作 */
  2724. function handleRestart(row) {
  2725. getRepairOrder(row.id).then(response => {
  2726. restartForm.value = response.data
  2727. restartDialogVisible.value = true
  2728. })
  2729. }
  2730. /** 提交复运 */
  2731. async function submitRestart() {
  2732. proxy.$refs["restartFormRef"].validate(async valid => {
  2733. if (valid) {
  2734. try {
  2735. await restartRepairOrder(restartForm.value)
  2736. proxy.$modal.msgSuccess("复运成功")
  2737. restartDialogVisible.value = false
  2738. getList()
  2739. } catch (error) {
  2740. proxy.$modal.msgError("操作失败: " + error.message)
  2741. }
  2742. }
  2743. })
  2744. }
  2745. function handleImgUplaoded(imgUrl){
  2746. from.value.workUrl = imgUrl;
  2747. }
  2748. function handleImgRemoved(imgUrl){
  2749. form.value.workUrl = null;
  2750. }
  2751. /*** MIS导入参数 */
  2752. const uploadMis = reactive({
  2753. // 是否显示弹出层(设备导入)
  2754. open: false,
  2755. // 弹出层标题(设备导入)
  2756. title: "",
  2757. // 是否禁用上传
  2758. isUploading: false,
  2759. // 是否更新已经存在的设备数据
  2760. updateSupport: 0,
  2761. // 设置上传的请求头部
  2762. headers: { Authorization: "Bearer " + getToken() },
  2763. // 上传的地址
  2764. url: import.meta.env.VITE_APP_BASE_API + "/gxt/repairOrder/importDataMis"
  2765. })
  2766. /** 导入按钮操作 */
  2767. function handleImportMis() {
  2768. uploadMis.title = "MIS工单导入"
  2769. uploadMis.open = true
  2770. uploadMis.selectedFile = null
  2771. }
  2772. /** 下载模板操作 */
  2773. function importTemplateMis() {
  2774. proxy.download("gxt/repairOrder/importTemplateMis", {
  2775. }, `repairOrderMis_template_${new Date().getTime()}.xlsx`)
  2776. }
  2777. /**文件上传中处理 */
  2778. const handleFileUploadProgressMis = (event, file, fileList) => {
  2779. uploadMis.isUploading = true
  2780. }
  2781. /** 文件选择处理 */
  2782. const handleFileChangeMis = (file, fileList) => {
  2783. uploadMis.selectedFile = file
  2784. }
  2785. /** 文件删除处理 */
  2786. const handleFileRemoveMis = (file, fileList) => {
  2787. uploadMis.selectedFile = null
  2788. }
  2789. /** 文件上传成功处理 */
  2790. const handleFileSuccessMis = (response, file, fileList) => {
  2791. uploadMis.open = false
  2792. uploadMis.isUploading = false
  2793. proxy.$refs["uploadMisRef"].handleRemove(file)
  2794. proxy.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果", { dangerouslyUseHTMLString: true })
  2795. getList()
  2796. }
  2797. /** 提交上传文件 */
  2798. function submitFileFormMis() {
  2799. const file = uploadMis.selectedFile
  2800. if (!file || file.length === 0 || !file.name.toLowerCase().endsWith('.xls') && !file.name.toLowerCase().endsWith('.xlsx')) {
  2801. proxy.$modal.msgError("请选择后缀为 “xls”或“xlsx”的文件。")
  2802. return
  2803. }
  2804. proxy.$refs["uploadMisRef"].submit()
  2805. }
  2806. /*** 维修工单导入参数 */
  2807. const upload = reactive({
  2808. // 是否显示弹出层(设备导入)
  2809. open: false,
  2810. // 弹出层标题(设备导入)
  2811. title: "",
  2812. // 是否禁用上传
  2813. isUploading: false,
  2814. // 是否更新已经存在的设备数据
  2815. updateSupport: 0,
  2816. // 设置上传的请求头部
  2817. headers: { Authorization: "Bearer " + getToken() },
  2818. // 上传的地址
  2819. url: import.meta.env.VITE_APP_BASE_API + "/gxt/repairOrder/importData"
  2820. })
  2821. /** 导入按钮操作 */
  2822. function handleImport() {
  2823. upload.title = "维修工单导入"
  2824. upload.open = true
  2825. upload.selectedFile = null
  2826. }
  2827. /** 下载模板操作 */
  2828. function importTemplate() {
  2829. proxy.download("gxt/repairOrder/importTemplate", {
  2830. }, `repairOrder_template_${new Date().getTime()}.xlsx`)
  2831. }
  2832. /**文件上传中处理 */
  2833. const handleFileUploadProgress = (event, file, fileList) => {
  2834. upload.isUploading = true
  2835. }
  2836. /** 文件选择处理 */
  2837. const handleFileChange = (file, fileList) => {
  2838. upload.selectedFile = file
  2839. }
  2840. /** 文件删除处理 */
  2841. const handleFileRemove = (file, fileList) => {
  2842. upload.selectedFile = null
  2843. }
  2844. /** 文件上传成功处理 */
  2845. const handleFileSuccess = (response, file, fileList) => {
  2846. upload.open = false
  2847. upload.isUploading = false
  2848. proxy.$refs["uploadRef"].handleRemove(file)
  2849. proxy.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果", { dangerouslyUseHTMLString: true })
  2850. getList()
  2851. }
  2852. /** 提交上传文件 */
  2853. function submitFileForm() {
  2854. const file = upload.selectedFile
  2855. if (!file || file.length === 0 || !file.name.toLowerCase().endsWith('.xls') && !file.name.toLowerCase().endsWith('.xlsx')) {
  2856. proxy.$modal.msgError("请选择后缀为 “xls”或“xlsx”的文件。")
  2857. return
  2858. }
  2859. proxy.$refs["uploadRef"].submit()
  2860. }
  2861. /** 打开MIS信息选择对话框 */
  2862. function handleSelectMisInfo() {
  2863. misInfoSelectVisible.value = true
  2864. }
  2865. /** 设备MIS信息回调 */
  2866. function onMisInfoSelected(row) {
  2867. if (row) {
  2868. listRepairOrder({pageNum: 1, pageSize: 10, misOrderNo: row.misNo }).then(response => {
  2869. const gxtOrders= response.rows
  2870. if (gxtOrders.length > 0) {
  2871. proxy.$modal.msgWarning('选择工单已存在!请重新选择!')
  2872. return
  2873. }
  2874. finalizeForm.value.misOrderNo = row.misNo
  2875. finalizeForm.value.realStartTime = row.realStartTime
  2876. finalizeForm.value.realEndTime = row.realEndTime
  2877. // finalizeForm.value.content = row.content
  2878. listWorkPerson({ misNo: row.misNo }).then(response => {
  2879. debugger
  2880. finalizeForm.value.repairOrderPersonList = response.rows;
  2881. if (finalizeForm.value.repairOrderPersonList) {
  2882. const nickNames = finalizeForm.value.repairOrderPersonList
  2883. .map(person => person.nickName)
  2884. .join(',');
  2885. finalizeForm.value.workGroupMemberName = nickNames
  2886. }
  2887. })
  2888. misInfoSelectVisible.value = false
  2889. })
  2890. }
  2891. }
  2892. </script>
  2893. <style scoped>
  2894. .text-gray-500 {
  2895. color: #6b7280;
  2896. }
  2897. .mb-2 {
  2898. margin-bottom: 0.5rem;
  2899. }
  2900. .mb-3 {
  2901. margin-bottom: 0.75rem;
  2902. }
  2903. .card-header {
  2904. font-weight: bold;
  2905. font-size: 16px;
  2906. }
  2907. .info-section {
  2908. padding: 16px 0;
  2909. height: 100%;
  2910. box-sizing: border-box;
  2911. }
  2912. .section-title {
  2913. font-weight: bold;
  2914. font-size: 16px;
  2915. margin-bottom: 15px;
  2916. padding-bottom: 10px;
  2917. border-bottom: 1px solid #ebeef5;
  2918. }
  2919. .info-content {
  2920. height: calc(100% - 30px);
  2921. overflow-y: auto;
  2922. overflow-x: hidden; /* 防止横向滚动 */
  2923. padding: 0 10px; /* 添加内边距防止内容贴边 */
  2924. }
  2925. .info-item {
  2926. margin-bottom: 12px;
  2927. }
  2928. .info-item label {
  2929. display: block;
  2930. font-size: 12px;
  2931. color: #999;
  2932. margin-bottom: 4px;
  2933. }
  2934. .info-item p {
  2935. font-size: 14px;
  2936. color: #333;
  2937. margin: 0;
  2938. line-height: 1.4;
  2939. }
  2940. .flow-history {
  2941. height: 100%;
  2942. padding: 0 10px; /* 添加内边距防止内容贴边 */
  2943. }
  2944. .flow-history .el-timeline {
  2945. margin-left: 0;
  2946. padding-left: 0;
  2947. }
  2948. .flow-item {
  2949. /*padding: 10px;
  2950. border-radius: 4px;*/
  2951. }
  2952. .flow-item h4 {
  2953. margin: 0 0 5px 0;
  2954. font-size: 14px;
  2955. font-weight: bold;
  2956. }
  2957. .flow-item p {
  2958. margin: 0;
  2959. font-size: 12px;
  2960. line-height: 1.4;
  2961. color: #606266;
  2962. }
  2963. /* 修复对话框底部按钮点击区域问题 */
  2964. :deep(.el-dialog__footer) {
  2965. padding: 20px !important;
  2966. position: relative;
  2967. z-index: 10;
  2968. }
  2969. /* 确保关闭按钮有完整的点击区域 */
  2970. .dialog-footer :deep(.el-button) {
  2971. padding: 12px 20px;
  2972. min-width: 80px;
  2973. z-index: 20;
  2974. position: relative;
  2975. }
  2976. /* 表单字段间距调整 */
  2977. :deep(.el-form-item) {
  2978. margin-bottom: 18px;
  2979. }
  2980. /* 表单中的列间距调整 */
  2981. :deep(.el-col) {
  2982. padding-left: 5px;
  2983. padding-right: 5px;
  2984. }
  2985. /* 表单行间距调整 */
  2986. :deep(.el-row) {
  2987. margin-left: -5px;
  2988. margin-right: -5px;
  2989. }
  2990. /* MIS工单快速检索样式 */
  2991. .quick-select-dropdown {
  2992. position: absolute;
  2993. top: 100%;
  2994. left: 0;
  2995. right: 0;
  2996. background: white;
  2997. border: 1px solid #e4e7ed;
  2998. border-top: none;
  2999. border-radius: 0 0 4px 4px;
  3000. max-height: 200px;
  3001. overflow-y: auto;
  3002. z-index: 2000;
  3003. box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  3004. }
  3005. .quick-select-item {
  3006. padding: 8px 12px;
  3007. cursor: pointer;
  3008. border-bottom: 1px solid #f0f0f0;
  3009. display: flex;
  3010. justify-content: space-between;
  3011. align-items: center;
  3012. }
  3013. .quick-select-item:hover {
  3014. background-color: #f5f7fa;
  3015. }
  3016. .quick-select-item:last-child {
  3017. border-bottom: none;
  3018. }
  3019. .mis-no {
  3020. font-weight: bold;
  3021. color: #409eff;
  3022. flex-shrink: 0;
  3023. }
  3024. .mis-info {
  3025. display: flex;
  3026. flex-direction: column;
  3027. align-items: flex-end;
  3028. flex: 1;
  3029. margin-left: 10px;
  3030. }
  3031. .mis-info .device {
  3032. color: #606266;
  3033. font-size: 12px;
  3034. margin-bottom: 2px;
  3035. }
  3036. .mis-info .station {
  3037. color: #909399;
  3038. font-size: 11px;
  3039. }
  3040. .no-data {
  3041. padding: 15px;
  3042. text-align: center;
  3043. color: #909399;
  3044. font-size: 14px;
  3045. }
  3046. /* 确保表单项有相对定位 */
  3047. :deep(.el-form-item) {
  3048. position: relative;
  3049. }
  3050. /* 输入框样式调整 */
  3051. :deep(.el-input-group__append) {
  3052. background-color: #409eff;
  3053. border-color: #409eff;
  3054. color: white;
  3055. }
  3056. :deep(.el-input-group__append .el-button) {
  3057. color: white;
  3058. border: none;
  3059. }
  3060. :deep(.el-input-group__append .el-button:hover) {
  3061. background-color: #66b1ff;
  3062. }
  3063. /* 表单字段间距调整 */
  3064. :deep(.el-form-item) {
  3065. margin-bottom: 18px;
  3066. }
  3067. .content-text {
  3068. white-space: pre-wrap;
  3069. word-break: break-word;
  3070. line-height: 1.5;
  3071. }
  3072. </style>