| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494 |
- <template>
- <div class="container-panel">
- <el-row class="info-panel">
- <div class="info-item">
- <span class="label">报告编号:</span>
- <span class="value">{{ selectedItem?.reportNo || '-' }}</span>
- </div>
- <div class="info-item" style="margin: 0 auto;" v-if="isShowRecordOrReportBtn">
- <!-- <el-switch-->
- <!-- v-model="isShowReportPdf"-->
- <!-- active-text="报告"-->
- <!-- inactive-text="记录"-->
- <!-- @change="handleChangeShowReportPdf"-->
- <!-- />-->
- <!-- <el-radio-group v-model="showReportPdfType" @change="handleChangeShowReportPdf">-->
- <!-- <el-radio-button label="record">记录</el-radio-button>-->
- <!-- <el-radio-button label="report">报告</el-radio-button>-->
- <!-- <el-radio-button label="result" v-if="selectedItem?.reportType === 100">结论报告</el-radio-button>-->
- <!-- </el-radio-group>-->
- <div class="capsule-tabs">
- <div
- class="tab-item"
- :class="{ active: showReportPdfType === 'record' }"
- @click="handleChangeShowReportPdf('record')"
- v-if="hasRecord"
- >
- <span>记录</span>
- </div>
- <div
- class="tab-item"
- :class="{ active: showReportPdfType === 'report' }"
- @click="handleChangeShowReportPdf('report')"
- >
- <span>报告</span>
- </div>
- </div>
- </div>
- <div class="info-item" style="margin: 0 auto;">
- <span class="label">检验项目:</span>
- <span class="value" :title="selectedItem?.reportName || '-'">{{
- selectedItem?.reportName || '-'
- }}</span>
- </div>
- <div v-if="selectedItem?.reportType === 300">
- <span>{{ selectedItem.instructionId ? '已' : '未'}}关联操作指导书</span>
- <el-button
- type="primary"
- size="small"
- link
- class="edit-checker-btn"
- @click="handleShowAssociationOperationManual"
- >
- <Icon icon="ep:edit" />
- </el-button>
- </div>
- <div class="info-item" style="flex-basis: 300px; text-align: end;">
- <span class="label">{{ selectedItem?.reportType === 100 ? '主检人' : '检验员' }}:</span>
- <span
- class="value"
- :title="
- selectedItem?.reportType === 100
- ? taskOrderItem?.mainCheckerUser?.nickname || '-'
- : getCheckersName()
- "
- >{{
- selectedItem?.reportType === 100
- ? taskOrderItem?.mainCheckerUser?.nickname || '-'
- : getCheckersName()
- }}</span
- >
- <el-button
- v-if="!isAuditMode"
- type="primary"
- size="small"
- link
- class="edit-checker-btn"
- @click="
- () =>
- selectedItem?.reportType === 100 ? handleModifyMainChecker() : handleModifyChecker()
- "
- :disabled="(selectedItem?.reportType === 100 && taskOrderItem?.mainCheckerUser?.id !== userStore?.user?.id)
- || (selectedItem?.checkUsers?.length > 0 && selectedItem?.checkUsers?.[0]?.id !== userStore?.user?.id && taskOrderItem?.mainCheckerUser?.id !== userStore?.user?.id)
- || isCompleteInput"
- >
- <!-- 主报告:登录用户为主检人的时,才可以修改主检人 -->
- <!-- 子报告:登录用户为检验员或主检人的时候,才可以修改检验员 -->
- <Icon icon="ep:edit" />
- </el-button>
- </div>
- </el-row>
- <el-row class="status-operation-panel">
- <!-- 未选择任何项目时的提示 -->
- <div v-if="!selectedItem" class="no-selection">
- <el-empty description="请选择一个检验项目查看详情" :image-size="100" />
- </div>
- <!-- 选择单个项目时显示详情操作 -->
- <div v-else class="single-item-panel">
- <!--
- 1、重大问题线索告知表
- 2、作业指导书
- 3、检验方案
- 以上报告类型不显示做进度栏目
- -->
- <InspectionItemProgress
- v-if="!onlyShowPdf"
- :selected-item="selectedItem"
- :task-info="taskInfo"
- :is-audit-mode="isAuditMode"
- @modify-checker="handleModifyChecker"
- />
- <!-- <div class="pdf-panel" :style="{ maxWidth: !onlyShowPdf ? '1200px' : 'unset' }"> -->
- <div ref="pdfPanelRef" class="pdf-panel" >
- <!-- PDF预览区域 -->
- <div class="!h-full" :style="{ width: pdfContentWidth + 'px'}">
- <SpreadViewer :initData="initData" ref="spreadRef" isFullscreen @saveSuccess="saveSuccess"/>
- </div>
- </div>
- <!--
- 1、重大问题线索告知表
- 2、作业指导书
- 3、检验方案
- 以上报告类型不显示右侧栏目
- -->
- <template v-if="showCheckBook && getReportStatusEnd">
- <div class="right-panel-container">
- <!-- 收缩展开按钮 -->
- <div class="toggle-btn" @click="togglePanel" :class="{ 'collapsed': !isExpanded }">
- <el-icon>
- <Back v-if="!isExpanded" />
- <Right v-else />
- </el-icon>
- </div>
- <div class="operation-panel" :class="{ 'expanded': isExpanded, 'collapsed': !isExpanded }">
- <div class="operation-inner custom-inner">
- <template v-if="checkBookDetail.rectificationStatus === 2">
- <div class="operation-item">
- <div class="item-header"> 回退原因 </div>
- <div class="item-content">
- <el-form
- ref="returnFormRef"
- :model="returnForm"
- :rules="returnFormRules"
- label-position="right"
- label-width="80px"
- >
- <el-form-item label="回退原因" prop="rejectionReason">
- <el-input
- v-model="returnForm.rejectionReason"
- type="textarea"
- :rows="5"
- maxlength="100"
- placeholder="请输入回退原因"
- />
- </el-form-item>
- </el-form>
- </div>
- </div>
- </template>
- <div class="operation-item1">
- <div class="item-header"> 处理人信息 </div>
- <div class="item-content">
- <div class="item-content-item">
- <span class="item-content-item-label">联系人姓名:</span>
- <span class="item-content-item-value">{{ checkBookDetail?.recipient || '-' }}</span>
- </div>
- <div class="item-content-item">
- <span class="item-content-item-label">联系人电话:</span>
- <span class="item-content-item-value">{{ checkBookDetail?.recipientPhone || '-'}}</span>
- </div>
- <div class="item-content-item">
- <span class="item-content-item-label">当前状态:</span>
- <span class="item-content-item-value">{{
- rectificationStatusMap[checkBookDetail?.rectificationStatus] || '-'
- }}</span>
- </div>
- </div>
- </div>
- <div class="operation-item1 videoAndImg">
- <div class="item-header"> 整改材料 </div>
- <div class="item-content1">
- <div class="item-content1-item">图片:</div>
- <div class="item-content1-img">
- <template
- v-for="(path, index) in checkBookDetail.rectificationImage?.split(',') || []"
- :key="'img' + index"
- >
- <div class="item-content1-img-item">
- <el-image
- class="img-item"
- :src="buildFileUrl(path)"
- :preview-src-list="[buildFileUrl(path)]"
- fit="cover"
- preview-teleported
- />
- </div>
- </template>
- </div>
- </div>
- <div class="item-content1">
- <div class="item-content1-item">视频:</div>
- <div class="item-content1-img">
- <template
- v-for="(path, index) in checkBookDetail.rectificationVideo?.split(',') || []"
- :key="'vid' + index"
- >
- <div class="item-content1-img-item" @click="handlePreview(buildFileUrl(path), 'video')">
- <video class="img-item" :src="buildFileUrl(path)"></video>
- <div class="video-play-overlay">
- <el-icon :size="28"><VideoPlay /></el-icon>
- </div>
- </div>
- </template>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </template>
- <template v-else>
- <div class="right-panel-container">
- <!-- 收缩展开按钮 -->
- <div class="toggle-btn" @click="togglePanel" :class="{ 'collapsed': !isExpanded }" v-if="!onlyShowPdf">
- <el-icon>
- <Back v-if="!isExpanded" />
- <Right v-else />
- </el-icon>
- </div>
- <div class="operation-panel" :class="{ 'expanded': isExpanded, 'collapsed': !isExpanded }" v-if="!onlyShowPdf">
- <div class="operation-inner">
- <!-- 流转记录 -->
- <div class="operation-item">
- <div class="item-header"> 流转记录 </div>
- <div class="item-content">
- <el-empty
- v-if="!recordList.length"
- description="暂无流转记录"
- :image-size="120"
- />
- <div class="record-item" v-for="record in recordList" :key="record.id">
- <div class="record-item-title">{{ PressureReportType['SUGGUESTION'] === props.selectedItem?.reportType ? record.processName : PressureCheckerMyTaskStatusMap[record.process]
- }}</div>
- <div class="record-item-inner">
- <div class="content">
- <span>{{ record.createUser?.nickname }}</span>
- <el-button
- :type="
- OAApprovalResultType[record.result] ||
- (record.result === 100 || record.result === '100'
- ? 'success'
- : record.result === 200 || record.result === '200'
- ? 'danger'
- : 'default')
- "
- round
- size="small"
- >{{
- OAApprovalResultMap[record.result] ||
- (record.result === 100 || record.result === '100'
- ? '通过'
- : record.result === 200 || record.result === '200'
- ? '拒绝'
- : record.result || '-')
- }}</el-button
- >
- <span class="time">{{
- !record.createTime
- ? '-'
- : dayjs(record.createTime).format('YYYY-MM-DD HH:mm:ss')
- }}</span>
- </div>
- <p class="desc">
- <span>描述</span>
- {{ record.remark && record.remark.trim() !== '' ? record.remark : '-' }}
- </p>
- </div>
- </div>
- </div>
- </div>
- <!-- 智能纠错 -->
- <div class="operation-item">
- <div class="item-header"> 智能纠错 </div>
- <div class="item-content">
- <el-empty
- v-if="!checkInputList.length"
- description="暂无纠错内容"
- :image-size="120"
- />
- <div class="error-item" v-for="input in checkInputList" :key="input.code">
- <el-icon color="#E0534E" :size="20"><InfoFilled /></el-icon>
- {{ input.code }}:{{ input.name }}
- </div>
- </div>
- </div>
- <!-- 历史版本 -->
- <div class="operation-item">
- <div class="item-header"> 历史版本 </div>
- <div class="item-content" v-if="historyList.length">
- <!-- <template> -->
- <div class="history-item" v-for="item in historyList" :key="item.id">
- <div class="history-title">{{ item.versionNoStr || '-' }}号版本</div>
- <p
- >修改原因:<span>{{ item.modifiedReason || '人工修改' }}</span></p
- >
- <div class="history-footer">
- <span class="name">{{ item.creatorName || '-' }}</span>
- <span class="time"
- >修改于{{
- dayjs(item.updateTime).format('YYYY-MM-DD HH:mm:ss') || '-'
- }}</span
- >
- </div>
- <div class="my-2">
- <el-button type="primary" link @click="handleShowVersionInfo(item)"
- >查看详情</el-button
- >
- <el-button v-if="!checkerIsLoginUser" type="primary" link @click="restoreVersion(item)"
- >恢复版本</el-button
- >
- </div>
- </div>
- <!-- </template> -->
- </div>
- <template v-else>
- <el-empty description="暂无历史版本" :image-size="120" />
- </template>
- </div>
- </div>
- </div>
- </div>
- </template>
- </div>
- <!-- 审批人选择对话框 -->
- <AuditUserDialog
- v-if="isShowApprovalDialog"
- v-model="isShowApprovalDialog"
- :apiFn="getRecheckUserList"
- title="请选择审批人"
- selectedAlertText="已选择审批人"
- width="700px"
- :columns="[
- {
- type: 'selection',
- fieldProps: {
- reserveSelection: true
- }
- },
- {
- label: '姓名',
- prop: 'nickname',
- search: {
- type: 'input',
- span: 12,
- prop: 'nickName'
- }
- },
- {
- label: '部门',
- prop: 'deptName',
- search: {
- type: 'input',
- span: 12
- }
- }
- ]"
- @confirm="handleApprovalSelectConfirm"
- />
- <Dialog
- v-model="isShowAuditDialog"
- width="400"
- :title="schemaFlag == 'proofread' ? '请选择校核人' : '请选择审核人'"
- >
- <CustomLargeListSelect
- v-model="form.recheckUser"
- :fetchFunc="getRecheckUserList"
- label-key="nickname"
- value-key="id"
- searchKeyProp="nickName"
- @change="handleChangeEntrustUnit"
- />
- <template #footer>
- <el-button type="primary" @click="handleAuditSelectConfirm" :loading="submitting">保 存</el-button>
- <el-button @click="isShowAuditDialog = false">取 消</el-button>
- </template>
- </Dialog>
- <!-- 批量提交校核 -->
- <Dialog
- v-model="showBatchSubmitToRecheckDialog"
- width="400"
- title="批量提交校核"
- >
- <el-form ref="batchRecheckFormRef" :model="batchRecheckForm" :rules="batchRecheckFormRules" label-width="80px">
- <el-form-item label="提交记录" prop="reportIds">
- <el-select
- v-model="batchRecheckForm.reportIds"
- multiple
- clearable
- placeholder="请选择报告"
- >
- <el-option
- v-for="item in getCanSubmitRecheckReport"
- :key="item.id"
- :value="item.id"
- :label="item.reportName"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="校核人" prop="recheckUser">
- <CustomLargeListSelect
- v-model="batchRecheckForm.recheckUser"
- :fetchFunc="getRecheckUserList"
- label-key="nickname"
- value-key="id"
- searchKeyProp="nickName"
- @change="handleChangeEntrustUnit"
- placeholder="请选择校核人"
- />
- </el-form-item>
- <el-form-item label="">
- <span style="font-size: 13px; white-space: nowrap; margin-top: -16px; color: #999;">
- 您已完成{{getCanSubmitRecheckReport.length}}份记录录入,可以进行批量提交校核
- </span>
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button type="primary" @click="handleBatchSubmitToRecheck">提 交</el-button>
- <el-button @click="showBatchSubmitToRecheckDialog = false">取 消</el-button>
- </template>
- </Dialog>
- <!-- 校核人选择对话框 暂时作废
- -->
- <!-- <AuditUserDialog
- v-if="isShowAuditDialog"
- v-model="isShowAuditDialog"
- :apiFn="getRecheckUserList"
- title="请选择校核人"
- selectedAlertText="已选择校核人"
- width="700px"
- :pageType="0"
- :columns="[
- {
- type: 'selection',
- fieldProps: {
- reserveSelection: true
- }
- },
- {
- label: '姓名',
- prop: 'nickname',
- search: {
- type: 'input',
- span: 12,
- prop: 'nickName'
- }
- },
- {
- label: '部门',
- prop: 'deptName',
- search: {
- type: 'input',
- span: 12
- }
- }
- ]"
- @confirm="handleAuditSelectConfirm"
- /> -->
- <!-- 报告审核人选择对话框 -->
- <Dialog
- v-model="isShowReportAuditDialog"
- width="400"
- title="请选择审核人"
- >
- <el-select
- v-model="reportAuditUserCode"
- filterable
- placeholder="请选择审核人"
- :loading="reportAuditUserLoading"
- clearable
- style="width: 100%"
- >
- <el-option
- v-for="item in reportAuditUserOptions"
- :key="item.code"
- :label="item.name"
- :value="item.code"
- />
- </el-select>
- <template #footer>
- <el-button type="primary" :loading="reportAuditSubmitting" @click="handleReportAuditSelectConfirm">确 定</el-button>
- <el-button @click="isShowReportAuditDialog = false">取 消</el-button>
- </template>
- </Dialog>
- </el-row>
- <!-- 检验结果录入-葡萄城模板 -->
- <InlineInspectionResultInput
- v-if="showInlineInspectionResultInput"
- v-model:visible="showInlineInspectionResultInput"
- :template-params="inspectionResultTemplateParams"
- @confirm="handleInspectionResultConfirm"
- @cancel="handleReturnToNormalMode"
- />
- <!-- 检验录入-模板 -->
- <!-- <InlineEditCheckRecord-->
- <!-- v-if="showInlineEditCheckRecord"-->
- <!-- :templateId="templateId"-->
- <!-- v-model:visible="showInlineEditCheckRecord"-->
- <!-- :report-list="reportList"-->
- <!-- :task-order-item="taskOrderItem"-->
- <!-- :template-params="templateParams"-->
- <!-- @confirm="handleTemplateConfirm"-->
- <!-- @cancel="handleRefresh"-->
- <!-- />-->
- <!-- 检验录入-模板 -->
- <CustomDialog v-model="showInlineEditCheckRecord" :show-footer="false" fullscreen :show-close="false">
- <SpreadViewer :initData="editData" ref="editSpreadRecordRef" @saveSuccess="saveSuccessRecord" @close="handleClose">
- <template #title>
- <div style="font-size: 20px; ">检验录入</div>
- </template>
- </SpreadViewer>
- </CustomDialog>
- <!-- 报告编制 - 模板 -->
- <!-- <InlineReportEdit-->
- <!-- v-if="showInlineReportEdit"-->
- <!-- v-model:visible="showInlineReportEdit"-->
- <!-- :template-params="templateParams"-->
- <!-- :report-list="reportList || []"-->
- <!-- :report-type="showReportPdfType"-->
- <!-- @confirm="handleTemplateConfirm"-->
- <!-- @cancel="handleRefresh"-->
- <!-- @refresh="()=>{refreshPdf = !refreshPdf}"-->
- <!-- />-->
- <!-- 报告编制 - 模板 -->
- <CustomDialog v-model="showInlineReportEdit" :show-footer="false" fullscreen :show-close="false">
- <SpreadViewer :initData="editData" ref="editSpreadReportRef" @saveSuccess="saveSuccessReport" @close="handleClose">
- <template #title>
- <div style="font-size: 20px; ">报告编制</div>
- </template>
- </SpreadViewer>
- </CustomDialog>
- <!-- 修改主检人弹窗 -->
- <UserSelectForm ref="userSelectFormRef" @confirm="handleUserSelect" :single="true" />
- <CustomDialog v-model="showReportDialog" :show-footer="false" width="1000px">
- <!-- <VuePdfEmbed
- v-loading="pdfLoading"
- :height="500"
- :width="968"
- :source="reportSource"
- @rendered="handlePdfRendered"
- />-->
- <SpreadViewer :initData="reportInitData" ref="reportSpreadRef" />
- </CustomDialog>
- <!-- 查看版本详情的弹窗 -->
- <CustomDialog v-model="showVersionDetail" title="查看详情" :show-footer="false" width="1000px">
- <SmartTable
- v-model:columns="versionColumns"
- :buttons="versionDetailButtons"
- :data="versionDataCompareList"
- :is-pagination="false"
- :show-refresh="false"
- />
- </CustomDialog>
- <!-- 图片预览对话框 -->
- <el-dialog
- v-model="previewVisible"
- class="preview-dialog"
- title="Warning"
- width="500"
- :show-footer="false"
- :show-close="false"
- align-center
- >
- <div class="preview-container">
- <video class="preview-video" v-if="previewType === 'video'" :src="previewUrl" auto-play controls></video>
- <img class="preview-image" v-else :src="previewUrl" />
- </div>
- </el-dialog>
- <dialog ref="previewDialogRef"></dialog >
- <ReportListUploadModal
- ref="reportListUploadModalRef"
- :selectedItem="selectedItem"
- :reportList="reportList"
- @confirm="handleRefresh"
- />
- <!-- 回退原因弹窗(面板收缩时使用) -->
- <el-dialog
- v-model="rejectionReasonDialogVisible"
- title="请输入回退原因"
- width="450px"
- :close-on-click-modal="false"
- >
- <el-form ref="rejectionReasonDialogFormRef" :model="tempRejectionReason" :rules="returnFormRules">
- <el-form-item label="回退原因" prop="rejectionReason">
- <el-input
- v-model="tempRejectionReason.rejectionReason"
- type="textarea"
- :rows="5"
- maxlength="100"
- placeholder="请输入回退原因"
- />
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="rejectionReasonDialogVisible = false">取消</el-button>
- <el-button type="primary" @click="handleRejectionReasonDialogConfirm">确定回退</el-button>
- </template>
- </el-dialog>
- </div>
- <!-- 新加 -->
- <Teleport v-if="teleportBtnRef" to=".teleport-btn">
- <template v-if="showCheckBook && getReportStatusEnd">
- <div v-if="[0, 2].includes(checkBookDetail.rectificationStatus)" class="default-toolbar">
- <el-button type="success" size="small" @click="() => handlePass(0)">整改通过</el-button>
- <el-button type="success" size="small" @click="() => handlePass(2)">整改不通过</el-button>
- <el-button type="primary" size="small" @click="handleRectificationMaterials">上传整改材料</el-button>
- <template v-if="checkBookDetail.rectificationStatus === 2">
- <el-button type="primary" size="small" @click="() => handlePass(1)">回退</el-button>
- </template>
- </div>
- <div v-if="[3].includes(checkBookDetail.rectificationStatus)" class="default-toolbar">
- <el-button type="primary" size="small" @click="handleRectificationMaterials">上传整改材料</el-button>
- </div>
- </template>
- <template v-else>
- <div class="operation-btns">
- <!-- 报告办结后,这部分按钮不再显示 -->
- <template v-if="!getReportStatusEnd && selectedItem">
- <!-- 根据报告类型和配置显示相应按钮 -->
- <template
- v-if="selectedItem.reportType === PressureReportType.SINGLE"
- >
- <!-- 独审报告根据配置显示按钮 -->
- <el-button
- v-if="isCanSubmitToAudit"
- type="danger"
- @click="handleSubmitAudit"
- :disabled="checkerIsLoginUser"
- size="small"
- >
- 提交报告审核
- </el-button>
- <!-- 没有审核只有审批 -->
- <!-- <el-button
- v-if="
- currentReportConfig?.isRatify &&
- !currentReportConfig?.isApproval &&
- isCanSubmitToAudit
- "
- type="danger"
- @click="handleApprovalSelectConfirm"
- :disabled="checkerIsLoginUser"
- size="small"
- >
- 提交报告审批
- </el-button> -->
- </template>
- <!-- 非独审报告默认显示审核按钮 -->
- <el-button
- v-if="
- selectedItem.reportType !== PressureReportType.SUB &&
- selectedItem.reportType !== PressureReportType.SINGLE &&
- isCanSubmitToAudit &&
- 'BoilerCheckerTaskDetail' === routeName
- "
- type="danger"
- @click="handleSubmitAudit"
- :disabled="checkerIsLoginUser"
- size="small"
- >
- {{ selectedItem.reportType === PressureReportType['SUGGUESTION'] ? '提交审核' : '提交报告审核' }}
- </el-button>
- <el-button
- v-if="selectedItem.reportType === PressureReportType.SUB && selectedItem.taskStatus == PressureCheckerMyTaskStatus.REPORT_INPUT "
- type="danger"
- @click="handleCompletion"
- :disabled="checkerIsLoginUser"
- size="small"
- >
- 报告办结
- </el-button>
- <el-button type="primary" size="small" plain v-if="isCanEditReport" @click="handleEditRreport" :disabled="checkerIsLoginUser"
- >编制报告</el-button>
- <el-button v-if="isCanSubmitRecheck" type="primary" @click="handleSelectVerfiyer" :disabled="checkerIsLoginUser" size="small"
- >提交校核</el-button>
- <el-button
- type="primary"
- v-if="isCanEditTestRecord"
- plain
- @click="handleEditSpreadRecord"
- :disabled="checkerIsLoginUser"
- size="small"
- >{{ selectedItem.reportType === PressureReportType['SUGGUESTION'] ? '编制意见书' : '填写记录' }}</el-button>
- <!-- 撤销流程:报告审核或审批阶段,有OA流程ID且当前用户是发起人时显示 -->
- <el-button
- v-if="isCanCancelFlow"
- type="warning"
- @click="handleCancelFlow"
- size="small"
- >撤销流程</el-button>
- <!-- OA审核:报告审核或审批阶段,有OA流程ID时显示 -->
- <el-button
- v-if="isCanOAAudit"
- type="success"
- @click="handleOpenOAAudit"
- size="small"
- >OA审核</el-button>
- <!-- 小程序推送:记录录入状态下,根据项目配置判断是否需要签名 -->
- <el-button
- v-if="isCanMiniProgramPush"
- type="warning"
- @click="handleMiniProgramPush"
- size="small"
- >小程序推送</el-button>
- </template>
- </div>
- </template>
- </Teleport>
- <AssociationOperationManual
- v-if="showAssociationOperationManual"
- :selectedItem="selectedItem"
- :reportList="reportList"
- :equipCode="props.taskOrderItem?.equipCode"
- @close="()=>{
- showAssociationOperationManual = false
- handleRefresh()
- }"
- />
- <!-- 上传整改材料弹窗 -->
- <RectificationMaterialsDialog
- :visible="ectificationMaterialsVisible"
- :report-name="selectedItem?.reportName"
- :detail="checkBookDetail"
- :submit-api="BoilerTaskOrderApi.inspectionOpinionRectifyApi"
- :editable="true"
- @close="ectificationMaterialsVisible = false"
- @success="handleRefresh"
- />
- <CustomDialog
- ref="customUnitDialogRef"
- title="选择审核人"
- v-model="approvalUserVisible"
- width="650px"
- :dialogAttrs="{ zIndex: 10006 }"
- >
- <el-form ref="formRef" :model="formData" :rules="formRules" label-width="150px">
- <el-form-item label="意见通知书审核人" prop="inspectionAuditId">
- <el-select v-model="formData.inspectionAuditId" clearable placeholder="请选择">
- <el-option
- v-for="item in optionList.schemeReviewerList.list"
- :key="item.id"
- :label="item.nickname"
- :value="item.id"
- />
- </el-select>
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="approvalUserVisible = false">取消</el-button>
- <el-button type="primary" @click="handleSubmitUser">确定</el-button>
- </template>
- </CustomDialog>
- <!-- 小程序推送签名信息弹窗 -->
- <el-dialog
- v-model="miniProgramPushDialogVisible"
- title="签名信息"
- width="500px"
- :close-on-click-modal="false"
- >
- <el-form
- ref="miniProgramPushFormRef"
- :model="miniProgramPushForm"
- :rules="miniProgramPushFormRules"
- label-width="100px"
- >
- <el-form-item label="联系人姓名" prop="recipient">
- <el-input
- v-model="miniProgramPushForm.recipient"
- placeholder="请输入联系人姓名"
- clearable
- />
- </el-form-item>
- <el-form-item label="联系人电话" prop="recipientPhone">
- <el-input
- v-model="miniProgramPushForm.recipientPhone"
- placeholder="请输入联系人电话"
- clearable
- />
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="miniProgramPushDialogVisible = false">取消</el-button>
- <el-button type="primary" :loading="miniProgramPushLoading" @click="handleMiniProgramPushConfirm">确定推送</el-button>
- </template>
- </el-dialog>
- </template>
- <script setup lang="tsx">
- import SmartTable from '@/components/SmartTable/SmartTable'
- import RectificationUpload from '@/views/pressure2/components/RectificationUpload.vue'
- import RectificationMaterialsDialog from '@/views/pressure2/components/RectificationMaterialsDialog.vue'
- import { computed, nextTick, reactive, ref, watch } from 'vue'
- import { useRouter, useRoute } from 'vue-router'
- import { InfoFilled, View, Back, Right, WarningFilled, VideoPlay } from '@element-plus/icons-vue'
- import {dayjs, ElLoading, ElMessage, ElMessageBox, FormInstance, FormRules} from 'element-plus'
- const CustomDialog = defineAsyncComponent(() => import('@/components/CustomDialog/index.vue'))
- import VuePdfEmbed from 'vue-pdf-embed'
- import { getReportAllowedApplyModify, getReportCheckPdf } from '@/api/laboratory/functional/report'
- import * as UserApi from '@/api/system/user'
- import {
- PressureCheckerMyTaskStatusMap,
- PressureCheckerMyTaskStatus,
- PressureReportType,
- PressureTaskOrderTaskStatus,
- SugguestionApproveConfig,
- } from '@/utils/constants'
- import { OAApprovalResultMap, OAApprovalResultType } from '@/utils/pressure2/oaConstants'
- import type {
- ReportItemVO,
- BoilerTaskOrderDetailVO,
- BoilerTaskOrderOrderItemVO
- } from '@/api/pressure2/boilertaskorder'
- import InspectionItemProgress from './InspectionItemProgress.vue'
- import InlineEditCheckRecord from './InlineEditCheckRecord.vue'
- import InlinePdfViewer from './InlinePdfViewer.vue'
- import InlineInspectionResultInput from './InlineInspectionResultInput.vue'
- import InlineReportEdit from './InlineReportEdit.vue'
- import { BoilerTaskOrderApi } from '@/api/pressure2/boilertaskorder'
- import { defineAsyncComponent } from 'vue'
- import UserSelectForm from '@/components/UserSelectForm/index.vue'
- import { reportInfoApi } from '@/api/reportInfoService'
- import { buildFileUrl } from '@/utils'
- import { useUserStore } from '@/store/modules/user'
- const AuditUserDialog = defineAsyncComponent(
- () => import('@/views/Functional/components/AuditUserDialog.vue')
- )
- import { is } from '@/utils/is'
- import _ from 'lodash'
- import { uploadFile } from '@/api/common/index'
- import ReportListUploadModal from './reportListUploadModal.vue'
- import AssociationOperationManual from './AssociationOperationManual.vue'
- import {DynamicTbInsApi} from "@/api/pressure2/dynamictbins";
- import { OrderReportApi } from "@/api/pressure2/orderreport";
- import {SpreadViewer} from "@/components/DynamicReport";
- import {InitParams} from "@/components/DynamicReport/SpreadInterface";
- import { cloneDeep, debounce } from 'lodash-es'
- import {PipeTaskOrderApi} from "@/api/pressure2/pipetaskorder";
- import {BoilerConnectRecordReportApi} from "@/api/pressure2/boilerconnectrecordreport";
- import * as UserGroupApi from '@/api/bpm/userGroup'
- interface Props {
- selectedItem: ReportItemVO | null
- taskInfo: BoilerTaskOrderDetailVO | null
- taskOrderItem: BoilerTaskOrderOrderItemVO
- isAuditMode?: boolean
- reportId?: string | null
- reportList?: ReportItemVO[]
- taskId: string
- teleportBtnRef: Ref<HTMLDivElement | null>
- isFullscreen?: boolean
- }
- interface Emits {
- (e: 'refresh'): void
- (e: 'template-confirm', templateUrl?: string): void
- (e: 'modify-checker', item: ReportItemVO): void
- (e: 'submit-approval'): void
- (e: 'reject'): void
- (e: 'cancel'): void
- (e: 'submit-ratify'): void
- (e: 'update:selected-item', item: ReportItemVO): void
- }
- const props = defineProps<Props>()
- const emit = defineEmits<Emits>()
- const route = useRoute()
- const userStore = useUserStore()
- const schemaFlag = ref<string | null>(null) //等于proofread = 校核 audit=审核
- // 获取当前的路由Name
- const routeName = computed(() => route.name)
- const form = ref<Record<string, any>>({
- recheckUser: {}
- })
- const refreshPdf = ref(true)
- // 视图模式状态管理
- const viewMode = ref<'normal' | 'inspection-result'>('normal')
- // 批量提交的表单
- const batchRecheckForm = ref({
- reportIds: [],
- recheckUser: {}
- })
- const batchRecheckFormRules = {
- reportIds: [{required: true, message: '请选择提交记录', trigger: 'change'}],
- recheckUser: [{required: true, message: '请选择校核人', trigger: 'change'}]
- }
- const batchRecheckFormRef = ref()
- // const isShowReportPdf = ref([PressureCheckerMyTaskStatus.REPORT_INPUT,PressureCheckerMyTaskStatus.REPORT_AUDIT,PressureCheckerMyTaskStatus.REPORT_APPROVE,PressureCheckerMyTaskStatus.REPORT_END].includes(props.selectedItem.taskStatus)
- // && ![400,500,600,700].includes(props.selectedItem.reportType))
- const showReportPdfType = ref('record')
- const refreshPdfFlag = ref(true)
- // const pdfPanelRef = ref<HTMLElement | null>(null)
- const hasRecord = ref(true)
- const hasReport = ref(true)
- // 格式化记录结果状态显示
- const formatRecordResult = (record) => {
- const resultMap = {
- 100: '通过',
- 200: '拒绝',
- 300: '已阅',
- 400: '同意',
- 500: '不同意'
- }
- return resultMap[record.result] || record.result || '-'
- }
- // 获取记录结果的按钮类型
- const getRecordResultButtonType = (record) => {
- if ([100, 300, 400].includes(record.result)) {
- return 'success'
- } else if ([200, 500].includes(record.result)) {
- return 'danger'
- } else {
- return 'default'
- }
- }
- const reportSpreadRef=ref();
- const spreadRef=ref();
- const initData=ref<InitParams>(
- {
- templateId: '',
- refId: '',
- refName:'',
- insId:'',
- opType: 0, // 0:excel,1: pdf
- manualUrl: '',
- });
- const editSpreadRecordRef=ref();
- const editSpreadReportRef=ref();
- const editData=ref<InitParams>(
- {
- templateId: '',
- refId: '',
- refName:'',
- insId:'',
- opType: 0, // 0:excel,1: pdf
- manualUrl: '',
- });
- const reportInitData=ref<InitParams>(
- {
- templateId: '',
- refId: '',
- refName:'',
- insId:'',
- opType: 1, // 0:excel,1: pdf
- });
- // 选择检验意见审核人
- const formRef = ref<InstanceType<typeof ElForm>>()
- const optionList = reactive<{
- schemeReviewerList: Recordable[]
- }>({
- schemeReviewerList: []
- })
- const formData = ref<Recordable>({})
- const formRules = reactive({
- inspectionAuditId: [{ required: true, message: '请选择审核人', trigger: 'change' }]
- })
- const approvalUserVisible = ref(false)
- const handleSubmitUser = () => {
- formRef.value?.validate(async (valid) => {
- if (valid) {
- const submitResult = await BoilerTaskOrderApi.submitOpinionNoticeApproval({
- id: templateParams.value?.id,
- auditUserIds: [formData.value.inspectionAuditId],
- reportType: PressureReportType['SUGGUESTION']
- })
- if (submitResult) {
- approvalUserVisible.value = false
- // 这里可以做页面刷新
- emit('template-confirm')
- }
- }
- })
- }
- // 获取可以批量提交的报告
- const getCanSubmitRecheckReport = computed(() => {
- if(!props.reportList || !props.reportList.length) return []
- return props.reportList.filter((report: any) => {
- // 主报告、子报告、独审报告才有记录校核
- const reportTypes = [PressureReportType['SUB'], PressureReportType['SINGLE']]
- const status = PressureTaskOrderTaskStatus['RECORD_INPUT'] // 记录录入状态
- // report.reportUrl 已经录入数据
- // if(report.taskStatus !== status || !report.reportUrl) return false
- if(report.taskStatus !== status) return false
- else if(report.reportType === PressureReportType['MAIN'] && userStore.user.id === props.taskOrderItem?.mainCheckerUser?.id) return true
- else
- return reportTypes.includes(report.reportType) && (report.checkUsers?.[0]?.id === userStore.user.id || !report.checkUsers || !report.checkUsers.length)
- // 过滤掉主报告存在未办结检验意见通知书时
- }).filter((report: any) => {
- if(report.reportType !== PressureReportType['MAIN']){
- return true
- }
- const sugguestionReport = props.reportList?.find(x => x.reportType === PressureReportType['SUGGUESTION'])
- // 不存在检验意见通知书返回true
- if(!sugguestionReport) return true
- // 检验意见通知书已办结,返回true
- return sugguestionReport.taskStatus === PressureCheckerMyTaskStatus['REPORT_END'];
- })
- })
- // 当意见通知书未办结时,主报告不能流转到后续流程(提交校核)
- const canSubmitMainReportType = (tipsText: string)=>{
- // 不是主报告,直接返回true
- if(PressureReportType.MAIN !== props?.selectedItem?.reportType) return true
- // 判断检验意见通知书的状态
- const report = props.reportList?.find(x => x.reportType === PressureReportType['SUGGUESTION'])
- console.log('检验意见通知书', report)
- // 不存在检验意见通知书返回true
- if(!report) return true
- // 检验意见通知书已办结,返回true
- if(report.taskStatus === PressureCheckerMyTaskStatus['REPORT_END']) return true
- ElMessageBox.alert(tipsText, '提示', {
- showCancelButton: false,
- confirmButtonText: '确定',
- type: 'warning'
- })
- return false
- }
- // 校核人选择对话框状态
- const showBatchSubmitToRecheckDialog = ref(false)
- const isShowAuditDialog = ref(false)
- const btnLoading = ref(false)
- // 检验意见通知书提交审核
- const sugguestionApproveConfig = ref<any[]>(cloneDeep(SugguestionApproveConfig))
- const isShowSuggestionAuditDialog = ref(false)
- const suggestionFormRef = ref<FormInstance>()
- const suggestionFormData = ref<any>({})
- const suggestionFormRules = reactive({
- sugguestionAuditId: [
- { required: true, message: '请选择审核人', trigger: 'blur' }
- ],
- sugguestionApproveId: [
- { required: true, message: '请选择审批人', trigger: 'blur' }
- ]
- })
- const handleSelectVerfiyer = async () => {
- try {
- await spreadRef.value?.handleSave()
- } catch (error) {
- console.error('保存数据失败:', error)
- ElMessage.error('保存数据失败,请重试')
- return
- }
- const canSubmit = canSubmitMainReportType('该报告存在未办结检验意见通知书,无法提交校核')
- if(!canSubmit) return
- // 获取审核人\校核人配置信息
- let res = await BoilerTaskOrderApi.getDefaultApproval()
- // 如果存在多份待提交校核的报告,执行批量校核弹窗
- if(getCanSubmitRecheckReport.value.length > 1) {
- if(res && res.recheckUser) {
- // 校验默认校核人是否在校核人列表中
- const checkList = await getRecheckUserList({ pageNo: 1, pageSize: 200, nickName: res.recheckUser.nickname })
- const exists = (checkList?.list || []).some((item: any) => item.id === res.recheckUser.id)
- if (exists) {
- batchRecheckForm.value.recheckUser = res.recheckUser
- }
- }
- batchRecheckForm.value.reportIds = getCanSubmitRecheckReport.value.map(x => x?.id)
- showBatchSubmitToRecheckDialog.value = true
- return
- }
- // 只有一份待提交校核的报告,执行以下逻辑
- if(res && res.recheckUser) {
- // 校验默认校核人是否在校核人列表中
- const checkList = await getRecheckUserList({ pageNo: 1, pageSize: 200, nickName: res.recheckUser.nickname })
- const exists = (checkList?.list || []).some((item: any) => item.id === res.recheckUser.id)
- if (exists) {
- form.value.recheckUser = res.recheckUser
- }
- }
- schemaFlag.value = 'proofread'
- isShowAuditDialog.value = true
- }
- // const handleAuditSelectConfirm = async (res: any) => {
- // console.log('handleAuditSelectConfirm', res)
- // if (!props.selectedItem || !res[0]) {
- // return
- // }
- // const saveResult = await BoilerTaskOrderApi.submitTaskReportTemplate({
- // id: props.selectedItem.id,
- // recheckId: res[0]
- // })
- // if (saveResult) {
- // ElMessage.success('提交校核成功!')
- // // 这里可以做页面刷新
- // emit('template-confirm')
- // }
- // }
- // 批量提交
- const handleBatchSubmitToRecheck = async () => {
- try {
- await batchRecheckFormRef.value.validate()
- } catch (err) {
- ElMessage.error('请完善表单数据!')
- return
- }
- if (_.isEmpty(batchRecheckForm.value.recheckUser)) {
- return ElMessage.error('请选择校核人')
- }
- // 待提交的数据
- const params = {
- reportList: getCanSubmitRecheckReport.value.filter((x: any) => batchRecheckForm.value.reportIds.includes(x?.id)).map((x: any) => ({
- id: x.id,
- reportUrl: x.reportUrl,
- dataJson: x?.prepareJson
- })),
- recheckId: batchRecheckForm.value.recheckUser?.id
- }
- const submitResult = await BoilerTaskOrderApi.batchSubmitToRecheck(params)
- if (submitResult) {
- // 保存默认校核人
- BoilerTaskOrderApi.saveDefaultApproval({
- recheckId: batchRecheckForm.value.recheckUser?.id
- })
- ElMessage.success('提交校核成功!')
- showBatchSubmitToRecheckDialog.value = false
- selectNextItem(getCanSubmitRecheckReport.value.filter((x: any) => batchRecheckForm.value.reportIds.includes(x?.id)))
- // 这里可以做页面刷新
- emit('template-confirm')
- }
- }
- const submitting = ref(false)
- const handleAuditSelectConfirm = async () => {
- if (_.isEmpty(form.value.recheckUser)) {
- return ElMessage.error(schemaFlag.value == 'proofread' ? '请选择校核人' : '请选择审核人')
- }
- // 审核
- if (schemaFlag.value === 'audit') {
- submitting.value = true
- const submitResult = await BoilerTaskOrderApi.submitReportAudit({
- id: templateParams.value?.id,
- approveId: form.value?.recheckUser?.id
- })
- submitting.value = false
- if (submitResult) {
- ElMessage.success('提交审核成功!')
- isShowAuditDialog.value = false
- selectNextItem([props.selectedItem])
- // 这里可以做页面刷新
- emit('template-confirm')
- }
- } else if (schemaFlag.value === 'proofread') {
- // 校核
- const saveResult = await BoilerTaskOrderApi.submitTaskReportTemplate({
- id: props?.selectedItem?.id,
- recheckId: form.value?.recheckUser?.id
- })
- if (saveResult) {
- // 保存默认校核人
- BoilerTaskOrderApi.saveDefaultApproval({
- recheckId: form.value?.recheckUser?.id
- })
- ElMessage.success('提交校核成功!')
- isShowAuditDialog.value = false
- selectNextItem([props.selectedItem])
- // 这里可以做页面刷新
- emit('template-confirm')
- }
- }
- }
- /**
- * 项目切换
- */
- const selectNextItem = (items:ReportItemVO[]) => {
- // 找到其他在记录录入或者报告编制状态的第一项目
- const ids = items.map(item => item.id)
- const inputReportList= props.reportList.filter(
- item => {
- return !ids.includes(item.id)
- }
- ).filter(item =>{
- return item.taskStatus === PressureTaskOrderTaskStatus['RECORD_INPUT'] || item.taskStatus === PressureTaskOrderTaskStatus['REPORT_INPUT']
- })
- console.log(inputReportList)
- if (inputReportList.length > 0){
- emit('item-select', inputReportList[0])
- }
- }
- // 审批人选择对话框状态
- const isShowApprovalDialog = ref(false)
- // 监听项目切换,自动重置视图模式
- watch(
- () => props.selectedItem,
- (newItem, oldItem) => {
- if (newItem) {
- showReportPdfType.value = [PressureCheckerMyTaskStatus.REPORT_INPUT,PressureCheckerMyTaskStatus.REPORT_AUDIT,PressureCheckerMyTaskStatus.REPORT_APPROVE,PressureCheckerMyTaskStatus.REPORT_END].includes(props.selectedItem.taskStatus)
- && ![400,500,600,700].includes(props.selectedItem.reportType) ? 'report':'record'
- handleRefreshData()
- props.taskId && getReportAuditInfo()
- hasRecord.value = props.selectedItem.templateId != null
- if (props.selectedItem?.reportTemplateId == null){
- showReportPdfType.value = 'record'
- }
- if (props.selectedItem?.templateId == null){
- showReportPdfType.value = 'report'
- }
- }
- // 当切换到不同的项目时,重置视图模式为normal
- if (newItem?.id !== oldItem?.id) {
- viewMode.value = 'normal'
- }
- },
- { immediate: false }
- )
- const previewUrl = ref('')
- const previewVisible = ref(false)
- const previewType = ref('')
- const handlePreview = (path: string, type: 'video' | 'image') => {
- previewUrl.value = path;
- previewType.value = type;
- previewVisible.value = true;
- }
- /**
- * 如果是"已经审核完的检验意见通知书,则查询相关的检验意见通知信息,显示在最右侧
- */
- const checkBookDetail = ref<Record<string, any>>({})
- const showCheckBook = computed(() => {
- const { reportType, taskStatus } = props.selectedItem || {}
- // console.log(taskStatus, 'taskStatus', reportType)
- // taskStatus: 800
- return reportType === PressureReportType['SUGGUESTION']
- })
- const rectificationStatusMap = reactive({
- 0: '待确认',
- 1: '待整改',
- 2: '已递交',
- 3: '材料有误',
- 4: '整改通过',
- 5: '整改不通过'
- })
- const getReportAuditInfo = async () => {
- if (props.selectedItem?.reportType === PressureReportType['SUGGUESTION']) {
- const res = await BoilerTaskOrderApi.exportCheckBookDetail({
- id: props.selectedItem?.id
- })
- console.log(res, '查询检验意见通知书详细信息')
- if (res) {
- checkBookDetail.value = res
- }
- }
- }
- const returnForm = ref({
- rejectionReason: ''
- })
- const returnFormRules = ref({
- rejectionReason: [{ required: true, message: '请输入回退原因', trigger: 'blur' }]
- })
- const returnFormRef = ref()
- const rejectionReasonDialogVisible = ref(false)
- const tempRejectionReason = ref({ rejectionReason: '' })
- const rejectionReasonDialogFormRef = ref()
- const isCompleteInput = computed(() => {
- return props.selectedItem?.taskStatus >= PressureCheckerMyTaskStatus.RECORD_CHECK
- })
- const isShowRecordOrReportBtn = computed(() => {
- return [PressureReportType.MAIN,PressureReportType.SUB,PressureReportType.SINGLE].includes(props.selectedItem?.reportType)
- })
- // 通过 退回
- const handlePass = async (type) => {
- const params: Record<string, any> = {
- reportId: props.selectedItem?.id,
- approvalType: type
- }
- if (type === 1) {
- if (isExpanded.value) {
- try {
- await returnFormRef.value.validate()
- } catch {
- ElMessage.warning('请填写回退原因')
- return
- }
- params.rejectionReason = returnForm.value.rejectionReason
- executePass(params, type)
- } else {
- tempRejectionReason.value.rejectionReason = returnForm.value.rejectionReason
- rejectionReasonDialogVisible.value = true
- }
- return
- }
- executePass(params, type)
- }
- // 弹出框确认回退
- const handleRejectionReasonDialogConfirm = async () => {
- try {
- await rejectionReasonDialogFormRef.value.validate()
- } catch {
- return
- }
- rejectionReasonDialogVisible.value = false
- // 同步到主表单以便保持数据一致
- returnForm.value.rejectionReason = tempRejectionReason.value.rejectionReason
- const params: Record<string, any> = {
- reportId: props.selectedItem?.id,
- approvalType: 1,
- rejectionReason: tempRejectionReason.value.rejectionReason
- }
- executePass(params, 1)
- }
- // 执行通过/退回操作
- const executePass = (params: Record<string, any>, type: number) => {
- const tipText = type === 1 ? '退回' : type === 2 ? '整改不通过' : '整改通过'
- ElMessageBox.confirm(`确定${tipText}吗?`, '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(() => {
- BoilerTaskOrderApi.inspectionApproval(params).then((res) => {
- props.taskId && getReportAuditInfo()
- emit('refresh')
- }).catch(() => {
- ElMessage.error('操作失败')
- })
- })
- }
- // 上传整改材料
- const ectificationMaterialsVisible = ref(false)
- const handleRectificationMaterials = () => {
- ectificationMaterialsVisible.value = true
- }
- // 获取检验员名称
- const getCheckersName = (): string => {
- if (!props.selectedItem?.checkUsers || props.selectedItem.checkUsers.length === 0) {
- return '未分配'
- }
- return props.selectedItem.checkUsers.map((user) => user.nickname).join('、')
- }
- // 切换主检人
- const handleUserSelect = async (id, userList) => {
- const result = await BoilerTaskOrderApi.updateReportMainChecker({
- id: props.taskOrderItem?.id,
- mainChecker: userList[0]?.id
- })
- if (result) {
- ElMessage.success('修改主检人成功!')
- emit('refresh')
- }
- }
- const userSelectFormRef = ref()
- const handleModifyMainChecker = () => {
- userSelectFormRef.value.open(props.taskOrderItem?.mainCheckerUser?.id)
- }
- // 判断当前检验员或主检人是否为登录用户,如果不是,则功能按钮disabled
- const checkerIsLoginUser = computed(() => {
- const checkerUserIds = props.selectedItem?.checkUsers.map(checker => checker?.id)
- return !(checkerUserIds?.includes(userStore?.user?.id) || props.taskOrderItem?.mainCheckerUser?.id === userStore?.user?.id)
- })
- // 判断当前项目是否已经到报告办结阶段
- const getReportStatusEnd = computed(
- () =>{
- return props.selectedItem && props.selectedItem.taskStatus >= PressureCheckerMyTaskStatus['REPORT_CONFIRMATION']
- }
- )
- // 判断“提交校核”按钮是否显示
- const isCanSubmitRecheck = computed(() => {
- if (props.selectedItem?.reportType === PressureReportType['SUGGUESTION'])
- return props.selectedItem?.isRecheck || false
- else if (props.selectedItem?.reportType === PressureReportType['MAINQUESTION']) return false
- else
- return (
- props.selectedItem &&
- props.selectedItem.taskStatus === PressureCheckerMyTaskStatus['RECORD_INPUT']
- // && props.selectedItem.reportUrl
- )
- })
- // 判断“提交审核&提交审批”按钮是否显示
- const isCanSubmitToAudit = computed(() => {
- const { selectedItem } = props
- if (selectedItem && selectedItem?.reportType === PressureReportType['SUBCONTRACT']){
- return selectedItem.taskStatus === PressureCheckerMyTaskStatus['CONFIRMED']
- }
- if (props.selectedItem && props.selectedItem?.reportType === PressureReportType['SUGGUESTION'])
- return (
- props.selectedItem?.isApproval &&
- props.selectedItem.taskStatus === PressureCheckerMyTaskStatus['RECORD_INPUT']
- )
- else if (
- props.selectedItem &&
- props.selectedItem?.reportType === PressureReportType['MAINQUESTION']
- )
- return (
- props.selectedItem.taskStatus === PressureCheckerMyTaskStatus['RECORD_INPUT'] &&
- props.selectedItem?.reportUrl
- )
- else
- return (
- props.selectedItem &&
- props.selectedItem.taskStatus === PressureCheckerMyTaskStatus['REPORT_INPUT']
- )
- })
- // 判断“填写记录”按钮是否显示
- const isCanEditTestRecord = computed(
- () =>
- props.selectedItem &&
- (props.selectedItem.taskStatus === PressureCheckerMyTaskStatus['RECORD_INPUT'] ||
- props.selectedItem.taskStatus === PressureCheckerMyTaskStatus['CONFIRMED']) && props.selectedItem.reportType !== PressureReportType['SUBCONTRACT']
- )
- // 判断“编制报告”按钮是否显示
- const isCanEditReport = computed(
- () =>
- props.selectedItem &&
- props.selectedItem.taskStatus === PressureCheckerMyTaskStatus['REPORT_INPUT']
- )
- // 判断"撤销流程"按钮是否显示:报告审核或审批阶段,且有OA流程ID,且当前用户是发起人
- const isCanCancelFlow = computed(() => {
- if (!props.selectedItem) return false
- const isAuditOrApprove = [
- PressureCheckerMyTaskStatus['REPORT_AUDIT'],
- PressureCheckerMyTaskStatus['REPORT_APPROVE']
- ].includes(props.selectedItem.taskStatus)
- if (!isAuditOrApprove) return false
- if (!props.selectedItem.summaryId) return false
- return !checkerIsLoginUser.value
- })
- // 撤销流程
- const handleCancelFlow = async () => {
- if (!props.selectedItem?.summaryId) {
- ElMessage.warning('未找到OA流程ID,无法撤销')
- return
- }
- ElMessageBox.confirm('确定要撤销该流程吗?撤销后报告将回到报告编制阶段,您可以重新发起。', '撤销流程', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(async () => {
- try {
- const result = await BoilerTaskOrderApi.cancelOAFlow(props.selectedItem.summaryId)
- if (result) {
- ElMessage.success('流程已撤销')
- emit('refresh')
- }else {
- ElMessage.error('流程已撤销')
- emit('refresh')
- }
- } catch (error) {
- console.error('撤销流程失败:', error)
- ElMessage.error('撤销流程失败,请稍后重试')
- }
- }).catch(() => {})
- }
- const oaSummaryList = ref([])
- // 判断"OA审核"按钮是否显示:报告审核或审批阶段,且有OA流程ID,且当前用户是对应阶段的审核人/审批人
- const isCanOAAudit = computed(() => {
- if (!props.selectedItem) return false
- // const { taskStatus, summaryId, approvalId, ratifyId } = props.selectedItem
- const {summaryId,taskStatus} = props.selectedItem
- // const currentUserId = userStore?.user?.id
- // 审核阶段:只有审核人才能点击
- // 审批阶段:只有审批人才能点击
- if (taskStatus === PressureCheckerMyTaskStatus['REPORT_AUDIT'] || taskStatus === PressureCheckerMyTaskStatus['REPORT_APPROVE']) {
- // 检查是否在OA待办事项中
- const isOaSummary = oaSummaryList.value.some(item => item == summaryId)
- if (!isOaSummary) return false
- return true
- }
- return false
- })
- // OA审核:弹出独立窗口
- const oaAuditTimer = ref<ReturnType<typeof setInterval> | null>(null)
- onMounted(() => {
- setTimeout(() => {
- if (route.query?.type == 'reportRatify' || route.query?.type == 'reportAudit') {
- if (isCanOAAudit.value) {
- handleOpenOAAudit()
- }
- }
- }, 500)
- })
- const handleOpenOAAudit = async () => {
- // 清除之前的定时器
- if (oaAuditTimer.value) {
- clearInterval(oaAuditTimer.value)
- oaAuditTimer.value = null
- }
- // 先打开空白弹窗
- // 先打开全屏空白弹窗
- const win = window.open('', 'OAAudit', 'width=' + screen.width + ',height=' + screen.height + ',left=0,top=0,menubar=no,toolbar=no,location=no,status=no,scrollbars=yes,resizable=yes')
- try {
- const link = await BoilerTaskOrderApi.getAffairLink(props.selectedItem.summaryId)
- if (link && win) {
- win.location.href = link
- // 轮询监听窗口关闭,关闭后触发报告状态更新
- oaAuditTimer.value = setInterval(() => {
- if (win.closed) {
- clearInterval(oaAuditTimer.value!)
- oaAuditTimer.value = null
- BoilerTaskOrderApi.updateReportBySummaryId(props.selectedItem.summaryId).finally(() => emit('refresh'))
- BoilerTaskOrderApi.getAffairSummaryList().then((res) => {
- oaSummaryList.value = res || []
- })
- }
- }, 100)
- } else if (!win) {
- ElMessage.warning('浏览器拦截了弹窗,请允许弹窗后重试')
- } else {
- win.close()
- ElMessage.warning('未找到对应的OA审批链接')
- }
- } catch (error) {
- console.error('获取OA审批链接失败:', error)
- win?.close()
- ElMessage.error('获取OA审批链接失败,请稍后重试')
- }
- }
- // 小程序推送相关逻辑
- const projectConfig = ref<any>({})
- const miniProgramPushDialogVisible = ref(false)
- const miniProgramPushForm = ref({
- recipient: '',
- recipientPhone: ''
- })
- const miniProgramPushFormRules = {
- recipient: [{ required: true, message: '请输入联系人姓名', trigger: 'blur' }],
- recipientPhone: [{ required: true, message: '请输入联系人电话', trigger: 'blur' }]
- }
- const miniProgramPushFormRef = ref()
- const miniProgramPushLoading = ref(false)
- // 判断是否可以小程序推送:记录录入状态下且项目配置需要签名
- const isCanMiniProgramPush = computed(() => {
- if (!props.selectedItem) return false
- // 只有记录录入状态下才能推送
- if (props.selectedItem.taskStatus !== PressureCheckerMyTaskStatus['RECORD_INPUT']) return false
- // 需要有模板ID才能获取项目配置
- if (!props.selectedItem.templateId) return false
- // 项目配置需要签名才显示
- return projectConfig.value.isSign === '1'
- })
- // 获取项目配置
- const fetchProjectConfig = async () => {
- if (!props.selectedItem?.templateId) return
- try {
- const type = showReportPdfType.value === 'report' ? 'report' : 'record'
- const res = await BoilerConnectRecordReportApi.getByTemplateId({
- templateId: props.selectedItem.templateId,
- type: type
- })
- if (res && res.length > 0) {
- projectConfig.value = res[0]
- } else {
- projectConfig.value = {}
- }
- } catch (error) {
- console.error('获取项目配置失败:', error)
- }
- }
- // 处理小程序推送
- const handleMiniProgramPush = async () => {
- await fetchProjectConfig()
- // 判断是否需要签名
- if (projectConfig.value.isSign === '1') {
- // 需要签名,打开签名信息弹窗
- miniProgramPushForm.value = {
- recipient: props.taskOrderItem?.unitContact || '',
- recipientPhone: props.taskOrderItem?.unitPhone || ''
- }
- miniProgramPushDialogVisible.value = true
- } else {
- // 不需要签名,直接推送
- // ElMessageBox.confirm('确定要进行小程序推送吗?', '提示', {
- // confirmButtonText: '确定',
- // cancelButtonText: '取消',
- // type: 'warning'
- // }).then(() => {
- // executeMiniProgramPush()
- // }).catch(() => {})
- }
- }
- // 执行小程序推送 - 更新报告的接收人信息
- const executeMiniProgramPush = async (signInfo?: any) => {
- miniProgramPushLoading.value = true
- try {
- const params: Record<string, any> = {
- id: props.selectedItem?.id
- }
- if (signInfo) {
- params.recipient = signInfo.recipient
- params.recipientPhone = signInfo.recipientPhone
- }
- await BoilerTaskOrderApi.miniProgramPush(params)
- ElMessage.success('推送信息保存成功')
- miniProgramPushDialogVisible.value = false
- emit('refresh')
- } catch (error) {
- console.error('推送信息保存失败:', error)
- ElMessage.error('推送信息保存失败,请稍后重试')
- } finally {
- miniProgramPushLoading.value = false
- }
- }
- // 签名信息弹窗确认
- const handleMiniProgramPushConfirm = async () => {
- try {
- await miniProgramPushFormRef.value?.validate()
- executeMiniProgramPush(miniProgramPushForm.value)
- } catch (error) {
- // 表单验证失败
- }
- }
- // 判断"填写结果"按钮是否显示
- const isCanEditRecordResult = computed(() => {
- // 非我的任务详情页面,不显示
- if ('BoilerCheckerTaskDetail' !== routeName.value) return false
- if (!props.selectedItem?.isAutoAmount || props.selectedItem?.isAutoAmount === '0') return false
- if (
- (props.selectedItem?.reportType === 100 || props.selectedItem?.reportType === 300) &&
- props.selectedItem.taskStatus !== PressureCheckerMyTaskStatus['REPORT_END']
- ) {
- // 独审报告&主报告--“填写结果”:报告办结之前都可以填写
- return true
- }
- // 查找主报告
- const mainReport = props.reportList?.find((item) => item.reportType === 100) || {
- taskStatus: null
- }
- if (
- props.selectedItem?.reportType !== 100 &&
- props.selectedItem?.reportType !== 300 &&
- mainReport?.taskStatus !== PressureCheckerMyTaskStatus['REPORT_END']
- ) {
- // 非主报告 & 非独审报告 -- “填写结果”:主报告办结之前都可以填写
- return true
- }
- return false
- })
- // 1、重大问题线索告知表 2、作业指导书 3、检验方案 只显示pdf
- const onlyShowPdf = computed(() => {
- const reportTypes = [
- PressureReportType.MAINQUESTION,
- PressureReportType.INSPECTIONPLAN,
- PressureReportType.WORKINSTRUCTION
- ]
- return !props.selectedItem?.reportType
- ? false
- : reportTypes.includes(props.selectedItem?.reportType)
- })
- // 模板参数
- const templateParams = computed(() => {
- if (!props.selectedItem) return {}
- return {
- ...props.selectedItem,
- equipCode: props.taskOrderItem?.equipCode || '',
- equipId: props.taskOrderItem?.id || ''
- }
- })
- // 判断是否为独审报告且不需要审批
- const isApprovalWithoutRatify = computed(() => {
- if (!props.selectedItem) return false
- const reportType = (props.selectedItem as any).reportType
- const isApproval = (props.selectedItem as any).isApproval
- const isRatify = (props.selectedItem as any).isRatify
- return (
- reportType === PressureReportType.SINGLE &&
- isApproval === true &&
- isRatify === false &&
- props.reportId === props.selectedItem.id
- )
- })
- /**** 葡萄城:记录录入的显示和隐藏 ****/
- const showInlineEditCheckRecord = ref(false)
- const templateId = ref('')
- const handleEditSpreadRecord = () => {
- // console.log('templateParams', templateParams.value)
- // DynamicTbInsApi.getOrCreatePreviewData('dc8fbb6078b2a2f0eadc0f6aedbeafa0').then(res => {
- // showInlineEditCheckRecord.value = true
- // templateId.value = res.id
- // })
- editPreview('record')
- showInlineEditCheckRecord.value = true
- }
- const handleTemplateConfirm = (templateUrl: string) => {
- console.log('templateUrl', templateUrl)
- emit('template-confirm', templateUrl)
- }
- const handleRefresh = () => {
- emit('refresh')
- }
- /**** 葡萄城:记录录入的显示和隐藏 end****/
- /**** 葡萄城:检验结果录入的显示和隐藏 ****/
- const showInlineInspectionResultInput = ref(false)
- const inspectionResultTemplateParams = ref({})
- // 检验结果录入模板参数
- const handleInputCheckConclusion = () => {
- showInlineInspectionResultInput.value = true
- if (!props.selectedItem) return {}
- inspectionResultTemplateParams.value = {
- ...props.selectedItem,
- equipCode: props.taskOrderItem?.equipCode || ''
- }
- }
- const handleInspectionResultConfirm = (resultUrl: string) => {
- emit('template-confirm', resultUrl)
- viewMode.value = 'normal'
- }
- const handleReturnToNormalMode = () => {
- viewMode.value = 'normal'
- }
- /**** 葡萄城:检验结果录入的显示和隐藏 end ****/
- /**** 葡萄城:报告编制的显示和隐藏 ****/
- const showInlineReportEdit = ref(false)
- const handleEditRreport = () => {
- if (showReportPdfType.value !== 'report' && showReportPdfType.value !== 'result'){
- ElMessage.warning('请切换报告后再进行报告编制!')
- return
- }
- editPreview('report')
- showInlineReportEdit.value = true
- }
- // 获取当前报告的配置信息
- const currentReportConfig = computed(() => {
- if (
- !props.selectedItem ||
- props.selectedItem.reportType !== PressureReportType.SINGLE ||
- !props.reportList
- ) {
- return null
- }
- // 从reportList中找到当前报告的配置
- const currentReport = props.reportList.find((report) => report.id === templateParams.value?.id)
- return currentReport
- ? {
- isApproval: (currentReport as any).isApproval,
- isRatify: (currentReport as any).isRatify
- }
- : null
- })
- // 选择报告审核人弹窗的显示和隐藏
- const isShowReportAuditDialog = ref(false)
- // 弹窗打开时预加载审核人列表和默认值
- watch(isShowReportAuditDialog, async (val) => {
- if (val) {
- reportAuditUserCode.value = ''
- reportAuditUserLoading.value = true
- // 加载审核人列表
- const userList = await getReviewUserList({ pageNo: 1, pageSize: 200, name: '' }).finally(() => {
- reportAuditUserLoading.value = false
- })
- reportAuditUserOptions.value = userList || []
- // 加载默认审核人(工号),校验是否在列表中
- try {
- const defaultApproval = await BoilerTaskOrderApi.getDefaultApproval()
- if (defaultApproval?.approveEmployeeNo) {
- const exists = (userList || []).some((item: any) => item.code === defaultApproval.approveEmployeeNo)
- if (exists) {
- reportAuditUserCode.value = defaultApproval.approveEmployeeNo
- }
- }
- } catch (e) {
- // ignore
- }
- }
- })
- // 提交报告审核
- const handleSubmitAudit = async () => {
- try {
- await spreadRef.value?.handleSave()
- } catch (error) {
- console.error('保存数据失败:', error)
- ElMessage.error('保存数据失败,请重试')
- return
- }
- // 主报告需检查签名状态(金额变动后签名会被置空)
- if (props?.selectedItem?.reportType === PressureReportType.MAIN) {
- try {
- const hasValidSign = await OrderReportApi.hasValidSignByOrderId(props.taskInfo?.id || props.taskId)
- if (!hasValidSign) {
- await ElMessageBox.alert(
- '任务单金额已发生变动,客户签名已失效,请重新推送客户签名后再提交审核',
- '无法提交审核'
- )
- return
- }
- } catch (error) {
- console.error('检查签名状态失败:', error)
- ElMessage.error('检查签名状态失败,请重试')
- return
- }
- }
- // if([PressureReportType.SUGGUESTION, PressureReportType.MAINQUESTION].includes(props?.selectedItem?.reportType) && !props?.selectedItem?.reportUrl) {
- // // 【重大问题线索告知表,检验意见通知书】必须先填写记录,才能提交审核
- // ElMessage.warning('请先“填写记录”!再提交审核!')
- // return
- // }
- if(PressureReportType.SINGLE === props?.selectedItem?.reportType && !props?.selectedItem?.prepareUrl) {
- // 独审报告:用户可以不走报告编制环节直接提交审核,需要调用handleUploadAPIReportPreviewBlob将reportPreview接口的文件流拿来提交一遍
- // return handleUploadAPIReportPreviewBlob(handleSubmitAudit)
- isShowReportAuditDialog.value = true
- return
- }
- // 检查检验意见通知书是否“报告完结”
- const canSubmit = canSubmitMainReportType('该报告存在未办结检验意见通知书,无法提交审核、审批')
- if(!canSubmit) return
- // 检查其他报告状态
- const checkResult = checkOtherReportsFinished()
- if (!checkResult.canSubmit) {
- try {
- await ElMessageBox.alert(
- checkResult.message || '请先办结其他报告再提交主报告审核',
- '无法提交审核'
- )
- } catch (error) {
- // 用户关闭对话框,不需要处理
- }
- return
- }
- // if(PressureReportType.MAIN === props?.selectedItem?.reportType && !props?.selectedItem?.prepareUrl) {
- // // 主报告:用户可以不走报告编制环节直接提交审核,需要调用handleUploadAPIReportPreviewBlob将reportPreview接口的文件流拿来提交一遍
- // return handleUploadAPIReportPreviewBlob(handleSubmitAudit)
- // }
- // 重大问题线索通知 不需要选择审核人
- if ([PressureReportType['MAINQUESTION']].includes(templateParams.value?.reportType)) {
- ElMessageBox.confirm(`确定提交【${templateParams.value?.reportName}】`, '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消'
- })
- .then(async () => {
- const submitResult = await BoilerTaskOrderApi.submitOpinionNoticeApproval({
- id: templateParams.value?.id
- })
- if (submitResult) {
- // 这里可以做页面刷新
- emit('template-confirm')
- }
- })
- .catch(() => {
- console.log('用户取消提交审核')
- })
- } else if ([PressureReportType['SUGGUESTION']].includes(templateParams.value?.reportType)) {
- optionList.schemeReviewerList = await BoilerTaskOrderApi.getAuditList({
- roleCode: 'Boiler Director'
- })
- approvalUserVisible.value = true
- } else {
- // 确定审核人:使用当前用户,否则使用默认审核人
- // const approveId = userStore.user.id
- // const approveId = 'b5369aeb73954430eef53a9c8b7586ee'
- //
- // ElMessageBox.confirm('确定提交审核吗?', '提示', {
- // confirmButtonText: '确定',
- // cancelButtonText: '取消',
- // type: 'warning'
- // }).then(async () => {
- // const loadingInstance = ElLoading.service({
- // fullscreen: true,
- // text: '正在提交审核...'
- // })
- // try {
- // const submitResult = await BoilerTaskOrderApi.submitReportAudit({
- // id: templateParams.value?.id,
- // approveId
- // })
- // if (submitResult) {
- // ElMessage.success('提交审核成功!')
- // selectNextItem([props.selectedItem])
- // emit('template-confirm')
- // }
- // } finally {
- // loadingInstance.close()
- // }
- // }).catch(() => {
- // console.log('用户取消提交审核')
- // })
- isShowReportAuditDialog.value = true
- }
- }
- const handleCompletion = async () => {
- await BoilerTaskOrderApi.handleCompletion(props.selectedItem.id)
- handleRefresh()
- ElMessage.success('报告已办结')
- }
- const handleOpenSuggestionAuditDialog = () => {
- isShowSuggestionAuditDialog.value = true
- btnLoading.value = true
- UserApi.getApprovalDetail({})
- .then(async (res) => {
- if (res) {
- const opinionNotificationJsonData = res.opinionNotificationJson ? JSON.parse(res.opinionNotificationJson) : {}
- suggestionFormData.value = {
- ...res,
- ...opinionNotificationJsonData,
- }
- const suggestionFilds = sugguestionApproveConfig.value.map((item) => item.filed)
- const suggestionPromise = suggestionFilds.map((category) =>
- UserGroupApi.getUserGroupUserList({ category: category, status: 0 })
- )
- const suggestionResult = await Promise.all(suggestionPromise)
- sugguestionApproveConfig.value.forEach((item, index) => {
- const auditOptions = suggestionResult[index] || []
- item.auditOptions = auditOptions
- const auditId = suggestionFormData.value[item.auditIdProp]
- const auditUser = auditOptions.find((v) => v.id === auditId) || {}
- suggestionFormData.value[item.auditIdPropUser] = { ...auditUser, nickname: `${auditUser.nickname || ''}${auditUser.employeeNo ? `(${auditUser.employeeNo})` : ''}` }
- })
- }
- }).finally(() => {
- btnLoading.value = false
- })
- }
- const handleSubmitSuggestionAudit = () => {
- suggestionFormRef.value?.validate().then(async (valid) => {
- if (valid) {
- btnLoading.value = true
- const params = {
- id: templateParams.value?.id,
- auditUserIds: [suggestionFormData.value?.sugguestionAuditId],
- approveUserIds: [suggestionFormData.value?.sugguestionApproveId]
- }
- BoilerTaskOrderApi.submitOpinionNoticeApproval(params).then((submitResult) => {
- if (submitResult) {
- emit('template-confirm')
- }
- }).catch(() => {
- btnLoading.value = false
- ElMessage.error('提交失败')
- }).finally(() => {
- btnLoading.value = false
- isShowSuggestionAuditDialog.value = false
- })
- }
- })
- }
- const getUserLists = async (userList, params) => {
- const nickname = params.nickname
- const list = nickname ? userList.filter((item) => item.nickname.includes(nickname)) : userList
- const optList = list.map((item) => ({
- ...item,
- nickname: `${item.nickname}${item.employeeNo ? `(${item.employeeNo})` : ''}`,
- }))
- return Promise.resolve({ list: optList, total: list.length })
- }
- const handleChangeHandler = (val, prop) => {
- const { id } = val
- suggestionFormData.value[prop] = id
- }
- const getRecheckUserList = async (params) => {
- params.orderId = props.taskInfo.id
- params.orderItemId = props.taskOrderItem?.id
- return await BoilerTaskOrderApi.getRecheckUserList(params)
- }
- const getReviewUserList = async (params) => {
- params.reportId = props.selectedItem.id
- return await BoilerTaskOrderApi.getReviewUserList(params)
- }
- // 上传主报告文件流
- const handleUploadAPIReportPreviewBlob = async (submitApprovalFn) => {
- if(!props.selectedItem || props.selectedItem.taskStatus !== PressureTaskOrderTaskStatus.REPORT_INPUT) return
- // 获取文件流
- const blob = await BoilerTaskOrderApi.getReportPreview({
- reportId: props.selectedItem?.id,
- type: 300, // 报告模板
- fileType: 100 // xlsx
- })
- if(blob) {
- // 上传文件流
- const formData = new FormData()
- formData.append('file', blob)
- const response = await uploadFile(formData)
- // 保存报告编制的url
- const saveResult = await BoilerTaskOrderApi.saveReportPrepare({
- id: props.selectedItem.id,
- prepareUrl: response,
- })
-
- if(saveResult) {
- await emit('update:selected-item', {...props.selectedItem, prepareUrl: response})
- // 提交审核
- await submitApprovalFn()
- }
- }
- }
- const handleChangeEntrustUnit = (unit: Record<string, any>) => {
- form.value.recheckUser = unit
- }
- // 检查其他报告是否已办结
- const checkOtherReportsFinished = (): { canSubmit: boolean; message?: string } => {
- if (!props.selectedItem) return { canSubmit: false }
- // 如果不是主报告,直接允许提交
- if (props.selectedItem.reportType !== PressureReportType.MAIN) {
- return { canSubmit: true }
- }
- // 主报告需要检查其他报告状态
- const unfinishedReports = !props.reportList
- ? []
- : props.reportList.filter((report) => {
- // 排除当前报告
- if (report.id === templateParams.value?.id) {
- return false
- }
- // 检查子报告和独审报告是否已办结
- const isSubReport = report.reportType === PressureReportType.SUB
- const isSingleReport = report.reportType === PressureReportType.SINGLE
- const isSUGGUESTIONReport = report.reportType === PressureReportType.SUGGUESTION
- if (isSubReport || isSingleReport || isSUGGUESTIONReport) {
- return report.taskStatus !== PressureCheckerMyTaskStatus.REPORT_END
- }
- return false
- })
- if (unfinishedReports.length > 0) {
- const unfinishedNames = unfinishedReports.map((report) => report.reportName).join('、')
- return {
- canSubmit: false,
- message: `请先办结其他报告再提交主报告审核。未办结的报告:${unfinishedNames}`
- }
- }
- // 检查是否确认费用
- // const reportsWithoutConfirmFee: any[] = []
- // 检查当前报告中是否存在应确认费用,但未确认的报错
- const reportsWithoutConfirmFee: any[] = !props.reportList
- ? []
- : props.reportList.filter(
- (report: any) => report.isAutoAmount === '1' && report.feeConfirm === false
- )
- // if (currentReport) {
- // reportsWithoutConfirmFee.push(currentReport)
- // }
- // 检查子报告是否都已录入结果
- // const subReports = !props.reportList ? [] : props.reportList.filter(report => {
- // return report.id !== templateParams.value?.id &&
- // report.reportType === PressureReportType.SUB
- // })
- // subReports.forEach(report => {
- // if (!report.formulaJson) {
- // reportsWithoutConfirmFee.push(report)
- // }
- // })
- if (reportsWithoutConfirmFee.length > 0) {
- const reportNames = reportsWithoutConfirmFee.map((report) => report.reportName).join('、')
- return {
- canSubmit: false,
- message: `请先确认费用再提交主报告审核。未确认费用的报告:${reportNames}`
- }
- }
- return { canSubmit: true }
- }
- // 报告审核人选择对话框 - 远程搜索选项
- const reportAuditUserCode = ref<string>('')
- const reportAuditUserOptions = ref<Recordable[]>([])
- const reportAuditUserLoading = ref(false)
- const reportAuditSubmitting = ref(false)
- // 报告审核人选择确认
- const handleReportAuditSelectConfirm = async () => {
- if (!reportAuditUserCode.value) {
- ElMessage.warning('请选择审核人')
- return
- }
- reportAuditSubmitting.value = true
- try {
- const submitResult = await BoilerTaskOrderApi.submitReportAudit({
- id: templateParams.value?.id,
- auditor: reportAuditUserCode.value
- })
- if (submitResult) {
- // 保存默认审核人(工号)
- BoilerTaskOrderApi.saveDefaultApproval({
- approveEmployeeNo: reportAuditUserCode.value
- })
- emit('template-confirm')
- }
- isShowReportAuditDialog.value = false
- } finally {
- reportAuditSubmitting.value = false
- }
- }
- /**** 葡萄城:报告编制的显示和隐藏 end ****/
- const handleModifyChecker = () => {
- if (props.selectedItem) {
- emit('modify-checker', props.selectedItem)
- }
- }
- // 审批人选择确认
- const handleApprovalSelectConfirm = async (res: any) => {
- if (!props.selectedItem || !res || res.length === 0) {
- ElMessage.warning('请选择审批人')
- return
- }
- const ratifyId = res[0] // 获取选中的审批人ID
- try {
- await BoilerTaskOrderApi.submitReportApprove({
- id: props.selectedItem.id,
- ratifyId: ratifyId
- })
- ElMessage.success('提交审批成功')
- isShowApprovalDialog.value = false
- emit('submit-approval')
- } catch (error: any) {
- console.error('提交审批失败:', error)
- ElMessage.error('提交审批失败,请稍后重试')
- isShowApprovalDialog.value = false
- }
- }
- // 加载流转记录列表
- const recordList = ref<any[]>([])
- const recordListLoading = ref(false)
- const loadRecordList = async () => {
- if (!props.selectedItem) return
- try {
- let response = null
- // 检验意见通知书&重大问题线索
- switch (props.selectedItem.reportType) {
- case PressureReportType['SUGGUESTION']:
- case PressureReportType['MAINQUESTION']:
- response = await BoilerTaskOrderApi.getOpinionNoticeApprovalRecordList({
- id: props.selectedItem.id
- })
- break
- default:
- // 其他
- response = await BoilerTaskOrderApi.getTaskOrderItemReportRecordPage({
- pageSize: 10,
- pageNo: 1,
- reportId: props.selectedItem.id
- })
- }
- // 根据实际接口返回的数据结构获取数据
- recordList.value = response?.data?.list || response?.list || response || []
- } catch (error: any) {
- console.error('获取流转记录失败:', error)
- ElMessage.error('获取流转记录失败,请稍后重试')
- recordList.value = []
- } finally {
- recordListLoading.value = false
- }
- }
- // 获取报告字段纠错列表
- const checkInputList = ref<any[]>([])
- const handleGetCheckKeyInputs = async () => {
- checkInputList.value = []
- //if (!dataJson) return
- if (!props.selectedItem?.id) return ElMessage.warning('字段纠错传参有误')
- let reportId = props.selectedItem?.id
- // const templateId = isShowReportPdf.value? props.selectedItem?.reportTemplateId : props.selectedItem?.templateId;
- // if (isShowReportPdf.value){
- // reportId = "report_" + reportId;
- // }
- let templateId = showReportPdfType.value === 'report' ? props.selectedItem?.reportTemplateId :
- showReportPdfType.value === 'result' ? props.selectedItem?.resultTemplateId : props.selectedItem?.templateId;
- if (showReportPdfType.value === 'report'){
- reportId = "report_" + reportId;
- }else if (showReportPdfType.value === 'result'){
- reportId = "result_" + reportId;
- }
- const response = await BoilerTaskOrderApi.getCheckKeyIsInput(
- { id: templateId,reportId: reportId },
- JSON.parse("{}")
- )
- //console.log(JSON.parse(dataJson))
- if (response) checkInputList.value = formatCheckInputList(response)
- }
- function formatCheckInputList(response, checkInputList = [] as any[]) {
- if (!response) return []
- for (let checkItem of response) {
- if (!checkItem.child) {
- checkInputList.push({ code: checkItem.code, name: checkItem.name })
- }
- if (is(checkItem.child, 'Array') && checkItem.type === 'object') {
- formatCheckInputList(checkItem.child, checkInputList)
- }
- if (is(checkItem.child, 'Array') && checkItem.type === 'array') {
- const childMapper = checkItem.child.map((item, i) => {
- return {
- code: `${checkItem.code}: ${item.code}`,
- name: item.name
- }
- })
- formatCheckInputList(childMapper, checkInputList)
- }
- }
- return checkInputList
- }
- // 获取版本记录列表
- const showVersionDetail = ref(false)
- const historyList = ref<any[]>([])
- async function getOrderHistoryVersion(id: string) {
- try {
- const response = await BoilerTaskOrderApi.getSafetyCheckRecordVersionPage({
- pageNo: 1,
- pageSize: 100,
- businessType: 0,
- orderItemReportId: id
- })
- historyList.value = response.list || []
- } catch (error) {
- console.error('获取历史版本失败:', error)
- ElMessage.error('获取历史版本失败')
- }
- }
- const versionDataCompareList = ref([])
- const versionColumns = ref([
- {
- label: '字段名',
- prop: 'displayName'
- },
- {
- label: '修改前',
- prop: 'oldValue',
- render: (row, value) => (
- <el-text link type="default">
- {value || '-'}
- </el-text>
- )
- },
- {
- label: '修改后',
- prop: 'newValue',
- render: (row, value) => <el-text type="primary">{value || '-'}</el-text>
- }
- ])
- const versionDetailButtons = ref([
- {
- render: () => (
- <el-button type="success" onClick={() => handleShowReportPdf()}>
- 查看原文件PDF
- </el-button>
- )
- }
- ])
- const showReportDialog = ref(false)
- const currentUrl = ref('')
- const reportSource = ref<any | null>(null)
- const pdfLoading = ref(false)
- // 恢复版本
- const restoreVersion = (item: any) => {
- ElMessageBox.confirm('是否确定恢复到该版本?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'info',
- center: true
- })
- .then(async () => {
- const result = await BoilerTaskOrderApi.saveTaskReportTemplate({
- id: props.selectedItem?.id,
- reportUrl: item.oldReportUrl,
- prepareJson: item.oldPrepareJson,
- reportType: showReportPdfType.value,
- modifiedReason: '恢复版本'
- })
- console.log('restoreVersion', result)
- if (result) {
- ElMessage({
- type: 'success',
- message: '操作成功'
- })
- handleRefresh()
- } else {
- ElMessage.warning('操作失败,请联系管理员!')
- }
- })
- .catch(() => {})
- }
- // 查看版本详情的pdf
- const handleShowReportPdf = async () => {
- if (currentUrl.value) {
- const reportId = props.selectedItem?.id;
- reportInitData.value.refId = showReportPdfType.value === 'report' ? "report_" + reportId :
- showReportPdfType.value === 'result' ? "result_" + reportId : reportId
- reportInitData.value.templateId = showReportPdfType.value === 'report' ? templateParams.value.reportTemplateId :
- showReportPdfType.value === 'result' ? templateParams.value.resultTemplateId : templateParams.value.templateId
- reportInitData.value.dataSource = currentUrl.value.oldPrepareJson ? JSON.parse(currentUrl.value.oldPrepareJson) : {}
- console.log(currentUrl)
- showReportDialog.value = true
- setTimeout(()=> {
- reportSpreadRef.value?.reloadView();
- })
- pdfLoading.value = false
- } else {
- ElMessage.warning('报告缺失,请联系管理员!')
- }
- }
- const handlePdfRendered = () => {
- pdfLoading.value = false
- currentUrl.value = ''
- }
- // 查看详情
- const handleShowVersionInfo = (item) => {
- showVersionDetail.value = true
- currentUrl.value = item
- versionDataCompareList.value = JSON.parse(item.modifiedObject)
- }
- // 检验项目添加上传附件功能
- const reportListUploadModalRef = ref<InstanceType<typeof ReportListUploadModal>>()
- const handleUploadItem = () => {
- reportListUploadModalRef.value?.openModal(route.query.type === 'BoilerMyTask')
- }
- //切换记录和报告的显示
- const handleChangeShowReportPdf = (showType: string) => {
- if (showType === 'report' || showType === 'result'){
- if (![PressureCheckerMyTaskStatus.REPORT_INPUT,PressureCheckerMyTaskStatus.REPORT_AUDIT,PressureCheckerMyTaskStatus.REPORT_APPROVE,PressureCheckerMyTaskStatus.REPORT_END].includes(props.selectedItem.taskStatus)){
- ElMessage.error('该检验项目暂未生成报告!')
- showReportPdfType.value = 'record';
- return;
- }
- }
- if (showType === 'result'){
- if (!props.selectedItem?.resultTemplateId){
- ElMessage.error('该检验项目没有结论报告!')
- showReportPdfType.value = 'record';
- return;
- }
- }
- refreshPdfFlag.value = false;
- showReportPdfType.value = showType;
- handleRefreshData()
- }
- const isCanSyncReportData = computed(() => {
- return true
- //return [PressureCheckerMyTaskStatus.CONFIRMED,PressureCheckerMyTaskStatus.RECORD_INPUT].includes(props.selectedItem.taskStatus)
- })
- const handleSyncReportData = async () => {
- try {
- const response = await BoilerTaskOrderApi.syncReportData({
- refId: props.selectedItem.id,
- reportType : showReportPdfType.value
- })
- if (response){
- ElMessage.success('同步数据成功')
- handleRefresh()
- }else{
- ElMessage.error('同步数据失败,请稍后重试')
- }
- } catch (error: any) {
- console.error('同步数据失败:', error)
- ElMessage.error('同步数据失败,请稍后重试')
- }
- }
- const showAssociationOperationManual = ref(false)
- const handleShowAssociationOperationManual = () => {
- showAssociationOperationManual.value = true
- }
- onMounted(() => {
- console.log(props)
- //initPreview()
- BoilerTaskOrderApi.getAffairSummaryList().then((res) => {
- oaSummaryList.value = res || []
- })
- })
- const initPreviewTimer = ref<ReturnType<typeof setTimeout> | null>(null)
- const initPreview=()=>{
- // 清除上一次的定时器,防止快速切换项目时重复触发 reloadView
- if (initPreviewTimer.value) {
- clearTimeout(initPreviewTimer.value)
- initPreviewTimer.value = null
- }
- const reportId = props.selectedItem?.id;
- const refId = showReportPdfType.value === 'report' ? "report_" + reportId :
- showReportPdfType.value === 'result' ? "result_" + reportId : reportId
- const templateId = showReportPdfType.value === 'report' ? templateParams.value.reportTemplateId :
- showReportPdfType.value === 'result' ? templateParams.value.resultTemplateId : templateParams.value.templateId
- initData.value.templateId = templateId;
- initData.value.refId = refId;
- initData.value.refName = props.selectedItem?.reportName;
- initData.value.opType = (props.selectedItem.taskStatus == 510 || props.selectedItem.taskStatus >= 600 || (showReportPdfType.value === 'record' && props.selectedItem.taskStatus > 500) || props?.selectedItem?.checkUsers?.[0]?.id != userStore?.user?.id) ? 1 : 0;
- if (props.selectedItem.reportType === PressureReportType['INSPECTIONPLAN'] && props.selectedItem.manualUrl){
- initData.value.manualUrl = props.selectedItem.manualUrl;
- }else{
- initData.value.manualUrl = '';
- }
- // 记录模式使用 enterPdfUrl,报告模式使用 issueUrl,有值时跳过表格渲染直接预览 PDF
- if (showReportPdfType.value === 'record') {
- initData.value.enterPdfUrl = props.selectedItem?.enterPdfUrl || '';
- initData.value.issueUrl = '';
- } else {
- initData.value.enterPdfUrl = '';
- initData.value.issueUrl = props.selectedItem?.issueUrl || '';
- }
- initPreviewTimer.value = setTimeout(()=>{
- initPreviewTimer.value = null
- // 重新计算 PDF 区域宽度,确保不同屏幕下首次渲染时宽度正确
- if (pdfPanelRef.value) {
- const width = pdfPanelRef.value.clientWidth - 20
- pdfContentWidth.value = props.isFullscreen ? width : (width > 1030 ? 1030 : width)
- }
- spreadRef.value?.reloadView();
- },50)
- console.log('initPreview', initData.value)
- }
- const editPreview=(reportType: string)=>{
- const reportId = props.selectedItem?.id;
- const refId = showReportPdfType.value === 'report' ? "report_" + reportId :
- showReportPdfType.value === 'result' ? "result_" + reportId : reportId
- const templateId = showReportPdfType.value === 'report' ? templateParams.value.reportTemplateId :
- showReportPdfType.value === 'result' ? templateParams.value.resultTemplateId : templateParams.value.templateId
- editData.value.templateId = templateId;
- editData.value.refId = refId;
- editData.value.opType = 0;
- setTimeout(()=>{
- if (reportType === 'record'){
- editSpreadRecordRef.value?.reloadView();
- }else if(reportType === 'report'){
- editSpreadReportRef.value?.reloadView();
- }
- },50)
- console.log('editDataPreview', editData.value)
- }
- const saveSuccess = async (data)=>{
- if (props.selectedItem.taskStatus >= PressureCheckerMyTaskStatus.REPORT_INPUT){
- saveSuccessReport(data)
- }else {
- saveSuccessRecord(data)
- }
- }
- const saveSuccessRecord = async (data)=>{
- const dataJson = !data.dataSource ? '' : JSON.stringify(data.dataSource)
- const params = {
- id: props.selectedItem?.id,
- reportUrl: props.selectedItem?.id,
- prepareJson: dataJson
- }
- const saveResult = await BoilerTaskOrderApi.saveTaskReportTemplate(params)
- if (saveResult) {
- showInlineEditCheckRecord.value = false
- handleRefresh()
- }
- }
- const handleClose = () => {
- ElMessageBox.confirm('是否关闭?', {
- confirmButtonText: '确认',
- cancelButtonText: '取消',
- type: 'warning',
- }).then(() => {
- showInlineEditCheckRecord.value = false
- showInlineReportEdit.value = false
- handleRefresh()
- })
- }
- const saveSuccessReport = async (data)=>{
- const dataJson = !data.dataSource ? '' : JSON.stringify(data.dataSource)
- const saveResult = BoilerTaskOrderApi.saveReportPrepare({
- id: props.selectedItem?.id,
- prepareJson: dataJson,
- })
- if(saveResult) {
- showInlineReportEdit.value = false
- handleRefresh()
- }
- }
- const handleRefreshData = () => {
- loadRecordList()
- initPreview()
- handleGetCheckKeyInputs()
- getOrderHistoryVersion(props.selectedItem?.id)
- fetchProjectConfig()
- }
- // 应用项目 - 使用模板数据填充当前记录
- const handleApplyTemplate = (defaultJson: Recordable) => {
- if (!isCanEditTestRecord.value) {
- return ElMessage.warning('非可编辑状态,不能应用模板')
- }
- // 将模板数据保存到 initData 的 dataSource 中,供 SpreadViewer 使用
- initData.value = {
- ...initData.value,
- dataSource: defaultJson
- }
- setTimeout(()=>{
- spreadRef.value?.reloadView();
- },50)
- console.log(initData);
- }
- // 更新模板 - 打开记录编辑器供用户更新模板
- const handleUpdateTemplateUrl = (item: ReportItemVO) => {
- handleEditSpreadRecord()
- }
- const getData = () =>{
- return spreadRef.value?.getData()
- }
- defineExpose({
- handleShowAssociationOperationManual,
- handleApplyTemplate,
- handleUpdateTemplateUrl,
- getData,
- handleUploadItem
- })
- //新加
- // 添加控制展开/收缩状态的变量
- const isExpanded = ref(false);
- // 添加切换面板展开/收缩的方法
- const togglePanel = () => {
- isExpanded.value = !isExpanded.value;
- setTimeout((() => {
- nextTick(handleWindowResize)
- }), 300);
- };
- // 获取PDF宽度
- const pdfContentWidth = ref<number>(1100)
- const pdfPanelRef = ref<HTMLDivElement>()
- const handleWindowResize = debounce(() => {
- if(!pdfPanelRef.value) return
- const width = pdfPanelRef.value?.clientWidth - 20
- pdfContentWidth.value = props.isFullscreen ? width : (width > 1030 ? 1030 : width)
- //重新加载适应宽度
- if (initData.value.opType == 1){
- spreadRef.value?.reloadView();
- }else {
- spreadRef.value?.handleSave();
- }
- }, 100)
- onMounted(() => {
- handleWindowResize()
- window.addEventListener('resize', handleWindowResize)
- })
- onUnmounted(() => {
- window.removeEventListener('resize', handleWindowResize)
- if (initPreviewTimer.value) {
- clearTimeout(initPreviewTimer.value)
- initPreviewTimer.value = null
- }
- })
- // 全屏切换时重新计算PDF区域宽度
- watch(() => props.isFullscreen, () => {
- nextTick(() => {
- handleWindowResize()
- })
- })
- </script>
- <style lang="scss" scoped>
- .capsule-tabs {
- display: inline-flex;
- align-items: center;
- gap: 2px;
- padding: 2px;
- border-radius: 20px;
- margin-right: 12px;
- flex-shrink: 0;
- .tab-item {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- padding: 4px 12px;
- font-size: 12px;
- background: white;
- border-radius: 16px;
- cursor: pointer;
- transition: all 0.3s ease;
- color: #606266;
- font-weight: 500;
- border: 1px solid transparent;
- user-select: none;
- white-space: nowrap;
- min-width: 50px;
- span {
- font-size: 12px !important;
- }
- &:hover {
- color: #409eff;
- border-color: #409eff;
- }
- &.active {
- background: linear-gradient(135deg, #409eff 0%, #66b1ff 100%);
- color: white;
- border-color: #409eff;
- box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
- }
- }
- }
- .container-panel {
- height: 100%;
- border: 1px solid var(--el-border-color);
- .info-panel {
- display: flex;
- height: 32px;
- padding: 0 8px 0 22px;
- font-size: 14px;
- color: #41475c;
- background-color: #effaff;
- justify-content: space-between;
- align-items: center;
- }
- .status-operation-panel {
- height: calc(100% - 32px);
- .single-item-panel {
- display: flex;
- align-items: stretch;
- justify-content: space-between;
- width: 100%;
- height: 100%;
- }
- .pdf-panel {
- height: 100%;
- padding: 10px;
- flex: 1;
- overflow: hidden;
- }
- .right-panel-container {
- display: flex;
- position: relative;
- // 收缩展开按钮样式
- .toggle-btn {
- position: absolute;
- left: -30px;
- top: 50%;
- transform: translateY(-50%);
- width: 30px;
- height: 60px;
- background-color: #fff;
- border: 1px solid var(--el-border-color);
- border-radius: 10px 0 0 10px;
- display: flex;
- align-items: center;
- justify-content: center;
- cursor: pointer;
- z-index: 100;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
- transition: all 0.3s ease;
- &:hover {
- background-color: #f5f5f5;
- }
- &.collapsed {
- left: -18px;
- // border-radius: 0 10px 10px 0;
- }
- }
- }
- .operation-panel {
- flex-basis: 300px;
- padding: 10px 10px 10px 0;
- box-sizing: border-box;
- transition: all 0.3s ease;
- // 展开状态样式
- &.expanded {
- width: 300px;
- }
- // 收缩状态样式
- &.collapsed {
- width: 0;
- padding: 0;
- border: none;
- .default-toolbar,
- .operation-inner {
- display: none;
- }
- }
- .operation-btns {
- display: flex;
- flex-wrap: wrap;
- gap: 12px;
- .el-button {
- margin-bottom: 10px;
- margin-left: 0;
- }
- }
- }
- .operation-inner {
- height: 100%;
- padding: 7px 10px 20px;
- background-color: #fff;
- border: 1px solid var(--el-border-color);
- box-sizing: border-box;
- }
- .custom-inner{
- display: flex;
- flex-direction: column;
- overflow: hidden;
- height: 100%;
- padding: 7px 10px 20px;
- background-color: #fff;
- border: 1px solid var(--el-border-color);
- box-sizing: border-box;
- .operation-item1 {
- position: relative;
- margin-bottom: 10px;
- overflow-y: auto;
- .item-header {
- position: sticky;
- top: 0;
- left: 0;
- z-index: 1000;
- width: 100%;
- height: 28px;
- padding-left: 20px;
- font-size: 16px;
- line-height: 28px;
- color: #fff;
- background: #fff url('@/assets/imgs/pressure/my-task-detail-operation-bg.png') no-repeat
- left top;
- background-size: 100% 28px;
- }
- .item-content1 {
- display: flex;
- margin-top: 10px;
- &-item {
- font-size: 14px;
- }
- &-img {
- flex: 1;
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- grid-gap: 10px;
- .item-content1-img-item{
- width: 100px;
- height: 100px;
- position: relative;
- border-radius: 8px;
- overflow: hidden;
- cursor: pointer;
- .video-play-overlay {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- border-radius: 8px;
- transition: all 0.3s ease;
- display: flex;
- justify-content: center;
- align-items: center;
- background-color: rgba(0, 0, 0, 0.2);
- color: #ffffffcc;
- pointer-events: none;
- &:hover {
- background-color: rgba(0, 0, 0, 0.45);
- color: #ffffff;
- }
- }
- }
- .img-item {
- width: 100px;
- height: 100px;
- }
- }
- }
- .record-item {
- margin-bottom: 10px;
- background-color: #f5f5fa;
- border-radius: 2px;
- }
- .item-content {
- padding: 10px 0;
- font-size: 14px;
- .el-empty {
- width: 100%;
- height: 150px;
- padding: 0;
- box-sizing: border-box;
- }
- &-item {
- height: 32px;
- display: flex;
- align-items: center;
- gap: 8px;
- }
- }
- .record-item-title {
- height: 31px;
- padding: 0 13px;
- line-height: 31px;
- background: linear-gradient(270deg, rgb(128 176 251 / 20%) 0%, rgb(73 120 246 / 20%) 100%);
- border-radius: 2px;
- }
- .record-item-inner {
- padding: 11px 13px 8px;
- .content {
- display: flex;
- align-items: center;
- .el-button {
- margin-left: 8px;
- }
- :deep(.el-button--small.is-round) {
- height: auto;
- padding: 3px 11px;
- }
- .time {
- color: rgb(31 31 31 / 88%);
- text-align: right;
- opacity: 0.5;
- flex: 1;
- }
- }
- .desc {
- margin-top: 7px;
- color: #41475c;
- opacity: 0.8;
- span {
- opacity: 0.5;
- }
- }
- }
- .error-item {
- display: flex;
- padding: 7px 10px;
- color: #41475c;
- background-color: #f5f5fa;
- border: 1px solid var(--el-border-color);
- border-width: 1px 0;
- align-items: center;
- .el-icon {
- margin-right: 6px;
- }
- &:nth-child(n + 1) {
- margin-top: -1px;
- }
- &:nth-child(even) {
- background-color: #fff;
- }
- }
- .history-item {
- padding: 7px 10px 10px;
- margin-bottom: 13px;
- color: #41475c;
- background-color: #f5f5fa;
- border-radius: 2px;
- .history-title {
- display: flex;
- align-items: center;
- margin-left: -10px;
- font-weight: 600;
- line-height: 20px;
- &::before {
- display: block;
- width: 4px;
- height: 15px;
- margin-right: 7px;
- background: #4978f6;
- content: '';
- }
- }
- p {
- margin: 10px 0;
- line-height: 20px;
- }
- .history-footer {
- display: flex;
- // align-items: center;
- font-size: 12px;
- .name {
- color: #4978f6;
- }
- .time {
- margin-left: 2px;
- color: rgb(65 71 92 / 50%);
- }
- div {
- flex: 1;
- display: flex;
- justify-content: flex-end;
- .el-button span {
- font-size: 12px;
- }
- }
- }
- }
- }
- .videoAndImg {
- flex: 1;
- width: 100%;
- overflow-y: auto;
- }
- }
- .operation-item {
- position: relative;
- max-height: calc(100% / 3 - 10px);
- margin-bottom: 10px;
- overflow-y: auto;
- .item-header {
- position: sticky;
- top: 0;
- left: 0;
- z-index: 1000;
- width: 100%;
- height: 28px;
- padding-left: 20px;
- font-size: 16px;
- line-height: 28px;
- color: #fff;
- background: #fff url('@/assets/imgs/pressure/my-task-detail-operation-bg.png') no-repeat
- left top;
- background-size: 100% 28px;
- }
- .item-content1 {
- display: flex;
- margin-top: 10px;
- &-item {
- font-size: 14px;
- }
- &-img {
- flex: 1;
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- grid-gap: 10px;
- .item-content1-img-item{
- width: 100px;
- height: 100px;
- position: relative;
- border-radius: 8px;
- overflow: hidden;
- cursor: pointer;
- .video-play-overlay {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- border-radius: 8px;
- transition: all 0.3s ease;
- display: flex;
- justify-content: center;
- align-items: center;
- background-color: rgba(0, 0, 0, 0.2);
- color: #ffffffcc;
- pointer-events: none;
- &:hover {
- background-color: rgba(0, 0, 0, 0.45);
- color: #ffffff;
- }
- }
- }
- .img-item {
- width: 100px;
- height: 100px;
- }
- }
- }
- .record-item {
- margin-bottom: 10px;
- background-color: #f5f5fa;
- border-radius: 2px;
- }
- .item-content {
- padding: 10px 0;
- font-size: 14px;
- .el-empty {
- width: 100%;
- height: 150px;
- padding: 0;
- box-sizing: border-box;
- }
- &-item {
- height: 32px;
- display: flex;
- align-items: center;
- gap: 8px;
- }
- }
- .record-item-title {
- height: 31px;
- padding: 0 13px;
- line-height: 31px;
- background: linear-gradient(270deg, rgb(128 176 251 / 20%) 0%, rgb(73 120 246 / 20%) 100%);
- border-radius: 2px;
- }
- .record-item-inner {
- padding: 11px 13px 8px;
- .content {
- display: flex;
- align-items: center;
- .el-button {
- margin-left: 8px;
- }
- :deep(.el-button--small.is-round) {
- height: auto;
- padding: 3px 11px;
- }
- .time {
- color: rgb(31 31 31 / 88%);
- text-align: right;
- opacity: 0.5;
- flex: 1;
- }
- }
- .desc {
- margin-top: 7px;
- color: #41475c;
- opacity: 0.8;
- span {
- opacity: 0.5;
- }
- }
- }
- .error-item {
- display: flex;
- padding: 7px 10px;
- color: #41475c;
- background-color: #f5f5fa;
- border: 1px solid var(--el-border-color);
- border-width: 1px 0;
- align-items: center;
- .el-icon {
- margin-right: 6px;
- }
- &:nth-child(n + 1) {
- margin-top: -1px;
- }
- &:nth-child(even) {
- background-color: #fff;
- }
- }
- .history-item {
- padding: 7px 10px 10px;
- margin-bottom: 13px;
- color: #41475c;
- background-color: #f5f5fa;
- border-radius: 2px;
- .history-title {
- display: flex;
- align-items: center;
- margin-left: -10px;
- font-weight: 600;
- line-height: 20px;
- &::before {
- display: block;
- width: 4px;
- height: 15px;
- margin-right: 7px;
- background: #4978f6;
- content: '';
- }
- }
- p {
- margin: 10px 0;
- line-height: 20px;
- }
- .history-footer {
- display: flex;
- // align-items: center;
- font-size: 12px;
- .name {
- color: #4978f6;
- }
- .time {
- margin-left: 2px;
- color: rgb(65 71 92 / 50%);
- }
- div {
- flex: 1;
- display: flex;
- justify-content: flex-end;
- .el-button span {
- font-size: 12px;
- }
- }
- }
- }
- }
- }
- }
- .default-toolbar {
- display: flex;
- justify-content: flex-end;
- gap: 16px;
- white-space: nowrap;
- ::v-deep .el-button {
- margin-left: 0;
- }
- }
- // 退回对话框样式
- .reject-dialog-content {
- .form-item {
- margin-bottom: 20px;
- &:last-child {
- margin-bottom: 0;
- }
- .form-label {
- display: block;
- margin-bottom: 8px;
- font-size: 14px;
- font-weight: 500;
- color: #606266;
- }
- }
- }
- :deep(.preview-dialog) {
- background-color: transparent !important;
- width: auto !important;
- padding: 0 !important;
- .el-dialog__header {
- display: none;
- }
- .el-dialog__body{
- padding: 0;
- .preview-container{
- padding: 0;
- position: relative;
- }
- .preview-image,.preview-video {
- height: 65vh;
- max-width: 100vw;
- }
- }
- }
- .rectification-dialog {
- padding: 8px 0;
- .upload-section {
- margin-bottom: 24px;
- padding: 20px;
- background: #fafafa;
- border-radius: 8px;
- transition: all 0.3s ease;
- &:hover {
- background: #f5f5f5;
- }
- &.required {
- border: 1px solid #e8f4ff;
- background: #f7fbff;
- &:hover {
- background: #f0f8ff;
- }
- }
- .section-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 16px;
- .header-left {
- display: flex;
- align-items: center;
- gap: 8px;
- .section-title {
- font-size: 15px;
- font-weight: 600;
- color: #303133;
- }
- .required-mark {
- color: #f56c6c;
- font-size: 16px;
- font-weight: bold;
- }
- i[class^="icon-"] {
- font-size: 18px;
- color: #409eff;
- }
- }
- .section-tip {
- font-size: 12px;
- color: #909399;
- background: #fff;
- padding: 4px 12px;
- border-radius: 12px;
- border: 1px solid #e4e7ed;
- }
- }
- .upload-area {
- min-height: 80px;
- }
- }
- .info-tips {
- display: flex;
- gap: 12px;
- padding: 16px;
- background: linear-gradient(135deg, #fff9e6 0%, #fff5cc 100%);
- border-left: 4px solid #e6a23c;
- border-radius: 6px;
- margin-top: 20px;
- .icon-info {
- font-size: 20px;
- color: #e6a23c;
- flex-shrink: 0;
- margin-top: 2px;
- }
- .tips-content {
- flex: 1;
- .tips-title {
- font-weight: 600;
- color: #606266;
- margin-bottom: 8px;
- font-size: 14px;
- }
- p {
- font-size: 13px;
- color: #606266;
- line-height: 1.8;
- margin: 0;
- &:not(.tips-title) {
- padding-left: 12px;
- position: relative;
- &::before {
- content: "•";
- position: absolute;
- left: 0;
- color: #e6a23c;
- }
- }
- }
- }
- }
- }
- .icon-document::before {
- content: "📄";
- }
- .icon-image::before {
- content: "🖼️";
- }
- .icon-video::before {
- content: "🎬";
- }
- .icon-info::before {
- content: "ℹ️";
- }
- .dialog-content {
- font-size: 15px;
- line-height: 30px;
- display: flex;
- justify-content: center;
- align-items: center;
- height: 100%;
- }
- </style>
|