| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908 |
- <!DOCTYPE html><html lang="zh-CN">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
- <title>清道夫系统 - 完整版 V21-SOP增强版</title>
- <script src="https://cdn.tailwindcss.com"></script>
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
- <style>
- * {
- -webkit-tap-highlight-color: transparent;
- box-sizing: border-box;
- }
- body {
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
- background: #f5f5f5;
- min-height: 100vh;
- margin: 0;
- padding: 0;
- }
- /* 页面容器 */
- .app-container {
- max-width: 430px;
- margin: 0 auto;
- min-height: 100vh;
- background: #f5f5f5;
- position: relative;
- }
- /* 页面内容区域 */
- .page {
- display: none;
- min-height: 100vh;
- padding-bottom: 70px;
- }
- .page.active {
- display: block;
- }
- /* 底部导航栏 */
- .bottom-nav {
- position: fixed;
- bottom: 0;
- left: 50%;
- transform: translateX(-50%);
- width: 100%;
- max-width: 430px;
- background: white;
- box-shadow: 0 -2px 10px rgba(0,0,0,0.08);
- z-index: 100;
- }
- .nav-item.active {
- color: #3b82f6;
- }
- .nav-item.active .nav-icon {
- background: #eff6ff;
- }
- .card {
- background: white;
- border-radius: 12px;
- box-shadow: 0 2px 8px rgba(0,0,0,0.06);
- }
- .project-card {
- transition: transform 0.2s, box-shadow 0.2s;
- }
- .project-card:active {
- transform: scale(0.98);
- box-shadow: 0 1px 4px rgba(0,0,0,0.1);
- }
- .disabled-card {
- opacity: 0.5;
- cursor: not-allowed;
- pointer-events: none;
- }
- .role-tab {
- transition: all 0.3s;
- }
- .role-tab.active {
- background: #3b82f6;
- color: white;
- border-color: #3b82f6;
- }
- /* 销售端统计卡片样式 */
- #salesApp .stat-card {
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- }
- #salesApp .stat-card:nth-child(2) {
- background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
- }
- #salesApp .stat-card:nth-child(3) {
- background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
- }
- .news-img {
- width: 60px;
- height: 60px;
- border-radius: 8px;
- background: linear-gradient(135deg, #e0e7ff 0%, #c7d2fe 100%);
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .login-btn {
- background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
- transition: all 0.3s;
- }
- .login-btn:active {
- transform: scale(0.98);
- opacity: 0.9;
- }
- .btn {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- padding: 10px 20px;
- border-radius: 8px;
- font-size: 14px;
- font-weight: 500;
- cursor: pointer;
- transition: all 0.2s;
- }
- .btn:active {
- transform: scale(0.98);
- }
- .btn-danger {
- background: #ef4444;
- color: white;
- }
- .btn-danger:active {
- background: #dc2626;
- }
- .add-btn {
- background: linear-gradient(135deg, #10b981 0%, #059669 100%);
- }
- .quick-entry-card {
- transition: all 0.2s;
- }
- .quick-entry-card:active {
- transform: scale(0.95);
- }
- .quick-entry-card.disabled {
- opacity: 0.5;
- cursor: not-allowed;
- }
- .quick-entry-card.disabled:active {
- transform: none;
- }
- /* 详情页样式 */
- .detail-section {
- background: white;
- border-radius: 12px;
- margin-bottom: 12px;
- overflow: hidden;
- }
- .detail-section-title {
- padding: 12px 16px;
- font-size: 14px;
- font-weight: 600;
- color: #333;
- border-bottom: 1px solid #f0f0f0;
- display: flex;
- align-items: center;
- gap: 8px;
- }
- .detail-row {
- padding: 12px 16px;
- display: flex;
- justify-content: space-between;
- align-items: flex-start;
- border-bottom: 1px solid #f5f5f5;
- }
- .detail-row:last-child {
- border-bottom: none;
- }
- .detail-label {
- color: #666;
- font-size: 14px;
- flex-shrink: 0;
- }
- .detail-value {
- color: #333;
- font-size: 14px;
- text-align: right;
- flex: 1;
- margin-left: 12px;
- }
- .tag {
- display: inline-block;
- padding: 2px 8px;
- border-radius: 4px;
- font-size: 12px;
- font-weight: 500;
- }
- .tag-blue {
- background: #e6f0ff;
- color: #2563eb;
- }
- .tag-green {
- background: #e6f7f1;
- color: #059669;
- }
- .tag-purple {
- background: #f3e8ff;
- color: #7c3aed;
- }
- .tag-orange {
- background: #fff7ed;
- color: #ea580c;
- }
- .service-point-item {
- padding: 12px 16px;
- background: #fafafa;
- border-radius: 8px;
- margin: 8px 16px;
- }
- .contact-item {
- display: flex;
- align-items: center;
- padding: 10px 0;
- border-bottom: 1px solid #f5f5f5;
- }
- .contact-item:last-child {
- border-bottom: none;
- }
- /* 表单样式 */
- .form-group {
- margin-bottom: 16px;
- }
- .form-label {
- display: block;
- font-size: 14px;
- color: #666;
- margin-bottom: 8px;
- }
- .form-input {
- width: 100%;
- padding: 12px 16px;
- border: 1px solid #e5e7eb;
- border-radius: 8px;
- font-size: 14px;
- color: #333;
- background: #fff;
- }
- .form-input:focus {
- outline: none;
- border-color: #3b82f6;
- box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
- }
- .form-select {
- width: 100%;
- padding: 12px 16px;
- border: 1px solid #e5e7eb;
- border-radius: 8px;
- font-size: 14px;
- color: #333;
- background: #fff;
- appearance: none;
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23999999' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
- background-repeat: no-repeat;
- background-position: right 16px center;
- }
- .form-select:focus {
- outline: none;
- border-color: #3b82f6;
- }
- .form-textarea {
- width: 100%;
- padding: 12px 16px;
- border: 1px solid #e5e7eb;
- border-radius: 8px;
- font-size: 14px;
- color: #333;
- background: #fff;
- resize: vertical;
- min-height: 100px;
- }
- .form-textarea:focus {
- outline: none;
- border-color: #3b82f6;
- box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
- }
- /* 列表项样式 */
- .list-item {
- background: white;
- padding: 16px;
- border-bottom: 1px solid #f0f0f0;
- cursor: pointer;
- transition: background 0.2s;
- }
- .list-item:active {
- background: #f9fafb;
- }
- .list-item:last-child {
- border-bottom: none;
- }
- /* 公告样式 */
- .notice-item {
- background: white;
- padding: 16px;
- border-bottom: 1px solid #f0f0f0;
- cursor: pointer;
- }
- .notice-item:active {
- background: #f9fafb;
- }
- /* 知识卡片样式 */
- .knowledge-card {
- background: white;
- padding: 12px;
- border-radius: 12px;
- margin-bottom: 12px;
- cursor: pointer;
- box-shadow: 0 2px 8px rgba(0,0,0,0.06);
- }
- .knowledge-card:active {
- transform: scale(0.98);
- }
- /* Toast样式 */
- #toast {
- position: fixed;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- background: rgba(0,0,0,0.8);
- color: white;
- padding: 16px 32px;
- border-radius: 8px;
- z-index: 9999;
- font-size: 14px;
- }
- #toast.hidden {
- display: none;
- }
- /* 隐藏底部导航的页面 */
- .page.hide-nav {
- padding-bottom: 0;
- }
- .page.hide-nav .bottom-nav {
- display: none;
- }
- /* 筛选标签样式 */
- .filter-tabs {
- display: flex;
- gap: 8px;
- padding: 12px 16px;
- background: white;
- overflow-x: auto;
- -webkit-overflow-scrolling: touch;
- }
- .filter-tabs::-webkit-scrollbar {
- display: none;
- }
- .filter-tab {
- flex-shrink: 0;
- padding: 6px 16px;
- border-radius: 20px;
- font-size: 13px;
- color: #666;
- background: #f5f5f5;
- border: 1px solid #e5e7eb;
- transition: all 0.2s;
- cursor: pointer;
- }
- .filter-tab:active {
- transform: scale(0.95);
- }
- .filter-tab.active {
- background: #3b82f6;
- color: white;
- border-color: #3b82f6;
- }
- /* 动态列表隐藏 */
- .project-item[data-type] {
- display: block;
- }
- .project-item.hidden {
- display: none !important;
- }
- /* 联系人卡片样式 */
- .contact-card {
- background: #f9fafb;
- border-radius: 8px;
- padding: 12px;
- margin-bottom: 8px;
- }
- .contact-card:last-child {
- margin-bottom: 0;
- }
- /* 子服务项样式 */
- .service-item {
- background: #f9fafb;
- border-radius: 8px;
- padding: 12px;
- margin-bottom: 8px;
- }
- .service-item:last-child {
- margin-bottom: 0;
- }
- .service-item .delete-btn {
- color: #ef4444;
- cursor: pointer;
- }
- /* 服务点样式 */
- .point-item {
- background: #f9fafb;
- border-radius: 8px;
- padding: 12px;
- margin-bottom: 8px;
- }
- .point-item:last-child {
- margin-bottom: 0;
- }
- .point-item .delete-btn {
- color: #ef4444;
- cursor: pointer;
- }
- /* 添加按钮样式 */
- .add-item-btn {
- width: 100%;
- padding: 12px;
- border: 2px dashed #d1d5db;
- border-radius: 8px;
- background: transparent;
- color: #6b7280;
- font-size: 14px;
- cursor: pointer;
- transition: all 0.2s;
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 6px;
- }
- .add-item-btn:active {
- background: #f3f4f6;
- border-color: #9ca3af;
- }
- /* 空状态样式 */
- .empty-state {
- text-align: center;
- padding: 60px 20px;
- }
- .empty-state i {
- font-size: 48px;
- color: #d1d5db;
- margin-bottom: 16px;
- }
- .empty-state p {
- color: #9ca3af;
- font-size: 14px;
- }
- /* 任务卡片样式 */
- .task-card {
- background: white;
- border-radius: 12px;
- padding: 16px;
- margin-bottom: 12px;
- box-shadow: 0 2px 8px rgba(0,0,0,0.06);
- cursor: pointer;
- transition: transform 0.2s, box-shadow 0.2s;
- }
- .task-card:active {
- transform: scale(0.98);
- box-shadow: 0 1px 4px rgba(0,0,0,0.1);
- }
- .task-card .header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 10px;
- }
- .task-card .task-name {
- font-size: 15px;
- font-weight: 600;
- color: #333;
- }
- .task-card .task-info {
- font-size: 13px;
- color: #666;
- margin-bottom: 6px;
- }
- .task-card .task-info i {
- width: 20px;
- color: #999;
- }
- /* 进度条样式(底部进度条) */
- .progress-bar-container {
- margin-top: 8px;
- padding: 0 4px;
- }
- .progress-bar-track {
- height: 4px;
- background: #e5e7eb;
- border-radius: 2px;
- position: relative;
- display: flex;
- justify-content: space-between;
- align-items: center;
- }
- .progress-bar-fill {
- position: absolute;
- left: 0;
- top: 0;
- height: 100%;
- background: #3b82f6;
- border-radius: 2px;
- transition: width 0.3s ease;
- }
- .progress-bar-step {
- width: 12px;
- height: 12px;
- border-radius: 50%;
- background: #e5e7eb;
- border: 2px solid #fff;
- position: relative;
- z-index: 1;
- flex-shrink: 0;
- }
- .progress-bar-step.completed {
- background: #3b82f6;
- }
- .progress-bar-step.active {
- background: #3b82f6;
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.3);
- }
- .progress-bar-labels {
- display: flex;
- justify-content: space-between;
- margin-top: 4px;
- }
- .progress-bar-labels span {
- font-size: 10px;
- color: #999;
- }
- .progress-bar-labels span.active {
- color: #3b82f6;
- font-weight: 500;
- }
- /* 任务卡片颜色区分 */
- .task-card {
- background: white;
- border-radius: 12px;
- padding: 16px;
- margin-bottom: 12px;
- box-shadow: 0 2px 8px rgba(0,0,0,0.06);
- cursor: pointer;
- transition: transform 0.2s, box-shadow 0.2s, background-color 0.2s;
- position: relative;
- overflow: hidden;
- }
- .task-card:active {
- transform: scale(0.98);
- box-shadow: 0 1px 4px rgba(0,0,0,0.1);
- }
- /* 应急/加急 - 左侧红色边框 */
- .task-card.emergency {
- border-left: 4px solid #ef4444;
- }
- /* 超时/即将超时 - 淡红色背景 */
- .task-card.timeout {
- background: #fef2f2;
- }
- /* 已完成 - 淡绿色背景 */
- .task-card.completed {
- background: #f0fdf4;
- }
- .task-card .header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 10px;
- }
- .task-card .task-name {
- font-size: 15px;
- font-weight: 600;
- color: #333;
- }
- .task-card .task-info {
- font-size: 13px;
- color: #666;
- margin-bottom: 6px;
- }
- .task-card .task-info i {
- width: 20px;
- color: #999;
- }
- /* 状态标签 */
- .status-tag {
- display: inline-block;
- padding: 3px 10px;
- border-radius: 4px;
- font-size: 12px;
- font-weight: 500;
- }
- .status-scheduling {
- background: #fff7ed;
- color: #ea580c;
- }
- .status-constructing {
- background: #eff6ff;
- color: #2563eb;
- }
- .status-completed {
- background: #ecfdf5;
- color: #059669;
- }
- .status-emergency {
- background: #fef2f2;
- color: #dc2626;
- }
- .status-pending-cancel {
- background: #fef3c7;
- color: #d97706;
- }
- /* 紧急程度 */
- .urgent-tag {
- display: inline-block;
- padding: 2px 6px;
- border-radius: 3px;
- font-size: 11px;
- margin-right: 6px;
- }
- .urgent-high {
- background: #fef2f2;
- color: #dc2626;
- }
- .urgent-normal {
- background: #f3f4f6;
- color: #6b7280;
- }
- /* 详情页优化样式 */
- /* 项目信息区块 */
- .detail-block {
- background: white;
- border-radius: 12px;
- margin-bottom: 12px;
- overflow: hidden;
- }
- .detail-block-header {
- padding: 12px 16px;
- font-size: 14px;
- font-weight: 600;
- color: #333;
- border-bottom: 1px solid #f0f0f0;
- display: flex;
- align-items: center;
- gap: 8px;
- }
- /* 处理记录时间线样式优化 */
- .timeline-record {
- display: flex;
- padding: 12px 16px;
- position: relative;
- }
- .timeline-record:not(:last-child)::after {
- content: '';
- position: absolute;
- left: 38px;
- top: 44px;
- bottom: 0;
- width: 2px;
- background: #e5e7eb;
- }
- .timeline-record:last-child::after {
- display: none;
- }
- .timeline-avatar {
- width: 32px;
- height: 32px;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-right: 12px;
- flex-shrink: 0;
- font-size: 14px;
- color: white;
- }
- .timeline-avatar.sales {
- background: #3b82f6;
- }
- .timeline-avatar.dispatch {
- background: #f97316;
- }
- .timeline-avatar.worker {
- background: #10b981;
- }
- .timeline-record.current {
- background: #eff6ff;
- border-radius: 8px;
- margin: 0 8px;
- border-left: 3px solid #3b82f6;
- }
- .timeline-record.current::after {
- display: none;
- }
- .timeline-content {
- flex: 1;
- }
- .timeline-time {
- font-size: 12px;
- color: #999;
- margin-bottom: 4px;
- }
- .timeline-action {
- font-size: 14px;
- color: #333;
- line-height: 1.5;
- }
- .timeline-operator {
- font-size: 12px;
- color: #666;
- margin-top: 4px;
- }
- .timeline-record.current .timeline-time {
- color: #3b82f6;
- font-weight: 500;
- }
- .timeline-record.current .timeline-action {
- color: #1e40af;
- font-weight: 500;
- }
- /* 子服务项卡片样式 */
- .service-point-card {
- background: #f9fafb;
- border-radius: 12px;
- padding: 14px;
- margin-bottom: 10px;
- border: 2px solid transparent;
- cursor: pointer;
- transition: all 0.2s;
- }
- .service-point-card:active {
- transform: scale(0.98);
- }
- .service-point-card.selected {
- border-color: #3b82f6;
- background: #eff6ff;
- }
- .service-point-card .card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 8px;
- }
- .service-point-card .point-name {
- font-size: 15px;
- font-weight: 600;
- color: #333;
- }
- .service-point-card .service-tag {
- background: #e6f0ff;
- color: #2563eb;
- padding: 3px 10px;
- border-radius: 12px;
- font-size: 12px;
- font-weight: 500;
- }
- .service-point-card .point-location {
- font-size: 13px;
- color: #666;
- display: flex;
- align-items: center;
- gap: 6px;
- }
- .service-point-card .point-location i {
- color: #999;
- width: 14px;
- }
- /* 日期时间选择器 */
- .datetime-input {
- display: flex;
- gap: 8px;
- }
- .datetime-input input {
- flex: 1;
- }
- /* 已填充信息样式 */
- .auto-filled {
- background: #f0f9ff !important;
- border-color: #3b82f6 !important;
- }
- .auto-filled-label {
- color: #3b82f6;
- font-size: 11px;
- font-weight: 500;
- margin-bottom: 4px;
- }
- /* 选择提示 */
- .select-hint {
- text-align: center;
- padding: 40px 20px;
- color: #9ca3af;
- }
- .select-hint i {
- font-size: 48px;
- margin-bottom: 12px;
- color: #d1d5db;
- }
- .select-hint p {
- font-size: 14px;
- }
- /* 合并选择器样式 */
- .inline-selector {
- display: flex;
- gap: 10px;
- }
- .inline-selector .form-group {
- flex: 1;
- margin-bottom: 0;
- }
- .inline-selector .form-select {
- padding-right: 32px;
- }
- /* 联系人列表样式 */
- .contact-list-item {
- display: flex;
- align-items: center;
- background: #f0f9ff;
- border-radius: 8px;
- padding: 10px 12px;
- margin-bottom: 8px;
- border: 1px solid #e0efff;
- }
- .contact-list-item .contact-info {
- flex: 1;
- display: flex;
- flex-direction: column;
- }
- .contact-list-item .contact-name {
- font-size: 14px;
- color: #333;
- font-weight: 500;
- }
- .contact-list-item .contact-phone {
- font-size: 12px;
- color: #666;
- margin-top: 2px;
- }
- .contact-list-item .delete-btn {
- width: 28px;
- height: 28px;
- display: flex;
- align-items: center;
- justify-content: center;
- color: #ef4444;
- cursor: pointer;
- }
- /* 可折叠区块样式 */
- .collapsible-section .detail-section-title {
- cursor: pointer;
- user-select: none;
- }
- .collapsible-section .detail-section-title .toggle-icon {
- transition: transform 0.2s;
- margin-left: auto;
- }
- .collapsible-section.collapsed .detail-section-title .toggle-icon {
- transform: rotate(-90deg);
- }
- .collapsible-section.collapsed .section-content {
- display: none;
- }
- /* 取消任务模态框样式 */
- .modal-overlay {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(0,0,0,0.5);
- z-index: 1000;
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 20px;
- }
- .modal-overlay.hidden {
- display: none;
- }
- .modal-content {
- background: white;
- border-radius: 16px;
- width: 100%;
- max-width: 360px;
- overflow: hidden;
- }
- .modal-header {
- padding: 16px 20px;
- border-bottom: 1px solid #f0f0f0;
- font-size: 16px;
- font-weight: 600;
- color: #333;
- text-align: center;
- }
- .modal-body {
- padding: 20px;
- }
- .modal-footer {
- padding: 16px 20px;
- border-top: 1px solid #f0f0f0;
- display: flex;
- gap: 12px;
- }
- .modal-footer button {
- flex: 1;
- padding: 12px;
- border-radius: 8px;
- font-size: 15px;
- font-weight: 500;
- cursor: pointer;
- transition: all 0.2s;
- }
- .modal-footer .btn-cancel {
- background: #f5f5f5;
- color: #666;
- border: none;
- }
- .modal-footer .btn-confirm {
- background: #ef4444;
- color: white;
- border: none;
- }
- /* 添加联系人模态框 */
- .add-contact-modal .modal-body {
- padding: 16px 20px 20px;
- }
- .add-contact-modal .form-group {
- margin-bottom: 12px;
- }
- .add-contact-modal .form-group:last-child {
- margin-bottom: 0;
- }
- /* 处理记录样式 */
- .record-item {
- display: flex;
- padding: 12px 0;
- border-bottom: 1px solid #f5f5f5;
- }
- .record-item:last-child {
- border-bottom: none;
- }
- .record-item .record-time {
- width: 70px;
- flex-shrink: 0;
- font-size: 11px;
- color: #999;
- }
- .record-item .record-dot {
- width: 8px;
- height: 8px;
- border-radius: 50%;
- background: #d1d5db;
- margin: 0 10px;
- margin-top: 4px;
- flex-shrink: 0;
- }
- .record-item .record-dot.latest {
- background: #3b82f6;
- }
- .record-item .record-content {
- flex: 1;
- }
- .record-item .record-action {
- font-size: 13px;
- color: #333;
- }
- .record-item .record-operator {
- font-size: 11px;
- color: #999;
- margin-top: 2px;
- }
- /* 调度端额外样式 */
- #dispatchApp .home-stats-container {
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- gap: 12px;
- }
- #dispatchApp .home-stats-container .stat-card {
- background: white;
- border-radius: 12px;
- padding: 16px 12px;
- text-align: center;
- cursor: pointer;
- transition: transform 0.2s;
- }
- #dispatchApp .home-stats-container .stat-card:active {
- transform: scale(0.98);
- }
- .stat-icon {
- width: 40px;
- height: 40px;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- margin: 0 auto 8px;
- }
- .stat-value {
- font-size: 24px;
- font-weight: bold;
- color: #1f2937;
- }
- .stat-label {
- font-size: 12px;
- color: #6b7280;
- margin-top: 4px;
- }
- #dispatchApp .resource-card {
- background: white;
- border-radius: 12px;
- padding: 16px;
- cursor: pointer;
- transition: transform 0.2s;
- }
- #dispatchApp .resource-card:active {
- transform: scale(0.98);
- }
- #dispatchApp .quick-item {
- background: white;
- border-radius: 12px;
- padding: 16px;
- display: flex;
- align-items: center;
- cursor: pointer;
- }
- #dispatchApp .quick-item:active {
- background: #f9fafb;
- }
- /* ==================== 调度端样式 ==================== */
- * {
- -webkit-tap-highlight-color: transparent;
- box-sizing: border-box;
- }
- body {
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
- background: #f5f5f5;
- min-height: 100vh;
- margin: 0;
- padding: 0;
- }
- .app-container {
- max-width: 430px;
- margin: 0 auto;
- min-height: 100vh;
- background: #f5f5f5;
- position: relative;
- }
- .page {
- display: none;
- min-height: 100vh;
- padding-bottom: 70px;
- }
- .page.active {
- display: block;
- }
- .bottom-nav {
- position: fixed;
- bottom: 0;
- left: 50%;
- transform: translateX(-50%);
- width: 100%;
- max-width: 430px;
- background: white;
- box-shadow: 0 -2px 10px rgba(0,0,0,0.08);
- z-index: 100;
- }
- .nav-item.active {
- color: #3b82f6;
- }
- .nav-item.active .nav-icon {
- background: #eff6ff;
- }
- .card {
- background: white;
- border-radius: 12px;
- box-shadow: 0 2px 8px rgba(0,0,0,0.06);
- }
- .role-tab {
- transition: all 0.3s;
- }
- .role-tab.active {
- background: #3b82f6;
- color: white;
- border-color: #3b82f6;
- }
- .login-btn {
- background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
- transition: all 0.3s;
- }
- .login-btn:active {
- transform: scale(0.98);
- opacity: 0.9;
- }
- .btn {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- padding: 10px 20px;
- border-radius: 8px;
- font-size: 14px;
- font-weight: 500;
- cursor: pointer;
- transition: all 0.2s;
- }
- .btn:active {
- transform: scale(0.98);
- }
- .btn-primary {
- background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
- color: white;
- }
- .btn-outline {
- background: white;
- border: 1px solid #e5e7eb;
- color: #666;
- }
- .btn-success {
- background: linear-gradient(135deg, #10b981 0%, #059669 100%);
- color: white;
- }
- .btn-danger {
- background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
- color: white;
- }
- .add-btn {
- background: linear-gradient(135deg, #10b981 0%, #059669 100%);
- color: white;
- text-shadow: 0 1px 2px rgba(0,0,0,0.1);
- }
- .add-btn:active {
- opacity: 0.9;
- }
- #toast {
- position: fixed;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- background: rgba(0,0,0,0.8);
- color: white;
- padding: 16px 32px;
- border-radius: 8px;
- z-index: 9999;
- font-size: 14px;
- }
- #toast.hidden {
- display: none;
- }
- .page.hide-nav {
- padding-bottom: 0;
- }
- .page.hide-nav .bottom-nav {
- display: none;
- }
- .tag {
- display: inline-block;
- padding: 2px 8px;
- border-radius: 4px;
- font-size: 12px;
- font-weight: 500;
- }
- .tag-blue {
- background: #e6f0ff;
- color: #2563eb;
- }
- .tag-orange {
- background: #fff7ed;
- color: #ea580c;
- }
- .tag-green {
- background: #e6f7f1;
- color: #059669;
- }
- .tag-red {
- background: #fef2f2;
- color: #dc2626;
- }
- .tag-yellow {
- background: #fef9c3;
- color: #a16207;
- }
- .form-group {
- margin-bottom: 16px;
- }
- .form-label {
- display: block;
- font-size: 14px;
- color: #666;
- margin-bottom: 8px;
- }
- .form-select {
- width: 100%;
- padding: 12px 16px;
- border: 1px solid #e5e7eb;
- border-radius: 8px;
- font-size: 14px;
- color: #333;
- background: #fff;
- appearance: none;
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23999999' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
- background-repeat: no-repeat;
- background-position: right 16px center;
- }
- .form-select:focus {
- outline: none;
- border-color: #3b82f6;
- }
- .form-textarea {
- width: 100%;
- padding: 12px 16px;
- border: 1px solid #e5e7eb;
- border-radius: 8px;
- font-size: 14px;
- color: #333;
- background: #fff;
- resize: vertical;
- min-height: 80px;
- }
- .form-textarea:focus {
- outline: none;
- border-color: #3b82f6;
- }
- #dispatchApp .calendar-container {
- background: white;
- border-radius: 12px;
- padding: 16px;
- margin: 16px;
- box-shadow: 0 2px 8px rgba(0,0,0,0.06);
- }
- #dispatchApp .calendar-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 16px;
- }
- #dispatchApp .calendar-title {
- font-size: 16px;
- font-weight: 600;
- color: #333;
- }
- #dispatchApp .calendar-nav {
- display: flex;
- gap: 8px;
- }
- #dispatchApp .calendar-nav button {
- width: 32px;
- height: 32px;
- border-radius: 8px;
- border: none;
- background: #f5f5f5;
- color: #666;
- cursor: pointer;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: all 0.2s;
- }
- #dispatchApp .calendar-nav button:active {
- background: #e5e7eb;
- }
- #dispatchApp .calendar-weekdays {
- display: grid;
- grid-template-columns: repeat(7, 1fr);
- gap: 4px;
- margin-bottom: 8px;
- }
- #dispatchApp .calendar-weekday {
- text-align: center;
- font-size: 12px;
- color: #999;
- padding: 8px 0;
- }
- #dispatchApp .calendar-days {
- display: grid;
- grid-template-columns: repeat(7, 1fr);
- gap: 4px;
- }
- #dispatchApp .calendar-day {
- height: 40px;
- min-height: 40px;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- border-radius: 8px;
- cursor: pointer;
- transition: all 0.2s;
- position: relative;
- font-size: 14px;
- color: #333;
- padding: 4px;
- }
- #dispatchApp .calendar-day:active {
- background: #f0f0f0;
- }
- #dispatchApp .calendar-day.other-month {
- color: #ccc;
- }
- #dispatchApp .calendar-day.today {
- background: #eff6ff;
- color: #3b82f6;
- font-weight: 600;
- }
- #dispatchApp .calendar-day.today .day-number {
- background: #3b82f6;
- color: white;
- border-radius: 50%;
- width: 28px;
- height: 28px;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- #dispatchApp .calendar-day.selected {
- background: #3b82f6;
- color: white;
- }
- #dispatchApp .calendar-day.selected .day-dots {
- display: none;
- }
- .day-dots {
- display: flex;
- gap: 2px;
- justify-content: center;
- height: 6px;
- margin-top: 2px;
- }
- .day-dot {
- width: 6px;
- height: 6px;
- border-radius: 50%;
- flex-shrink: 0;
- }
- .day-dot.monthly {
- background: #3b82f6;
- }
- .day-dot.emergency {
- background: #f97316;
- }
- #dispatchApp .schedule-card {
- background: white;
- border-radius: 12px;
- padding: 16px;
- margin-bottom: 12px;
- box-shadow: 0 2px 8px rgba(0,0,0,0.06);
- display: flex;
- align-items: center;
- gap: 12px;
- }
- #dispatchApp .schedule-card:active {
- transform: scale(0.98);
- }
- .schedule-icon {
- width: 48px;
- height: 48px;
- border-radius: 12px;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 20px;
- flex-shrink: 0;
- }
- .schedule-icon.monthly {
- background: #eff6ff;
- color: #3b82f6;
- }
- .schedule-icon.emergency {
- background: #fff7ed;
- color: #f97316;
- }
- .schedule-info {
- flex: 1;
- min-width: 0;
- }
- .schedule-team {
- font-size: 15px;
- font-weight: 600;
- color: #333;
- margin-bottom: 4px;
- }
- .schedule-vehicle {
- font-size: 13px;
- color: #666;
- display: flex;
- align-items: center;
- gap: 6px;
- }
- .schedule-vehicle i {
- color: #999;
- width: 16px;
- }
- .schedule-time {
- font-size: 12px;
- color: #999;
- margin-top: 4px;
- }
- /* 资源卡片可点击 */
- #dispatchApp .resource-card {
- background: white;
- border-radius: 12px;
- padding: 16px;
- flex: 1;
- text-align: center;
- box-shadow: 0 2px 8px rgba(0,0,0,0.06);
- cursor: pointer;
- transition: all 0.2s;
- }
- #dispatchApp .resource-card:active {
- transform: scale(0.98);
- opacity: 0.9;
- }
- #dispatchApp .resource-card:nth-child(1) {
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- color: white;
- }
- #dispatchApp .resource-card:nth-child(2) {
- background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
- color: white;
- }
- #dispatchApp .resource-card:nth-child(3) {
- background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
- color: white;
- }
- .resource-icon {
- width: 40px;
- height: 40px;
- background: rgba(255,255,255,0.2);
- border-radius: 10px;
- display: flex;
- align-items: center;
- justify-content: center;
- margin: 0 auto 8px;
- font-size: 18px;
- }
- .resource-value {
- font-size: 24px;
- font-weight: 700;
- }
- .resource-label {
- font-size: 12px;
- opacity: 0.9;
- }
- .modal-overlay {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(0,0,0,0.5);
- z-index: 1000;
- display: none;
- align-items: flex-end;
- justify-content: center;
- }
- .modal-overlay.active {
- display: flex;
- }
- .modal-content {
- background: white;
- border-radius: 16px 16px 0 0;
- width: 100%;
- max-width: 430px;
- max-height: 80vh;
- overflow-y: auto;
- animation: slideUp 0.3s ease;
- }
- @keyframes slideUp {
- from {
- transform: translateY(100%);
- }
- to {
- transform: translateY(0);
- }
- }
- .modal-header {
- padding: 16px 20px;
- border-bottom: 1px solid #f0f0f0;
- display: flex;
- align-items: center;
- justify-content: space-between;
- }
- .modal-title {
- font-size: 16px;
- font-weight: 600;
- color: #333;
- }
- .modal-close {
- width: 32px;
- height: 32px;
- border-radius: 50%;
- border: none;
- background: #f5f5f5;
- color: #666;
- cursor: pointer;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .modal-body {
- padding: 20px;
- }
- .modal-footer {
- padding: 16px 20px;
- border-top: 1px solid #f0f0f0;
- display: flex;
- gap: 12px;
- }
- .modal-footer button {
- flex: 1;
- }
- .type-selector {
- display: flex;
- gap: 12px;
- }
- .type-option {
- flex: 1;
- padding: 12px;
- border: 2px solid #e5e7eb;
- border-radius: 8px;
- text-align: center;
- cursor: pointer;
- transition: all 0.2s;
- }
- .type-option:active {
- transform: scale(0.98);
- }
- .type-option.selected {
- border-color: #3b82f6;
- background: #eff6ff;
- }
- .type-option.selected.emergency {
- border-color: #f97316;
- background: #fff7ed;
- }
- .type-option i {
- font-size: 20px;
- margin-bottom: 4px;
- }
- .type-option.monthly i {
- color: #3b82f6;
- }
- .type-option.emergency i {
- color: #f97316;
- }
- .type-option span {
- display: block;
- font-size: 13px;
- color: #666;
- margin-top: 4px;
- }
- .type-option.selected span {
- color: #333;
- font-weight: 500;
- }
- .empty-state {
- text-align: center;
- padding: 40px 20px;
- }
- .empty-state i {
- font-size: 48px;
- color: #d1d5db;
- margin-bottom: 16px;
- }
- .empty-state p {
- color: #9ca3af;
- font-size: 14px;
- }
- /* 统计卡片样式 */
- #dispatchApp .stat-card {
- background: white;
- border-radius: 12px;
- padding: 16px;
- text-align: center;
- box-shadow: 0 2px 8px rgba(0,0,0,0.06);
- display: flex;
- flex-direction: column;
- align-items: center;
- cursor: pointer;
- transition: all 0.2s;
- }
- #dispatchApp .stat-card:active {
- transform: scale(0.98);
- opacity: 0.9;
- }
- #dispatchApp .stat-card .stat-icon {
- width: 44px;
- height: 44px;
- border-radius: 12px;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-bottom: 8px;
- font-size: 18px;
- }
- #dispatchApp .stat-card .stat-value {
- font-size: 28px;
- font-weight: 700;
- color: #333;
- line-height: 1.2;
- }
- #dispatchApp .stat-card .stat-label {
- font-size: 12px;
- color: #666;
- margin-top: 4px;
- }
- /* 首页统计区域样式 */
- #dispatchApp .home-stats-container {
- display: flex;
- gap: 12px;
- }
- #dispatchApp .home-stats-container .stat-card {
- flex: 1;
- min-width: 0;
- }
- /* 快捷入口样式 */
- #dispatchApp .quick-entry {
- background: white;
- border-radius: 12px;
- padding: 16px;
- display: flex;
- justify-content: space-around;
- box-shadow: 0 2px 8px rgba(0,0,0,0.06);
- }
- #dispatchApp .quick-item {
- display: flex;
- flex-direction: column;
- align-items: center;
- cursor: pointer;
- }
- #dispatchApp .quick-item:active {
- transform: scale(0.95);
- }
- #dispatchApp .quick-item .quick-icon {
- width: 48px;
- height: 48px;
- border-radius: 12px;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 20px;
- margin-bottom: 8px;
- }
- #dispatchApp .quick-item .quick-text {
- font-size: 12px;
- color: #666;
- }
- /* 任务卡片样式 */
- #dispatchApp .task-card {
- background: white;
- border-radius: 12px;
- padding: 16px;
- margin-bottom: 12px;
- box-shadow: 0 2px 8px rgba(0,0,0,0.06);
- }
- #dispatchApp .task-card:active {
- transform: scale(0.98);
- }
- #dispatchApp .task-card .task-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 12px;
- }
- #dispatchApp .task-card .task-title {
- font-size: 15px;
- font-weight: 600;
- color: #333;
- }
- #dispatchApp .task-card .task-info {
- font-size: 13px;
- color: #666;
- margin-bottom: 8px;
- }
- #dispatchApp .task-card .task-actions {
- display: flex;
- gap: 8px;
- margin-top: 12px;
- }
- #dispatchApp .task-card .task-actions button {
- flex: 1;
- padding: 8px 12px;
- border-radius: 6px;
- font-size: 13px;
- border: none;
- cursor: pointer;
- }
- /* 待审核徽章 */
- #dispatchApp .pending-badge {
- position: absolute;
- top: -4px;
- right: -4px;
- width: 18px;
- height: 18px;
- background: #ef4444;
- color: white;
- border-radius: 50%;
- font-size: 10px;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- /* 发布任务页样式 */
- #dispatchApp .contact-list-item {
- background: #f9fafb;
- border-radius: 8px;
- padding: 10px;
- margin-bottom: 8px;
- display: flex;
- align-items: center;
- gap: 10px;
- }
- #dispatchApp .contact-list-item .delete-btn {
- width: 24px;
- height: 24px;
- background: #fee2e2;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- cursor: pointer;
- color: #ef4444;
- flex-shrink: 0;
- }
- #dispatchApp .contact-list-item .delete-btn:hover {
- background: #fecaca;
- }
- #dispatchApp .add-item-btn {
- width: 100%;
- padding: 10px;
- border: 1px dashed #d1d5db;
- border-radius: 8px;
- background: transparent;
- color: #6b7280;
- font-size: 14px;
- cursor: pointer;
- transition: all 0.2s;
- }
- #dispatchApp .add-item-btn:hover {
- border-color: #3b82f6;
- color: #3b82f6;
- background: #eff6ff;
- }
- #dispatchApp .auto-filled-label {
- font-size: 12px;
- color: #10b981;
- margin-bottom: 4px;
- }
- #dispatchApp .datetime-input {
- display: flex;
- gap: 10px;
- }
- #dispatchApp .datetime-input .form-input {
- flex: 1;
- }
- #dispatchApp .auto-filled {
- background: #ecfdf5 !important;
- border-color: #10b981 !important;
- }
- /* ==================== 施工端样式 ==================== */
- /* 施工流程步骤卡片样式 */
- #constructionApp .step-number {
- flex-shrink: 0;
- }
- #constructionApp .upload-area-mini {
- transition: all 0.2s;
- }
- #constructionApp .upload-area-mini:active {
- border-color: #10b981;
- background: #f0fdf4;
- }
- #constructionApp .nav-item.active {
- color: #3b82f6;
- }
- #constructionApp .nav-item.active .nav-icon {
- background: #eff6ff;
- }
- #constructionApp .role-tab.active {
- background: #3b82f6;
- border-color: #3b82f6;
- }
- #constructionApp .login-btn {
- background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
- }
- /* 施工端统计卡片样式 */
- #constructionApp .stat-card {
- background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
- }
- #constructionApp .stat-card:nth-child(2) {
- background: linear-gradient(135deg, #60a5fa 0%, #3b82f6 100%);
- }
- #constructionApp .stat-card:nth-child(3) {
- background: linear-gradient(135deg, #93c5fd 0%, #60a5fa 100%);
- }
- /* 施工端任务卡片 */
- #constructionApp .task-card {
- background: white;
- border-radius: 12px;
- padding: 16px;
- margin-bottom: 12px;
- box-shadow: 0 2px 8px rgba(0,0,0,0.06);
- }
- #constructionApp .task-card:active {
- transform: scale(0.98);
- }
- /* 施工端流程进度条 */
- #constructionApp .flow-progress {
- display: flex;
- justify-content: space-between;
- position: relative;
- padding: 0 10px;
- }
- #constructionApp .flow-progress::before {
- content: '';
- position: absolute;
- top: 15px;
- left: 30px;
- right: 30px;
- height: 3px;
- background: #e5e7eb;
- }
- #constructionApp .flow-step {
- display: flex;
- flex-direction: column;
- align-items: center;
- z-index: 1;
- position: relative;
- }
- #constructionApp .flow-step .step-icon {
- width: 30px;
- height: 30px;
- border-radius: 50%;
- background: #e5e7eb;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-bottom: 8px;
- }
- #constructionApp .flow-step.completed .step-icon {
- background: #3b82f6;
- color: white;
- }
- #constructionApp .flow-step.active .step-icon {
- background: #3b82f6;
- color: white;
- box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.3);
- }
- #constructionApp .flow-step .step-label {
- font-size: 10px;
- color: #999;
- text-align: center;
- }
- #constructionApp .flow-step.completed .step-label,
- #constructionApp .flow-step.active .step-label {
- color: #10b981;
- font-weight: 500;
- }
- /* 施工端按钮 */
- #constructionApp .btn-primary {
- background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
- color: white;
- }
- #constructionApp .btn-outline {
- background: white;
- border: 1px solid #e5e7eb;
- color: #666;
- }
- #constructionApp .btn-success {
- background: linear-gradient(135deg, #10b981 0%, #059669 100%);
- color: white;
- }
- #constructionApp .btn-danger {
- background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
- color: white;
- }
- /* 施工端模态框样式 */
- #constructionApp .modal-overlay {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(0,0,0,0.5);
- z-index: 1000;
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 20px;
- }
- #constructionApp .modal-overlay.hidden {
- display: none;
- }
- #constructionApp .modal-content {
- background: white;
- border-radius: 16px;
- width: 100%;
- max-width: 360px;
- overflow: hidden;
- }
- #constructionApp .modal-header {
- padding: 16px 20px;
- border-bottom: 1px solid #f0f0f0;
- font-size: 16px;
- font-weight: 600;
- color: #333;
- display: flex;
- justify-content: space-between;
- align-items: center;
- }
- #constructionApp .modal-body {
- padding: 20px;
- }
- #constructionApp .modal-footer {
- padding: 16px 20px;
- border-top: 1px solid #f0f0f0;
- display: flex;
- gap: 12px;
- }
- #constructionApp .modal-footer button {
- flex: 1;
- padding: 12px;
- border-radius: 8px;
- font-size: 15px;
- font-weight: 500;
- cursor: pointer;
- transition: all 0.2s;
- border: none;
- }
- #constructionApp .modal-close {
- background: none;
- border: none;
- color: #999;
- font-size: 18px;
- cursor: pointer;
- padding: 4px;
- }
- #constructionApp .modal-close:hover {
- color: #666;
- }
- /* 施工端标签 */
- #constructionApp .tag-green {
- background: #ecfdf5;
- color: #10b981;
- }
- #constructionApp .tag-blue {
- background: #eff6ff;
- color: #3b82f6;
- }
- #constructionApp .tag-orange {
- background: #fff7ed;
- color: #ea580c;
- }
- /* 施工端检查项卡片 */
- #constructionApp .check-item {
- background: white;
- border-radius: 12px;
- padding: 16px;
- margin-bottom: 12px;
- box-shadow: 0 2px 8px rgba(0,0,0,0.06);
- }
- #constructionApp .check-item .check-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 12px;
- }
- #constructionApp .check-item .check-title {
- font-size: 15px;
- font-weight: 600;
- color: #333;
- }
- #constructionApp .check-item .check-status {
- font-size: 12px;
- color: #999;
- }
- #constructionApp .check-item .check-status.completed {
- color: #10b981;
- }
- #constructionApp .upload-area {
- border: 2px dashed #e5e7eb;
- border-radius: 8px;
- padding: 20px;
- text-align: center;
- cursor: pointer;
- }
- #constructionApp .upload-area:active {
- border-color: #10b981;
- background: #ecfdf5;
- }
- #constructionApp .upload-area i {
- font-size: 24px;
- color: #d1d5db;
- margin-bottom: 8px;
- }
- #constructionApp .upload-area p {
- font-size: 13px;
- color: #999;
- }
- /* 容器控制 */
- #loginContainer {
- max-width: 430px;
- margin: 0 auto;
- height: 100vh;
- background: #f5f5f5;
- position: relative;
- }
- #loginContainer .page {
- height: 100vh;
- padding-bottom: 0;
- }
- #salesApp, #dispatchApp, #constructionApp {
- display: none;
- }
- /* 施工流程进度条样式 */
- .construction-flow-bar {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 16px 8px;
- background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);
- border-radius: 12px;
- margin-bottom: 16px;
- position: relative;
- overflow: hidden;
- }
- .construction-flow-bar::before {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: repeating-linear-gradient(
- 90deg,
- transparent,
- transparent 10px,
- rgba(16, 185, 129, 0.03) 10px,
- rgba(16, 185, 129, 0.03) 20px
- );
- }
- .construction-flow-step {
- display: flex;
- flex-direction: column;
- align-items: center;
- position: relative;
- z-index: 1;
- flex: 1;
- }
- .construction-flow-step .step-dot {
- width: 28px;
- height: 28px;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 12px;
- margin-bottom: 6px;
- transition: all 0.3s;
- }
- .construction-flow-step .step-dot.pending {
- background: #e5e7eb;
- color: #9ca3af;
- }
- .construction-flow-step .step-dot.completed {
- background: #10b981;
- color: white;
- }
- .construction-flow-step .step-dot.active {
- background: #059669;
- color: white;
- box-shadow: 0 0 0 4px rgba(16, 185, 129, 0.2);
- animation: pulse 2s infinite;
- }
- @keyframes pulse {
- 0%, 100% { transform: scale(1); }
- 50% { transform: scale(1.1); }
- }
- .construction-flow-step .step-name {
- font-size: 11px;
- color: #9ca3af;
- text-align: center;
- }
- .construction-flow-step.completed .step-name,
- .construction-flow-step.active .step-name {
- color: #059669;
- font-weight: 500;
- }
- .construction-flow-line {
- position: absolute;
- top: 30px;
- left: 10%;
- right: 10%;
- height: 2px;
- background: #e5e7eb;
- z-index: 0;
- }
- .construction-flow-line-fill {
- position: absolute;
- top: 0;
- left: 0;
- height: 100%;
- background: #10b981;
- transition: width 0.5s ease;
- }
- /* 拍照上传区域样式 */
- .photo-upload-grid {
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- gap: 8px;
- margin-bottom: 12px;
- }
- .photo-upload-item {
- aspect-ratio: 1;
- background: #f9fafb;
- border-radius: 8px;
- border: 2px dashed #d1d5db;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- cursor: pointer;
- transition: all 0.2s;
- overflow: hidden;
- position: relative;
- }
- .photo-upload-item:active {
- transform: scale(0.95);
- border-color: #10b981;
- }
- .photo-upload-item i {
- font-size: 24px;
- color: #9ca3af;
- margin-bottom: 4px;
- }
- .photo-upload-item span {
- font-size: 11px;
- color: #9ca3af;
- }
- .photo-upload-item.uploaded {
- border-style: solid;
- border-color: #10b981;
- background: #f0fdf4;
- }
- .photo-upload-item.uploaded i {
- color: #10b981;
- }
- .photo-upload-item .delete-photo {
- position: absolute;
- top: 4px;
- right: 4px;
- width: 20px;
- height: 20px;
- background: rgba(0,0,0,0.5);
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- color: white;
- font-size: 10px;
- }
- /* V13 施工端新增样式 */
- /* 大上传区域 */
- .upload-area-large {
- border: 2px dashed #d1d5db;
- border-radius: 12px;
- padding: 32px 20px;
- text-align: center;
- cursor: pointer;
- transition: all 0.2s;
- background: #fafafa;
- }
- .upload-area-large:active {
- transform: scale(0.98);
- border-color: #10b981;
- background: #f0fdf4;
- }
- /* 操作区域切换 */
- .action-content {
- display: block;
- }
- .action-content.hidden {
- display: none;
- }
- /* 可折叠区块 */
- .detail-section-title {
- padding: 14px 16px;
- background: white;
- cursor: pointer;
- user-select: none;
- }
- .detail-section-title .toggle-icon {
- transition: transform 0.2s;
- }
- .detail-section-title.collapsed .toggle-icon {
- transform: rotate(-90deg);
- }
- .section-content {
- transition: all 0.3s;
- }
- /* 状态标签 */
- .status-tag {
- display: inline-block;
- padding: 3px 10px;
- border-radius: 4px;
- font-size: 12px;
- font-weight: 500;
- }
- .status-scheduling {
- background: #fff7ed;
- color: #ea580c;
- }
- /* 进度条步骤名对齐 */
- .construction-flow-step .step-name {
- font-size: 10px !important;
- white-space: nowrap;
- }
- /* 上传区域样式 */
- #constructionApp .upload-area-normal {
- border: 2px dashed #d1d5db;
- border-radius: 12px;
- padding: 20px;
- text-align: center;
- cursor: pointer;
- transition: all 0.2s;
- }
- #constructionApp .upload-area-normal:active {
- border-color: #10b981;
- background: #f0fdf4;
- }
- /* SOP新增样式 - 标签选择器 */
- .tag-selector {
- display: flex;
- flex-wrap: wrap;
- gap: 8px;
- padding: 8px;
- background: #f9fafb;
- border-radius: 8px;
- }
- .tag-option {
- padding: 6px 12px;
- border: 1px solid #e5e7eb;
- border-radius: 16px;
- font-size: 13px;
- cursor: pointer;
- transition: all 0.2s;
- background: white;
- }
- .tag-option.selected {
- background: #3b82f6;
- color: white;
- border-color: #3b82f6;
- }
- .tag-option:active {
- transform: scale(0.95);
- }
- /* SOP新增样式 - 条件显示 */
- .conditional-show {
- display: none;
- }
- .conditional-show.visible {
- display: block;
- }
- /* SOP新增样式 - 开关 */
- .toggle-switch {
- position: relative;
- width: 44px;
- height: 24px;
- background: #ccc;
- border-radius: 12px;
- cursor: pointer;
- transition: background 0.3s;
- }
- .toggle-switch.active {
- background: #10b981;
- }
- .toggle-switch::after {
- content: '';
- position: absolute;
- width: 20px;
- height: 20px;
- background: white;
- border-radius: 50%;
- top: 2px;
- left: 2px;
- transition: transform 0.3s;
- }
- .toggle-switch.active::after {
- transform: translateX(20px);
- }
- /* SOP新增样式 - 勾选列表 */
- .checklist-item {
- display: flex;
- align-items: center;
- padding: 8px 0;
- border-bottom: 1px solid #f1f5f9;
- }
- .checklist-item:last-child {
- border-bottom: none;
- }
- .checklist-checkbox {
- width: 20px;
- height: 20px;
- border: 2px solid #d1d5db;
- border-radius: 4px;
- margin-right: 10px;
- cursor: pointer;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: all 0.2s;
- }
- .checklist-checkbox.checked {
- background: #10b981;
- border-color: #10b981;
- color: white;
- }
- /* SOP新增样式 - 照片分组 */
- .photo-group {
- margin-bottom: 12px;
- }
- .photo-group-title {
- font-size: 12px;
- color: #64748b;
- margin-bottom: 6px;
- font-weight: 500;
- }
- /* SOP新增样式 - 数据卡片扩展 */
- .detail-extended-row {
- display: flex;
- justify-content: space-between;
- padding: 10px 0;
- border-bottom: 1px solid #f1f5f9;
- }
- .detail-extended-row:last-child {
- border-bottom: none;
- }
- /* SOP新增样式 - 车辆/人员详情扩展 */
- .info-expansion {
- background: #f8fafc;
- border-radius: 8px;
- padding: 12px;
- margin-top: 10px;
- }
- .info-expansion-item {
- display: flex;
- justify-content: space-between;
- padding: 6px 0;
- font-size: 13px;
- }
- .info-expansion-item .label {
- color: #64748b;
- }
- .info-expansion-item .value {
- color: #334155;
- font-weight: 500;
- }
- /* SOP新增样式 - 资质标签 */
- .qualification-tag {
- display: inline-block;
- padding: 2px 8px;
- background: #e0f2fe;
- color: #0369a1;
- border-radius: 4px;
- font-size: 11px;
- margin-right: 4px;
- margin-bottom: 4px;
- }
- </style>
- </head>
- <body>
- <!-- 登录页(独立) -->
- <div id="loginContainer">
- <div id="loginPage" class="page active">
- <div class="min-h-full bg-gradient-to-b from-blue-500 to-blue-600 flex flex-col">
- <!-- Logo区域 -->
- <div class="flex-1 flex flex-col items-center justify-center px-8">
- <div class="w-24 h-24 bg-white rounded-2xl shadow-lg flex items-center justify-center mb-6">
- <i class="fas fa-broom text-blue-500 text-4xl"></i>
- </div>
- <h1 class="text-white text-2xl font-bold mb-2">清道夫系统</h1>
- <p class="text-blue-100 text-sm mb-12">智能清洁管理平台</p>
- <!-- 角色选择 -->
- <div class="w-full bg-white/20 backdrop-blur rounded-xl p-2 mb-8">
- <div class="flex">
- <button class="role-tab active flex-1 py-3 rounded-lg text-sm font-medium border-2 border-transparent" data-role="sales">
- <i class="fas fa-user-tie mr-1"></i>销售
- </button>
- <button class="role-tab flex-1 py-3 rounded-lg text-sm font-medium border-2 border-transparent text-white/80" data-role="dispatch">
- <i class="fas fa-clipboard-list mr-1"></i>调度
- </button>
- <button class="role-tab flex-1 py-3 rounded-lg text-sm font-medium border-2 border-transparent text-white/80" data-role="worker">
- <i class="fas fa-hard-hat mr-1"></i>施工
- </button>
- </div>
- </div>
- <!-- 登录表单 -->
- <div class="w-full space-y-4">
- <div class="bg-white/20 backdrop-blur rounded-xl px-4 py-3 flex items-center">
- <i class="fas fa-user text-white/70 mr-3"></i>
- <input type="text" placeholder="请输入账号" value="sales001" class="bg-transparent text-white placeholder-white/50 outline-none flex-1 text-sm">
- </div>
- <div class="bg-white/20 backdrop-blur rounded-xl px-4 py-3 flex items-center">
- <i class="fas fa-lock text-white/70 mr-3"></i>
- <input type="password" placeholder="请输入密码" value="123456" class="bg-transparent text-white placeholder-white/50 outline-none flex-1 text-sm">
- </div>
- <button id="loginBtn" class="login-btn w-full py-4 rounded-xl text-white font-medium text-lg shadow-lg mt-6">
- 登录
- </button>
- </div>
- </div>
- <!-- 底部信息 -->
- <div class="text-center pb-8">
- <p class="text-white/60 text-xs">v1.0.0 · 清道夫科技</p>
- </div>
- </div>
- </div>
- </div><!-- loginContainer结束 -->
- <!-- 销售端容器 -->
- <div class="app-container" id="salesApp">
- <!-- 销售端页面 -->
- <div id="salesPage" class="page">
- <!-- 顶部区域 -->
- <div class="bg-gradient-to-r from-blue-500 to-blue-600 px-4 pt-8 pb-6">
- <div class="flex items-center justify-between mb-4">
- <div class="flex items-center">
- <div class="w-12 h-12 bg-white rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-user text-blue-500 text-lg"></i>
- </div>
- <div>
- <p class="text-blue-100 text-xs">您好,欢迎回来</p>
- <p class="text-white font-medium">张销售</p>
- </div>
- </div>
- <button class="w-10 h-10 bg-white/20 rounded-full flex items-center justify-center relative" onclick="goToPage('sales_notificationPage')">
- <i class="fas fa-bell text-white"></i>
- <span class="absolute -top-1 -right-1 w-5 h-5 bg-red-500 rounded-full text-white text-xs flex items-center justify-center">3</span>
- </button>
- </div>
- </div>
- <!-- 主内容区域 -->
- <div class="px-4 -mt-4 space-y-4">
- <!-- 快捷入口区块 -->
- <div class="card p-4">
- <div class="grid grid-cols-3 gap-3">
- <!-- 项目库 -->
- <div class="quick-entry-card flex flex-col items-center py-4 px-2 bg-blue-50 rounded-xl cursor-pointer" onclick="goToPage('projectListPage')">
- <div class="w-12 h-12 bg-blue-100 rounded-full flex items-center justify-center mb-2">
- <i class="fas fa-folder-open text-blue-500"></i>
- </div>
- <span class="text-blue-600 text-xs text-center font-medium">项目库</span>
- </div>
- <!-- 客户管理 -->
- <div class="quick-entry-card disabled flex flex-col items-center py-4 px-2 bg-gray-100 rounded-xl">
- <div class="w-12 h-12 bg-gray-200 rounded-full flex items-center justify-center mb-2">
- <i class="fas fa-users text-gray-400"></i>
- </div>
- <span class="text-gray-400 text-xs text-center">客户管理</span>
- </div>
- <!-- 合同管理 -->
- <div class="quick-entry-card disabled flex flex-col items-center py-4 px-2 bg-gray-100 rounded-xl">
- <div class="w-12 h-12 bg-gray-200 rounded-full flex items-center justify-center mb-2">
- <i class="fas fa-file-contract text-gray-400"></i>
- </div>
- <span class="text-gray-400 text-xs text-center">合同管理</span>
- </div>
- </div>
- </div>
- <!-- 数据统计区块 -->
- <div class="card p-4">
- <div class="flex items-center justify-between mb-4">
- <h2 class="font-bold text-gray-800 flex items-center">
- <i class="fas fa-chart-bar text-blue-500 mr-2"></i>
- 数据统计
- </h2>
- </div>
- <div class="grid grid-cols-3 gap-3">
- <div class="stat-card rounded-xl p-3 text-center text-white cursor-pointer" onclick="goToPage('projectListPage')">
- <p class="text-2xl font-bold">12</p>
- <p class="text-xs opacity-80">本月项目</p>
- </div>
- <div class="stat-card rounded-xl p-3 text-center text-white cursor-pointer" onclick="goToPage('taskPage')">
- <p class="text-2xl font-bold">3</p>
- <p class="text-xs opacity-80">待确认</p>
- </div>
- <div class="stat-card rounded-xl p-3 text-center text-white cursor-pointer" onclick="goToPage('taskPage')">
- <p class="text-2xl font-bold">8</p>
- <p class="text-xs opacity-80">进行中</p>
- </div>
- </div>
- <button class="w-full mt-4 py-3 bg-blue-50 text-blue-600 rounded-xl text-sm font-medium flex items-center justify-center cursor-pointer" onclick="goToPage('sales_taskReminderPage')">
- <i class="fas fa-bell mr-2"></i>
- 任务提醒 (2)
- </button>
- </div>
- <!-- 通知公告区块 - 可点击 -->
- <div class="card p-4">
- <div class="flex items-center justify-between mb-4 cursor-pointer" onclick="goToPage('noticeListPage')">
- <h2 class="font-bold text-gray-800 flex items-center">
- <i class="fas fa-bullhorn text-blue-500 mr-2"></i>
- 通知公告
- </h2>
- <span class="text-gray-400 text-xs">更多 <i class="fas fa-chevron-right"></i></span>
- </div>
- <div class="space-y-3">
- <div class="pb-3 border-b border-gray-100 cursor-pointer" onclick="goToPage('noticeDetailPage')">
- <p class="text-gray-800 text-sm mb-1">关于2024年第一季度销售激励方案的通知</p>
- <p class="text-gray-400 text-xs">2024-01-15</p>
- </div>
- <div class="cursor-pointer" onclick="goToPage('noticeDetailPage')">
- <p class="text-gray-800 text-sm mb-1">春节期间服务安排调整公告</p>
- <p class="text-gray-400 text-xs">2024-01-10</p>
- </div>
- </div>
- </div>
- <!-- 行业知识区块 - 可点击 -->
- <div class="card p-4 mb-4">
- <div class="flex items-center justify-between mb-4 cursor-pointer" onclick="goToPage('knowledgeListPage')">
- <h2 class="font-bold text-gray-800 flex items-center">
- <i class="fas fa-book text-blue-500 mr-2"></i>
- 行业知识
- </h2>
- <span class="text-gray-400 text-xs">更多 <i class="fas fa-chevron-right"></i></span>
- </div>
- <div class="space-y-3">
- <div class="flex items-start cursor-pointer" onclick="goToPage('knowledgeDetailPage')">
- <div class="news-img mr-3 flex-shrink-0">
- <i class="fas fa-chart-pie text-blue-400 text-xl"></i>
- </div>
- <div class="flex-1">
- <p class="text-gray-800 text-sm mb-1">2024年清洁行业市场分析报告</p>
- <p class="text-gray-400 text-xs line-clamp-2">全面解读清洁行业发展趋势、市场规模及竞争格局...</p>
- </div>
- </div>
- <div class="flex items-start cursor-pointer" onclick="goToPage('knowledgeDetailPage')">
- <div class="news-img mr-3 flex-shrink-0">
- <i class="fas fa-lightbulb text-yellow-500 text-xl"></i>
- </div>
- <div class="flex-1">
- <p class="text-gray-800 text-sm mb-1">客户开发技巧与话术指南</p>
- <p class="text-gray-400 text-xs line-clamp-2">提升销售业绩的实战技巧,有效沟通方法汇总...</p>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- 底部导航栏 -->
- <div class="bottom-nav">
- <div class="flex justify-around py-2">
- <button class="nav-item active flex flex-col items-center py-1 px-4" onclick="goToPage('salesPage')">
- <div class="nav-icon w-10 h-10 rounded-full flex items-center justify-center mb-1 transition-all">
- <i class="fas fa-home text-lg"></i>
- </div>
- <span class="text-xs">首页</span>
- </button>
- <button class="nav-item flex flex-col items-center py-1 px-4" onclick="goToPage('taskPage')">
- <div class="nav-icon w-10 h-10 rounded-full flex items-center justify-center mb-1 transition-all bg-gray-100">
- <i class="fas fa-tasks text-gray-400 text-lg"></i>
- </div>
- <span class="text-xs text-gray-400">任务</span>
- </button>
- <button class="nav-item flex flex-col items-center py-1 px-4" onclick="goToPage('profilePage')">
- <div class="nav-icon w-10 h-10 rounded-full flex items-center justify-center mb-1 transition-all bg-gray-100">
- <i class="fas fa-user text-gray-400 text-lg"></i>
- </div>
- <span class="text-xs text-gray-400">我的</span>
- </button>
- </div>
- </div>
- </div>
- <!-- 任务页 -->
- <div id="taskPage" class="page">
- <div class="bg-white px-4 pt-8 pb-4 shadow-sm sticky top-0 z-10">
- <div class="flex items-center justify-between">
- <h1 class="text-xl font-bold text-gray-800">我的任务</h1>
- <button class="add-btn px-4 py-2 rounded-lg text-white text-sm flex items-center" onclick="goToPage('publishTaskPage')">
- <i class="fas fa-plus mr-1"></i>
- 发布
- </button>
- </div>
- </div>
- <!-- 筛选标签 -->
- <div class="filter-tabs">
- <button class="filter-tab active" data-status="all" onclick="filterTasks('all')">全部</button>
- <button class="filter-tab" data-status="调度中" onclick="filterTasks('调度中')">调度中</button>
- <button class="filter-tab" data-status="施工中" onclick="filterTasks('施工中')">施工中</button>
- <button class="filter-tab" data-status="已完成" onclick="filterTasks('已完成')">已完成</button>
- <button class="filter-tab" data-status="应急" onclick="filterTasks('应急')">应急</button>
- </div>
- <!-- 任务列表 -->
- <div class="px-4 py-4 space-y-3" id="taskListContainer">
- <!-- 任务卡片1 - 调度中 -->
- <div class="task-card" data-status="调度中" data-id="task001" onclick="goToTaskDetail('task001')">
- <div class="header">
- <div class="flex items-center">
- <span class="status-tag status-scheduling">调度中</span>
- <span class="urgent-tag urgent-normal">普通</span>
- </div>
- <span class="text-gray-400 text-xs">2024-01-20 14:30</span>
- </div>
- <div class="task-name mb-2">积丹白鹭 - 油污管疏通</div>
- <div class="task-info"><i class="fas fa-users"></i>施工班组:班组A</div>
- <div class="task-info"><i class="fas fa-map-marker-alt"></i>位置:积丹白鹭小区地下停车场</div>
- <div class="task-info"><i class="fas fa-clipboard-check"></i>验收:签署验收计量单</div>
- <!-- 底部进度条 -->
- <div class="progress-bar-container">
- <div class="progress-bar-track">
- <div class="progress-bar-fill" style="width: 25%"></div>
- <div class="progress-bar-step completed"></div>
- <div class="progress-bar-step active"></div>
- <div class="progress-bar-step"></div>
- <div class="progress-bar-step"></div>
- </div>
- <div class="progress-bar-labels">
- <span class="active">发布</span>
- <span class="active">调度确认</span>
- <span>施工中</span>
- <span>完成</span>
- </div>
- </div>
- </div>
- <!-- 任务卡片2 - 施工中 -->
- <div class="task-card emergency" data-status="施工中" data-id="task002" onclick="goToTaskDetail('task002')">
- <div class="header">
- <div class="flex items-center">
- <span class="status-tag status-constructing">施工中</span>
- <span class="urgent-tag urgent-high">紧急</span>
- </div>
- <span class="text-gray-400 text-xs">2024-01-20 10:15</span>
- </div>
- <div class="task-name mb-2">富源同坐 - 化粪池清掏</div>
- <div class="task-info"><i class="fas fa-users"></i>施工班组:班组B</div>
- <div class="task-info"><i class="fas fa-map-marker-alt"></i>位置:富源同坐商业广场南门</div>
- <div class="task-info"><i class="fas fa-clipboard-check"></i>验收:累计自动计费</div>
- <!-- 底部进度条 -->
- <div class="progress-bar-container">
- <div class="progress-bar-track">
- <div class="progress-bar-fill" style="width: 58%"></div>
- <div class="progress-bar-step completed"></div>
- <div class="progress-bar-step completed"></div>
- <div class="progress-bar-step active"></div>
- <div class="progress-bar-step"></div>
- </div>
- <div class="progress-bar-labels">
- <span class="active">发布</span>
- <span class="active">调度确认</span>
- <span class="active">施工中</span>
- <span>完成</span>
- </div>
- </div>
- </div>
- <!-- 任务卡片3 - 已完成 -->
- <div class="task-card completed" data-status="已完成" data-id="task003" onclick="goToTaskDetail('task003')">
- <div class="header">
- <div class="flex items-center">
- <span class="status-tag status-completed">已完成</span>
- <span class="urgent-tag urgent-normal">普通</span>
- </div>
- <span class="text-gray-400 text-xs">2024-01-19 16:45</span>
- </div>
- <div class="task-name mb-2">俊发城 - PVC管道维修</div>
- <div class="task-info"><i class="fas fa-users"></i>施工班组:班组C</div>
- <div class="task-info"><i class="fas fa-map-marker-alt"></i>位置:俊发城住宅区3号楼</div>
- <div class="task-info"><i class="fas fa-clipboard-check"></i>验收:签署验收计量单</div>
- <!-- 底部进度条 -->
- <div class="progress-bar-container">
- <div class="progress-bar-track">
- <div class="progress-bar-fill" style="width: 100%"></div>
- <div class="progress-bar-step completed"></div>
- <div class="progress-bar-step completed"></div>
- <div class="progress-bar-step completed"></div>
- <div class="progress-bar-step completed"></div>
- </div>
- <div class="progress-bar-labels">
- <span class="active">发布</span>
- <span class="active">调度确认</span>
- <span class="active">施工中</span>
- <span class="active">完成</span>
- </div>
- </div>
- </div>
- <!-- 任务卡片4 - 应急 -->
- <div class="task-card emergency" data-status="应急" data-id="task004" onclick="goToTaskDetail('task004')">
- <div class="header">
- <div class="flex items-center">
- <span class="status-tag status-emergency">应急</span>
- <span class="urgent-tag urgent-high">紧急</span>
- </div>
- <span class="text-gray-400 text-xs">2024-01-20 08:30</span>
- </div>
- <div class="task-name mb-2">逸安新城A区 - 管道堵塞疏通</div>
- <div class="task-info"><i class="fas fa-users"></i>施工班组:应急班组</div>
- <div class="task-info"><i class="fas fa-map-marker-alt"></i>位置:逸安新城A区地下车库入口</div>
- <div class="task-info"><i class="fas fa-clipboard-check"></i>验收:签署验收计量单</div>
- <!-- 底部进度条 -->
- <div class="progress-bar-container">
- <div class="progress-bar-track">
- <div class="progress-bar-fill" style="width: 58%"></div>
- <div class="progress-bar-step completed"></div>
- <div class="progress-bar-step completed"></div>
- <div class="progress-bar-step active"></div>
- <div class="progress-bar-step"></div>
- </div>
- <div class="progress-bar-labels">
- <span class="active">发布</span>
- <span class="active">调度确认</span>
- <span class="active">施工中</span>
- <span>完成</span>
- </div>
- </div>
- </div>
- <!-- 任务卡片5 - 调度中 -->
- <div class="task-card timeout" data-status="调度中" data-id="task005" onclick="goToTaskDetail('task005')">
- <div class="header">
- <div class="flex items-center">
- <span class="status-tag status-scheduling">调度中</span>
- <span class="urgent-tag urgent-normal">普通</span>
- <span class="urgent-tag urgent-high" style="background: #fef2f2; color: #dc2626;">即将超时</span>
- </div>
- <span class="text-gray-400 text-xs">2024-01-21 09:00</span>
- </div>
- <div class="task-name mb-2">逸安新城B区 - 隔油池清理</div>
- <div class="task-info"><i class="fas fa-users"></i>施工班组:待分配</div>
- <div class="task-info"><i class="fas fa-map-marker-alt"></i>位置:逸安新城B区餐饮一条街</div>
- <div class="task-info"><i class="fas fa-clipboard-check"></i>验收:累计自动计费</div>
- <!-- 底部进度条 -->
- <div class="progress-bar-container">
- <div class="progress-bar-track">
- <div class="progress-bar-fill" style="width: 8%"></div>
- <div class="progress-bar-step completed"></div>
- <div class="progress-bar-step"></div>
- <div class="progress-bar-step"></div>
- <div class="progress-bar-step"></div>
- </div>
- <div class="progress-bar-labels">
- <span class="active">发布</span>
- <span>调度确认</span>
- <span>施工中</span>
- <span>完成</span>
- </div>
- </div>
- </div>
- </div>
- <!-- 空状态 -->
- <div class="empty-state" id="taskEmptyState" style="display: none;">
- <i class="fas fa-clipboard-list"></i>
- <p>暂无符合条件的任务</p>
- </div>
- <div class="bottom-nav">
- <div class="flex justify-around py-2">
- <button class="nav-item flex flex-col items-center py-1 px-4" onclick="goToPage('salesPage')">
- <div class="nav-icon w-10 h-10 rounded-full flex items-center justify-center mb-1 transition-all bg-gray-100">
- <i class="fas fa-home text-gray-400 text-lg"></i>
- </div>
- <span class="text-xs text-gray-400">首页</span>
- </button>
- <button class="nav-item active flex flex-col items-center py-1 px-4" onclick="goToPage('taskPage')">
- <div class="nav-icon w-10 h-10 rounded-full flex items-center justify-center mb-1 transition-all">
- <i class="fas fa-tasks text-lg"></i>
- </div>
- <span class="text-xs">任务</span>
- </button>
- <button class="nav-item flex flex-col items-center py-1 px-4" onclick="goToPage('profilePage')">
- <div class="nav-icon w-10 h-10 rounded-full flex items-center justify-center mb-1 transition-all bg-gray-100">
- <i class="fas fa-user text-gray-400 text-lg"></i>
- </div>
- <span class="text-xs text-gray-400">我的</span>
- </button>
- </div>
- </div>
- </div>
- <!-- 我的页面 -->
- <div id="profilePage" class="page">
- <!-- 顶部用户信息区域 - Kimi风格深蓝色渐变 -->
- <div class="bg-gradient-to-br from-blue-900 to-blue-800 text-white pt-10 pb-6 px-5">
- <div class="flex items-center gap-4">
- <div class="w-14 h-14 bg-white/20 rounded-full flex items-center justify-center text-2xl">
- <i class="fas fa-user"></i>
- </div>
- <div>
- <h2 class="text-lg font-bold">李明</h2>
- <p class="text-blue-200 text-xs">销售部 · 工号 EMP001</p>
- </div>
- </div>
- </div>
- <!-- 功能列表 - 优化间距和内边距 -->
- <div class="px-4 -mt-3 space-y-4 pb-4">
- <!-- 基本信息卡片 -->
- <div class="bg-white rounded-xl p-4 shadow-sm">
- <div class="flex justify-between items-center py-2 border-b border-gray-100 cursor-pointer" onclick="showToast('查看基本信息')">
- <span class="text-gray-500 text-sm"><i class="fas fa-building w-5 text-blue-400"></i>部门</span>
- <span class="text-sm">销售一部</span>
- </div>
- <div class="flex justify-between items-center py-2 border-b border-gray-100">
- <span class="text-gray-500 text-sm"><i class="fas fa-id-badge w-5 text-blue-400"></i>职位</span>
- <span class="text-sm">销售经理</span>
- </div>
- <div class="flex justify-between items-center py-2">
- <span class="text-gray-500 text-sm"><i class="fas fa-phone w-5 text-blue-400"></i>电话</span>
- <span class="text-sm">138****8888</span>
- </div>
- </div>
- <!-- 功能入口卡片 -->
- <div class="bg-white rounded-xl p-4 shadow-sm">
- <div class="flex justify-between items-center py-3 border-b border-gray-100 cursor-pointer" onclick="goToPage('sales_basicInfoPage')">
- <span class="text-sm text-gray-700"><i class="fas fa-user-circle text-gray-400 w-6"></i>基本信息</span>
- <i class="fas fa-chevron-right text-gray-300 text-xs"></i>
- </div>
- <div class="flex justify-between items-center py-3 border-b border-gray-100 cursor-pointer" onclick="goToPage('sales_changePasswordPage')">
- <span class="text-sm text-gray-700"><i class="fas fa-lock text-gray-400 w-6"></i>修改密码</span>
- <i class="fas fa-chevron-right text-gray-300 text-xs"></i>
- </div>
- <div class="flex justify-between items-center py-3 border-b border-gray-100 cursor-pointer" onclick="goToPage('sales_notificationPage')">
- <span class="text-sm text-gray-700"><i class="fas fa-bell text-gray-400 w-6"></i>消息通知</span>
- <div class="flex items-center">
- <span class="w-2 h-2 bg-red-500 rounded-full mr-2"></span>
- <i class="fas fa-chevron-right text-gray-300 text-xs"></i>
- </div>
- </div>
- <div class="flex justify-between items-center py-3 cursor-pointer" onclick="goToPage('sales_helpCenterPage')">
- <span class="text-sm text-gray-700"><i class="fas fa-question-circle text-gray-400 w-6"></i>帮助中心</span>
- <i class="fas fa-chevron-right text-gray-300 text-xs"></i>
- </div>
- </div>
- <!-- 退出登录按钮 -->
- <button class="w-full py-3 mt-4 bg-red-500 text-white rounded-xl font-medium cursor-pointer active:bg-red-600 transition-colors" onclick="backToLogin()">
- 退出登录
- </button>
- </div>
- <!-- 底部导航 -->
- <div class="bottom-nav">
- <div class="flex justify-around py-2">
- <button class="nav-item flex flex-col items-center py-1 px-4" onclick="goToPage('salesPage')">
- <div class="nav-icon w-10 h-10 rounded-full flex items-center justify-center mb-1 transition-all bg-gray-100">
- <i class="fas fa-home text-gray-400 text-lg"></i>
- </div>
- <span class="text-xs text-gray-400">首页</span>
- </button>
- <button class="nav-item flex flex-col items-center py-1 px-4" onclick="goToPage('taskPage')">
- <div class="nav-icon w-10 h-10 rounded-full flex items-center justify-center mb-1 transition-all bg-gray-100">
- <i class="fas fa-tasks text-gray-400 text-lg"></i>
- </div>
- <span class="text-xs text-gray-400">任务</span>
- </button>
- <button class="nav-item active flex flex-col items-center py-1 px-4" onclick="goToPage('profilePage')">
- <div class="nav-icon w-10 h-10 rounded-full flex items-center justify-center mb-1 transition-all">
- <i class="fas fa-user text-lg"></i>
- </div>
- <span class="text-xs">我的</span>
- </button>
- </div>
- </div>
- </div>
- <!-- ========== 基本信息页 ========== -->
- <div id="sales_basicInfoPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToPage('profilePage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">基本信息</h1>
- </div>
- </div>
- <!-- 基本信息内容 -->
- <div class="px-4 py-4">
- <div class="bg-white rounded-xl p-4 shadow-sm">
- <div class="flex items-center justify-between py-3 border-b border-gray-100">
- <span class="text-gray-500 text-sm"><i class="fas fa-user w-5 text-blue-400"></i>姓名</span>
- <span class="text-sm text-gray-800">李明</span>
- </div>
- <div class="flex items-center justify-between py-3 border-b border-gray-100">
- <span class="text-gray-500 text-sm"><i class="fas fa-building w-5 text-blue-400"></i>部门</span>
- <span class="text-sm text-gray-800">销售一部</span>
- </div>
- <div class="flex items-center justify-between py-3 border-b border-gray-100">
- <span class="text-gray-500 text-sm"><i class="fas fa-id-badge w-5 text-blue-400"></i>职位</span>
- <span class="text-sm text-gray-800">销售经理</span>
- </div>
- <div class="flex items-center justify-between py-3 border-b border-gray-100">
- <span class="text-gray-500 text-sm"><i class="fas fa-id-card w-5 text-blue-400"></i>工号</span>
- <span class="text-sm text-gray-800">EMP001</span>
- </div>
- <div class="flex items-center justify-between py-3 border-b border-gray-100">
- <span class="text-gray-500 text-sm"><i class="fas fa-phone w-5 text-blue-400"></i>电话</span>
- <span class="text-sm text-gray-800">138****8888</span>
- </div>
- <div class="flex items-center justify-between py-3 border-b border-gray-100">
- <span class="text-gray-500 text-sm"><i class="fas fa-envelope w-5 text-blue-400"></i>邮箱</span>
- <span class="text-sm text-gray-800">liming@qingdaofu.com</span>
- </div>
- <div class="flex items-center justify-between py-3">
- <span class="text-gray-500 text-sm"><i class="fas fa-calendar w-5 text-blue-400"></i>入职日期</span>
- <span class="text-sm text-gray-800">2021-06-01</span>
- </div>
- </div>
- <div class="mt-4">
- <button class="w-full py-3 bg-blue-500 text-white rounded-xl font-medium" onclick="showToast('编辑功能开发中')">
- <i class="fas fa-edit mr-2"></i>编辑信息
- </button>
- </div>
- </div>
- </div>
- <!-- ========== 修改密码页 ========== -->
- <div id="sales_changePasswordPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToPage('profilePage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">修改密码</h1>
- </div>
- </div>
- <!-- 修改密码表单 -->
- <div class="px-4 py-4">
- <div class="bg-white rounded-xl p-4 shadow-sm">
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>当前密码</label>
- <input type="password" class="form-input" placeholder="请输入当前密码">
- </div>
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>新密码</label>
- <input type="password" class="form-input" placeholder="请输入新密码(6-20位)">
- </div>
- <div class="form-group mb-0">
- <label class="form-label"><span class="text-red-500">*</span>确认新密码</label>
- <input type="password" class="form-input" placeholder="请再次输入新密码">
- </div>
- <div class="mt-4">
- <div class="bg-blue-50 rounded-lg p-3 mb-4">
- <p class="text-blue-600 text-sm"><i class="fas fa-info-circle mr-1"></i>密码要求:</p>
- <ul class="text-gray-500 text-xs mt-2 space-y-1">
- <li>• 长度6-20位</li>
- <li>• 必须包含字母和数字</li>
- <li>• 不能与当前密码相同</li>
- </ul>
- </div>
- <button class="w-full py-3 bg-blue-500 text-white rounded-xl font-medium" onclick="showToast('密码修改成功')">
- 确认修改
- </button>
- </div>
- </div>
- </div>
- </div>
- <!-- ========== 消息通知页 ========== -->
- <div id="sales_notificationPage" class="page">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-4 shadow-sm">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToPage('salesPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">消息通知</h1>
- </div>
- <button class="px-3 py-1.5 text-blue-500 text-sm">全部已读</button>
- </div>
- <!-- 筛选标签 -->
- <div class="flex gap-2 mt-4" id="salesNotificationTabs">
- <button class="sales-notification-tab px-4 py-2 bg-blue-500 text-white rounded-full text-sm" onclick="filterSalesNotifications('all', this)">全部</button>
- <button class="sales-notification-tab px-4 py-2 bg-gray-100 text-gray-600 rounded-full text-sm" onclick="filterSalesNotifications('task', this)">任务通知</button>
- <button class="sales-notification-tab px-4 py-2 bg-gray-100 text-gray-600 rounded-full text-sm" onclick="filterSalesNotifications('system', this)">系统消息</button>
- </div>
- </div>
- <!-- 通知列表 -->
- <div class="px-4 py-4 space-y-3" id="salesNotificationList">
- <div class="notification-item bg-white rounded-xl p-4 shadow-sm border-l-4 border-red-400" data-type="task">
- <div class="flex items-center justify-between mb-2">
- <span class="text-sm font-medium text-gray-800">任务分配通知</span>
- <span class="text-xs text-gray-400">刚刚</span>
- </div>
- <p class="text-sm text-gray-600 mb-2">您有一个新的任务待确认:积丹白鹭小区疏通任务</p>
- <p class="text-xs text-gray-400">任务编号:TASK20240120001</p>
- </div>
- <div class="notification-item bg-white rounded-xl p-4 shadow-sm border-l-4 border-blue-400" data-type="task">
- <div class="flex items-center justify-between mb-2">
- <span class="text-sm font-medium text-gray-800">施工进度更新</span>
- <span class="text-xs text-gray-400">10分钟前</span>
- </div>
- <p class="text-sm text-gray-600 mb-2">俊发城住宅区任务已完成施工</p>
- <p class="text-xs text-gray-400">请及时确认验收</p>
- </div>
- <div class="notification-item bg-white rounded-xl p-4 shadow-sm border-l-4 border-green-400" data-type="task">
- <div class="flex items-center justify-between mb-2">
- <span class="text-sm font-medium text-gray-800">任务验收通过</span>
- <span class="text-xs text-gray-400">2小时前</span>
- </div>
- <p class="text-sm text-gray-600 mb-2">富源同坐商业广场任务已验收通过</p>
- <p class="text-xs text-gray-400">客户评价:满意</p>
- </div>
- <div class="notification-item bg-white rounded-xl p-4 shadow-sm border-l-4 border-gray-400" data-type="system">
- <div class="flex items-center justify-between mb-2">
- <span class="text-sm font-medium text-gray-800">系统公告</span>
- <span class="text-xs text-gray-400">1天前</span>
- </div>
- <p class="text-sm text-gray-600 mb-2">关于2024年第一季度销售激励方案的通知</p>
- <p class="text-xs text-gray-400">点击查看详情</p>
- </div>
- </div>
- </div>
- <!-- ========== 帮助中心页 ========== -->
- <div id="sales_helpCenterPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToPage('profilePage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">帮助中心</h1>
- </div>
- </div>
- <!-- 帮助中心内容 -->
- <div class="px-4 py-4">
- <!-- 常见问题 -->
- <div class="bg-white rounded-xl p-4 mb-4 shadow-sm">
- <h3 class="text-base font-semibold text-gray-800 mb-4"><i class="fas fa-question-circle text-blue-500 mr-2"></i>常见问题</h3>
- <div class="space-y-3">
- <div class="border-b border-gray-100 pb-3">
- <div class="flex justify-between items-center cursor-pointer" onclick="this.nextElementSibling.classList.toggle('hidden'); this.querySelector('i').classList.toggle('fa-chevron-up')">
- <span class="text-sm text-gray-700">如何提交新的任务工单?</span>
- <i class="fas fa-chevron-down text-gray-400 text-xs"></i>
- </div>
- <div class="hidden mt-2 text-gray-500 text-sm">
- 在首页点击右下角的"+"按钮,选择"发布任务",填写项目信息和服务信息后提交即可。
- </div>
- </div>
- <div class="border-b border-gray-100 pb-3">
- <div class="flex justify-between items-center cursor-pointer" onclick="this.nextElementSibling.classList.toggle('hidden'); this.querySelector('i').classList.toggle('fa-chevron-up')">
- <span class="text-sm text-gray-700">如何查看任务进度?</span>
- <i class="fas fa-chevron-down text-gray-400 text-xs"></i>
- </div>
- <div class="hidden mt-2 text-gray-500 text-sm">
- 进入"任务"页面,点击相应任务卡片即可查看任务详情和当前进度。
- </div>
- </div>
- <div class="border-b border-gray-100 pb-3">
- <div class="flex justify-between items-center cursor-pointer" onclick="this.nextElementSibling.classList.toggle('hidden'); this.querySelector('i').classList.toggle('fa-chevron-up')">
- <span class="text-sm text-gray-700">如何修改个人信息?</span>
- <i class="fas fa-chevron-down text-gray-400 text-xs"></i>
- </div>
- <div class="hidden mt-2 text-gray-500 text-sm">
- 进入"我的"页面,点击"基本信息"即可查看和修改个人信息。
- </div>
- </div>
- <div>
- <div class="flex justify-between items-center cursor-pointer" onclick="this.nextElementSibling.classList.toggle('hidden'); this.querySelector('i').classList.toggle('fa-chevron-up')">
- <span class="text-sm text-gray-700">如何联系客服?</span>
- <i class="fas fa-chevron-down text-gray-400 text-xs"></i>
- </div>
- <div class="hidden mt-2 text-gray-500 text-sm">
- 可以在"我的"页面点击"联系客服",或拨打客服热线:400-888-8888。
- </div>
- </div>
- </div>
- </div>
- <!-- 联系客服 -->
- <div class="bg-white rounded-xl p-4 shadow-sm">
- <h3 class="text-base font-semibold text-gray-800 mb-4"><i class="fas fa-headset text-green-500 mr-2"></i>联系客服</h3>
- <div class="flex items-center justify-between py-3 border-b border-gray-100">
- <div class="flex items-center">
- <i class="fas fa-phone text-blue-500 mr-3"></i>
- <span class="text-sm text-gray-700">客服热线</span>
- </div>
- <span class="text-blue-500 text-sm">400-888-8888</span>
- </div>
- <div class="flex items-center justify-between py-3 border-b border-gray-100">
- <div class="flex items-center">
- <i class="fas fa-envelope text-blue-500 mr-3"></i>
- <span class="text-sm text-gray-700">电子邮箱</span>
- </div>
- <span class="text-gray-600 text-sm">service@qingdaofu.com</span>
- </div>
- <div class="flex items-center justify-between py-3">
- <div class="flex items-center">
- <i class="fas fa-clock text-blue-500 mr-3"></i>
- <span class="text-sm text-gray-700">服务时间</span>
- </div>
- <span class="text-gray-600 text-sm">周一至周五 9:00-18:00</span>
- </div>
- </div>
- </div>
- </div>
- <!-- ========== 任务提醒页 ========== -->
- <div id="sales_taskReminderPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToPage('salesPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">任务提醒</h1>
- </div>
- </div>
- <!-- 提醒列表 -->
- <div class="px-4 py-4 space-y-3">
- <div class="bg-white rounded-xl p-4 shadow-sm border-l-4 border-orange-400">
- <div class="flex items-center justify-between mb-2">
- <span class="text-sm font-medium text-gray-800">待确认任务</span>
- <span class="text-xs text-gray-400">2小时前</span>
- </div>
- <p class="text-sm text-gray-600">积丹白鹭小区疏通任务等待您的确认</p>
- <button class="mt-3 px-4 py-2 bg-orange-50 text-orange-600 rounded-lg text-sm" onclick="goToPage('taskPage')">
- 立即处理
- </button>
- </div>
- <div class="bg-white rounded-xl p-4 shadow-sm border-l-4 border-blue-400">
- <div class="flex items-center justify-between mb-2">
- <span class="text-sm font-medium text-gray-800">施工进度更新</span>
- <span class="text-xs text-gray-400">5小时前</span>
- </div>
- <p class="text-sm text-gray-600">俊发城住宅区任务已完成施工</p>
- <button class="mt-3 px-4 py-2 bg-blue-50 text-blue-600 rounded-lg text-sm" onclick="goToPage('taskPage')">
- 查看详情
- </button>
- </div>
- </div>
- </div>
- <!-- 项目库列表页 - 二级页面,隐藏底部导航 -->
- <div id="projectListPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToPage('salesPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">项目库</h1>
- </div>
- <button class="add-btn px-4 py-2 rounded-lg text-white text-sm flex items-center" onclick="goToPage('addProjectPage')">
- <i class="fas fa-plus mr-1"></i>
- 新增
- </button>
- </div>
- </div>
- <!-- 筛选标签 -->
- <div class="filter-tabs">
- <button class="filter-tab active" data-type="all" onclick="filterProjects('all')">全部</button>
- <button class="filter-tab" data-type="包年" onclick="filterProjects('包年')">包年</button>
- <button class="filter-tab" data-type="单次" onclick="filterProjects('单次')">单次</button>
- <button class="filter-tab" data-type="季度" onclick="filterProjects('季度')">季度</button>
- <button class="filter-tab" data-type="月付" onclick="filterProjects('月付')">月付</button>
- </div>
- <!-- 项目列表内容 -->
- <div class="px-4 py-4 space-y-3" id="projectListContainer">
- <!-- 项目卡片1 - 积丹白鹭 -->
- <div class="project-card card p-4 cursor-pointer" data-type="包年" onclick="goToPage('projectDetailPage')">
- <div class="flex justify-between items-start mb-3">
- <h3 class="font-medium text-gray-800">积丹白鹭</h3>
- <span class="bg-blue-100 text-blue-600 text-xs px-2 py-0.5 rounded">包年</span>
- </div>
- <div class="space-y-2 text-sm text-gray-500">
- <p><i class="fas fa-tools w-5 text-gray-400"></i> 油污管、化粪池</p>
- <p><i class="fas fa-map-marker-alt w-5 text-gray-400"></i> 积丹白鹭小区</p>
- <p><i class="fas fa-map-pin w-5 text-gray-400"></i> 服务点数:<span class="text-blue-500 font-medium">3个</span></p>
- <p><i class="fas fa-user w-5 text-gray-400"></i> 陈物业 · 138****8888</p>
- </div>
- </div>
- <!-- 项目卡片2 - 富源同坐 -->
- <div class="project-card card p-4 cursor-pointer" data-type="单次" onclick="goToPage('projectDetailPage')">
- <div class="flex justify-between items-start mb-3">
- <h3 class="font-medium text-gray-800">富源同坐</h3>
- <span class="bg-green-100 text-green-600 text-xs px-2 py-0.5 rounded">单次</span>
- </div>
- <div class="space-y-2 text-sm text-gray-500">
- <p><i class="fas fa-tools w-5 text-gray-400"></i> PVC管道</p>
- <p><i class="fas fa-map-marker-alt w-5 text-gray-400"></i> 富源同坐商业广场</p>
- <p><i class="fas fa-map-pin w-5 text-gray-400"></i> 服务点数:<span class="text-blue-500 font-medium">2个</span></p>
- <p><i class="fas fa-user w-5 text-gray-400"></i> 王主管 · 139****6666</p>
- </div>
- </div>
- <!-- 项目卡片3 - 俊发城 -->
- <div class="project-card card p-4 cursor-pointer" data-type="季度" onclick="goToPage('projectDetailPage')">
- <div class="flex justify-between items-start mb-3">
- <h3 class="font-medium text-gray-800">俊发城</h3>
- <span class="bg-purple-100 text-purple-600 text-xs px-2 py-0.5 rounded">季度</span>
- </div>
- <div class="space-y-2 text-sm text-gray-500">
- <p><i class="fas fa-tools w-5 text-gray-400"></i> 化粪池、直抽直排</p>
- <p><i class="fas fa-map-marker-alt w-5 text-gray-400"></i> 俊发城住宅区</p>
- <p><i class="fas fa-map-pin w-5 text-gray-400"></i> 服务点数:<span class="text-blue-500 font-medium">4个</span></p>
- <p><i class="fas fa-user w-5 text-gray-400"></i> 张经理 · 158****2222</p>
- </div>
- </div>
- <!-- 项目卡片4 - 逸安新城A区 -->
- <div class="project-card card p-4 cursor-pointer" data-type="包年" onclick="goToPage('projectDetailPage')">
- <div class="flex justify-between items-start mb-3">
- <h3 class="font-medium text-gray-800">逸安新城A区</h3>
- <span class="bg-blue-100 text-blue-600 text-xs px-2 py-0.5 rounded">包年</span>
- </div>
- <div class="space-y-2 text-sm text-gray-500">
- <p><i class="fas fa-tools w-5 text-gray-400"></i> 油污管</p>
- <p><i class="fas fa-map-marker-alt w-5 text-gray-400"></i> 逸安新城A区</p>
- <p><i class="fas fa-map-pin w-5 text-gray-400"></i> 服务点数:<span class="text-blue-500 font-medium">2个</span></p>
- <p><i class="fas fa-user w-5 text-gray-400"></i> 李总 · 136****5555</p>
- </div>
- </div>
- <!-- 项目卡片5 - 逸安新城B区 -->
- <div class="project-card card p-4 cursor-pointer" data-type="月付" onclick="goToPage('projectDetailPage')">
- <div class="flex justify-between items-start mb-3">
- <h3 class="font-medium text-gray-800">逸安新城B区</h3>
- <span class="bg-orange-100 text-orange-600 text-xs px-2 py-0.5 rounded">月付</span>
- </div>
- <div class="space-y-2 text-sm text-gray-500">
- <p><i class="fas fa-tools w-5 text-gray-400"></i> PVC、化粪池</p>
- <p><i class="fas fa-map-marker-alt w-5 text-gray-400"></i> 逸安新城B区</p>
- <p><i class="fas fa-map-pin w-5 text-gray-400"></i> 服务点数:<span class="text-blue-500 font-medium">5个</span></p>
- <p><i class="fas fa-user w-5 text-gray-400"></i> 赵师傅 · 158****3333</p>
- </div>
- </div>
- <!-- 空状态 -->
- <div class="empty-state" id="emptyState" style="display: none;">
- <i class="fas fa-inbox"></i>
- <p>暂无符合条件的项目</p>
- </div>
- </div>
- </div>
- <!-- 新增项目页 - 二级页面,隐藏底部导航 -->
- <div id="addProjectPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToPage('projectListPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">新增项目</h1>
- </div>
- </div>
- </div>
- <!-- 表单内容 -->
- <div class="px-4 py-4">
- <div class="card p-4">
- <!-- 项目名称 -->
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>项目名称</label>
- <input type="text" id="projectName" class="form-input" placeholder="请输入项目名称">
- </div>
- <!-- 合作类型 -->
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>合作类型</label>
- <select id="cooperationType" class="form-select">
- <option value="">请选择合作类型</option>
- <option value="包年">包年</option>
- <option value="单次">单次</option>
- <option value="季度">季度</option>
- <option value="月付">月付</option>
- </select>
- </div>
- <!-- 设施类型 -->
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>设施类型</label>
- <select id="facilityType" class="form-select">
- <option value="">请选择设施类型</option>
- <option value="油污管">油污管</option>
- <option value="PVC">PVC</option>
- <option value="化粪池">化粪池</option>
- <option value="直抽直排">直抽直排</option>
- <option value="油污管+化粪池">油污管+化粪池</option>
- <option value="PVC+化粪池">PVC+化粪池</option>
- </select>
- </div>
- <!-- 省/市/区 -->
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>项目地址</label>
- <div class="flex gap-2">
- <select id="province" class="form-select" style="flex:1" onchange="onProvinceChange()">
- <option value="">省</option>
- <option value="云南省">云南省</option>
- <option value="贵州省">贵州省</option>
- <option value="四川省">四川省</option>
- </select>
- <select id="city" class="form-select" style="flex:1" onchange="onCityChange()">
- <option value="">市</option>
- <option value="昆明市">昆明市</option>
- <option value="贵阳市">贵阳市</option>
- <option value="成都市">成都市</option>
- </select>
- <select id="district" class="form-select" style="flex:1">
- <option value="">区</option>
- <option value="五华区">五华区</option>
- <option value="盘龙区">盘龙区</option>
- <option value="官渡区">官渡区</option>
- <option value="西山区">西山区</option>
- </select>
- </div>
- </div>
- <!-- 街道/路名 -->
- <div class="form-group">
- <label class="form-label">街道/路名</label>
- <input type="text" id="streetRoad" class="form-input" placeholder="请输入街道或路名">
- </div>
- <!-- 详细地址 -->
- <div class="form-group">
- <label class="form-label">详细地址</label>
- <input type="text" id="projectAddress" class="form-input" placeholder="请输入详细地址">
- </div>
- <!-- 地图定位 -->
- <div class="form-group">
- <label class="form-label">地图定位</label>
- <div class="bg-gray-100 rounded-xl h-24 flex items-center justify-center border border-gray-200">
- <div class="text-center">
- <i class="fas fa-map-marked-alt text-gray-400 text-2xl mb-1"></i>
- <p class="text-gray-400 text-xs">点击设置定位</p>
- </div>
- </div>
- </div>
- <!-- 主联系人 -->
- <div class="form-group">
- <label class="form-label"><i class="fas fa-user text-blue-500 mr-1"></i>主联系人</label>
- <div class="bg-blue-50 rounded-lg p-3">
- <div class="flex gap-2 mb-2">
- <input type="text" id="primaryContactName" class="form-input" placeholder="姓名" style="flex:1">
- <input type="text" id="primaryContactPosition" class="form-input" placeholder="职务" style="flex:1">
- </div>
- <div class="flex gap-2 mb-2">
- <input type="tel" id="primaryContactPhone" class="form-input" placeholder="手机号" style="flex:1">
- <div class="flex items-center gap-2" style="flex:1">
- <span class="text-sm text-gray-500">已验证</span>
- <div id="primaryContactVerified" class="toggle-switch" onclick="toggleSwitch(this)"></div>
- </div>
- </div>
- </div>
- </div>
- <!-- 备用联系人 -->
- <div class="form-group">
- <label class="form-label"><i class="fas fa-user-alt text-gray-400 mr-1"></i>备用联系人</label>
- <div class="bg-gray-50 rounded-lg p-3">
- <div class="flex gap-2 mb-2">
- <input type="text" id="backupContactName" class="form-input" placeholder="姓名" style="flex:1">
- <input type="text" id="backupContactPosition" class="form-input" placeholder="职务" style="flex:1">
- </div>
- <div class="flex gap-2">
- <input type="tel" id="backupContactPhone" class="form-input" placeholder="手机号" style="flex:1">
- <div class="flex items-center gap-2" style="flex:1">
- <span class="text-sm text-gray-500">已验证</span>
- <div id="backupContactVerified" class="toggle-switch" onclick="toggleSwitch(this)"></div>
- </div>
- </div>
- </div>
- </div>
- <!-- 特殊联系要求 -->
- <div class="form-group">
- <label class="form-label">特殊联系要求</label>
- <textarea id="specialContactReq" class="form-textarea" placeholder="如:仅工作时间联系、需提前预约等..."></textarea>
- </div>
- <!-- 所属行业 -->
- <div class="form-group">
- <label class="form-label">所属行业</label>
- <select id="industryType" class="form-select">
- <option value="">请选择所属行业</option>
- <option value="住宅">住宅</option>
- <option value="商业">商业</option>
- <option value="工业">工业</option>
- <option value="市政">市政</option>
- <option value="医疗">医疗</option>
- <option value="教育">教育</option>
- <option value="餐饮">餐饮</option>
- </select>
- </div>
- <!-- 项目入住率 -->
- <div class="form-group">
- <label class="form-label">项目入住率</label>
- <div class="flex items-center gap-2">
- <input type="number" id="occupancyRate" class="form-input" placeholder="请输入" min="0" max="100">
- <span class="text-gray-500">%</span>
- </div>
- </div>
- <!-- 建筑面积 -->
- <div class="form-group">
- <label class="form-label">建筑面积</label>
- <div class="flex items-center gap-2">
- <input type="number" id="buildingArea" class="form-input" placeholder="请输入" min="0">
- <span class="text-gray-500">㎡</span>
- </div>
- </div>
- <!-- 合同有效期 -->
- <div class="form-group">
- <label class="form-label">合同有效期</label>
- <div class="datetime-input">
- <input type="date" id="contractStartDate" class="form-input">
- <span class="text-gray-400 px-2">至</span>
- <input type="date" id="contractEndDate" class="form-input">
- </div>
- </div>
- <!-- 项目情况介绍 -->
- <div class="form-group">
- <label class="form-label">项目情况介绍</label>
- <textarea id="projectDesc" class="form-textarea" placeholder="请详细描述项目情况,包括服务范围、特殊要求等..."></textarea>
- </div>
- <!-- 合同总金额 -->
- <div class="form-group">
- <label class="form-label">合同总金额(元)</label>
- <input type="number" id="totalAmount" class="form-input" placeholder="请输入合同总金额">
- </div>
- <!-- 服务点列表 -->
- <div class="form-group">
- <label class="form-label">服务点列表</label>
- <div id="pointsContainer">
- <div class="point-item">
- <div class="flex items-center justify-between mb-2">
- <span class="text-gray-600 text-xs font-medium">服务点 1</span>
- <i class="fas fa-trash-alt text-red-400 ml-2 cursor-pointer" onclick="this.parentElement.parentElement.remove()"></i>
- </div>
- <input type="text" class="form-input point-name mb-2" placeholder="服务点名称(如:1号化粪池)">
- <input type="text" class="form-input point-location mb-2" placeholder="位置(如:南门地下车库)">
- <input type="text" class="form-input point-service" placeholder="对应服务项(如:清掏)">
- </div>
- </div>
- <button type="button" class="add-item-btn mt-2" onclick="addPoint()">
- <i class="fas fa-plus"></i> 添加服务点
- </button>
- </div>
- <button class="w-full py-3 bg-blue-500 text-white rounded-xl font-medium mt-4" onclick="submitProject()">
- 提交项目
- </button>
- </div>
- </div>
- </div>
- <!-- 项目详情页 - 二级页面,隐藏底部导航 -->
- <div id="projectDetailPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToPage('projectListPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">项目详情</h1>
- </div>
- <button class="text-blue-500 text-sm">
- <i class="fas fa-ellipsis-h"></i>
- </button>
- </div>
- </div>
- <!-- 详情内容 -->
- <div class="px-4 py-4 space-y-3">
- <!-- 基本信息区块 -->
- <div class="detail-section">
- <div class="detail-section-title">
- <i class="fas fa-info-circle text-blue-500"></i>
- 基本信息
- </div>
- <div class="detail-row">
- <span class="detail-label">项目名称</span>
- <span class="detail-value font-medium" id="detailProjectName">积丹白鹭</span>
- </div>
- <div class="detail-row">
- <span class="detail-label">合作类型</span>
- <span class="detail-value" id="detailCoopType"><span class="tag tag-blue">包年</span></span>
- </div>
- <div class="detail-row">
- <span class="detail-label">设施类型</span>
- <span class="detail-value" id="detailFacilityType">油污管、化粪池</span>
- </div>
- <div class="detail-row">
- <span class="detail-label">项目地址</span>
- <span class="detail-value" id="detailAddress">积丹白鹭小区</span>
- </div>
- <div class="detail-row">
- <span class="detail-label">累计服务</span>
- <span class="detail-value"><span class="text-blue-500 font-bold">24</span> 次</span>
- </div>
- </div>
- <!-- 地图定位区块 -->
- <div class="detail-section">
- <div class="detail-section-title">
- <i class="fas fa-map-marked-alt text-green-500"></i>
- 位置定位
- </div>
- <div class="mx-4 mb-4">
- <div class="bg-gray-100 rounded-xl h-36 flex items-center justify-center">
- <div class="text-center">
- <i class="fas fa-map text-gray-400 text-3xl mb-2"></i>
- <p class="text-gray-400 text-sm">地图定位区域</p>
- <p class="text-gray-300 text-xs">39.9088° N, 116.3974° E</p>
- </div>
- </div>
- </div>
- </div>
- <!-- 项目介绍区块 -->
- <div class="detail-section">
- <div class="detail-section-title">
- <i class="fas fa-file-alt text-purple-500"></i>
- 项目情况介绍
- </div>
- <div class="px-4 py-3">
- <p class="text-gray-600 text-sm leading-relaxed" id="detailDesc">
- 本项目为积丹白鹭小区提供全年日常清洁服务,主要包括:<br>
- 1. 每月对小区内所有油污管道进行专业疏通清洁<br>
- 2. 每季度对化粪池进行清理维护<br>
- 3. 24小时应急响应服务<br>
- 4. 定期出具服务报告
- </p>
- </div>
- </div>
- <!-- 位置联系人区块 -->
- <div class="detail-section">
- <div class="detail-section-title">
- <i class="fas fa-address-book text-orange-500"></i>
- 位置联系人
- </div>
- <div class="px-4 py-2" id="detailContacts">
- <div class="contact-item">
- <div class="w-10 h-10 bg-blue-100 rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-user text-blue-500"></i>
- </div>
- <div class="flex-1">
- <p class="text-gray-800 font-medium">陈物业</p>
- <p class="text-gray-400 text-sm">138****8888</p>
- </div>
- <button class="w-10 h-10 bg-green-100 rounded-full flex items-center justify-center">
- <i class="fas fa-phone text-green-500"></i>
- </button>
- </div>
- </div>
- </div>
- <!-- 费用信息区块 -->
- <div class="detail-section">
- <div class="detail-section-title">
- <i class="fas fa-coins text-yellow-500"></i>
- 费用信息
- </div>
- <div class="detail-row">
- <span class="detail-label">合同总金额</span>
- <span class="detail-value text-xl font-bold text-orange-500" id="detailTotalAmount">¥ 128,000.00</span>
- </div>
- <div class="detail-row">
- <span class="detail-label">付款方式</span>
- <span class="detail-value" id="detailPayType">年付</span>
- </div>
- <div class="detail-row">
- <span class="detail-label">合同状态</span>
- <span class="detail-value"><span class="tag tag-green">进行中</span></span>
- </div>
- </div>
- <!-- 服务点与服务项合并展示区块 -->
- <div class="detail-section">
- <div class="detail-section-title">
- <i class="fas fa-map-marker-alt text-red-500"></i>
- 服务点与对应服务项
- </div>
- <div class="pb-3" id="detailPoints">
- <div class="service-point-item">
- <div class="flex items-center justify-between mb-2">
- <span class="font-medium text-gray-800">服务点1:1号化粪池</span>
- <span class="tag tag-blue">主服务点</span>
- </div>
- <p class="text-gray-500 text-xs mb-1"><i class="fas fa-map-pin mr-1"></i>位置:地下停车场B1层</p>
- <p class="text-gray-500 text-xs"><i class="fas fa-tools mr-1"></i>服务项:<span class="text-blue-600">清掏</span></p>
- <p class="text-gray-400 text-xs mt-1"><i class="fas fa-history mr-1"></i>最近服务:2024-01-10</p>
- </div>
- <div class="service-point-item">
- <div class="flex items-center justify-between mb-2">
- <span class="font-medium text-gray-800">服务点2:2号隔油池</span>
- <span class="tag tag-green">正常</span>
- </div>
- <p class="text-gray-500 text-xs mb-1"><i class="fas fa-map-pin mr-1"></i>位置:地下停车场B2层</p>
- <p class="text-gray-500 text-xs"><i class="fas fa-tools mr-1"></i>服务项:<span class="text-blue-600">清掏</span></p>
- <p class="text-gray-400 text-xs mt-1"><i class="fas fa-history mr-1"></i>最近服务:2024-01-08</p>
- </div>
- <div class="service-point-item">
- <div class="flex items-center justify-between mb-2">
- <span class="font-medium text-gray-800">服务点3:3号油污管道</span>
- <span class="tag tag-green">正常</span>
- </div>
- <p class="text-gray-500 text-xs mb-1"><i class="fas fa-map-pin mr-1"></i>位置:裙楼餐饮区</p>
- <p class="text-gray-500 text-xs"><i class="fas fa-tools mr-1"></i>服务项:<span class="text-blue-600">疏通</span></p>
- <p class="text-gray-400 text-xs mt-1"><i class="fas fa-history mr-1"></i>最近服务:2024-01-05</p>
- </div>
- </div>
- </div>
- <!-- 操作按钮 -->
- <div class="pt-4 pb-6 space-y-3">
- <button class="w-full py-3 bg-blue-500 text-white rounded-xl font-medium">
- <i class="fas fa-edit mr-2"></i>编辑项目
- </button>
- <button class="w-full py-3 bg-white border border-gray-200 text-gray-600 rounded-xl font-medium">
- <i class="fas fa-file-alt mr-2"></i>查看合同
- </button>
- </div>
- </div>
- </div>
- <!-- 消息通知列表页 - 二级页面,隐藏底部导航 -->
- <div id="messageListPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToPage('profilePage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">消息通知</h1>
- </div>
- <button class="px-3 py-1.5 text-blue-500 text-sm" onclick="markAllMessagesRead()">全部已读</button>
- </div>
- <!-- 筛选标签 -->
- <div class="flex gap-2 mt-4 overflow-x-auto">
- <button class="px-4 py-2 bg-blue-500 text-white rounded-full text-sm whitespace-nowrap" onclick="filterMessages('all')">全部</button>
- <button class="px-4 py-2 bg-gray-100 text-gray-600 rounded-full text-sm whitespace-nowrap" onclick="filterMessages('task')">任务消息</button>
- <button class="px-4 py-2 bg-gray-100 text-gray-600 rounded-full text-sm whitespace-nowrap" onclick="filterMessages('system')">系统消息</button>
- </div>
- </div>
- <!-- 消息列表 -->
- <div class="bg-white">
- <div class="notice-item" onclick="goToPage('messageDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <div class="flex items-center">
- <span class="w-2 h-2 bg-red-500 rounded-full mr-2"></span>
- <h3 class="font-medium text-gray-800">任务已派发:积丹白鹭小区疏通</h3>
- </div>
- <span class="text-gray-400 text-xs whitespace-nowrap">刚刚</span>
- </div>
- <p class="text-gray-500 text-sm line-clamp-2">您提交的任务"积丹白鹭小区疏通"已派发给张师傅组,预计09:30到达现场...</p>
- </div>
- <div class="notice-item" onclick="goToPage('messageDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <div class="flex items-center">
- <span class="w-2 h-2 bg-red-500 rounded-full mr-2"></span>
- <h3 class="font-medium text-gray-800">任务状态更新</h3>
- </div>
- <span class="text-gray-400 text-xs whitespace-nowrap">10分钟前</span>
- </div>
- <p class="text-gray-500 text-sm line-clamp-2">您关注的"俊发城应急疏通"任务已进入施工阶段,施工班组已到达现场...</p>
- </div>
- <div class="notice-item" onclick="goToPage('messageDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <div class="flex items-center">
- <span class="w-2 h-2 rounded-full mr-2"></span>
- <h3 class="font-medium text-gray-600">系统维护通知</h3>
- </div>
- <span class="text-gray-400 text-xs whitespace-nowrap">昨天</span>
- </div>
- <p class="text-gray-500 text-sm line-clamp-2">系统将于本周六凌晨2:00-6:00进行升级维护,届时部分功能可能暂时无法使用...</p>
- </div>
- <div class="notice-item" onclick="goToPage('messageDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <div class="flex items-center">
- <span class="w-2 h-2 rounded-full mr-2"></span>
- <h3 class="font-medium text-gray-600">任务已完成</h3>
- </div>
- <span class="text-gray-400 text-xs whitespace-nowrap">2天前</span>
- </div>
- <p class="text-gray-500 text-sm line-clamp-2">您提交的任务"逸安新城日常维护"已顺利完成,施工单位已上传完工照片...</p>
- </div>
- <div class="notice-item" onclick="goToPage('messageDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <div class="flex items-center">
- <span class="w-2 h-2 rounded-full mr-2"></span>
- <h3 class="font-medium text-gray-600">催单已处理</h3>
- </div>
- <span class="text-gray-400 text-xs whitespace-nowrap">3天前</span>
- </div>
- <p class="text-gray-500 text-sm line-clamp-2">您催单的任务"富源同坐管道检修"已安排加急处理,施工班组正在赶往现场...</p>
- </div>
- </div>
- </div>
- <!-- 消息详情页 -->
- <div id="messageDetailPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToDispatchPage('dispatch_notificationPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">消息详情</h1>
- </div>
- </div>
- <!-- 详情内容 -->
- <div class="px-4 py-4">
- <div class="card p-4">
- <div class="flex items-center justify-between mb-3">
- <h2 class="text-base font-bold text-gray-800">任务已派发:积丹白鹭小区疏通</h2>
- </div>
- <p class="text-gray-400 text-sm mb-4"><i class="far fa-clock mr-1"></i>刚刚</p>
- <div class="border-t border-gray-100 pt-4">
- <p class="text-gray-600 text-sm leading-relaxed mb-4">
- 您提交的任务"积丹白鹭小区疏通"已成功派发,现将任务详情通知如下:
- </p>
- <div class="bg-gray-50 rounded-lg p-4 mb-4">
- <div class="flex justify-between text-sm mb-2">
- <span class="text-gray-500">任务名称:</span>
- <span class="text-gray-700">积丹白鹭小区疏通</span>
- </div>
- <div class="flex justify-between text-sm mb-2">
- <span class="text-gray-500">执行班组:</span>
- <span class="text-gray-700">张师傅组</span>
- </div>
- <div class="flex justify-between text-sm mb-2">
- <span class="text-gray-500">预计到达:</span>
- <span class="text-gray-700">09:30</span>
- </div>
- <div class="flex justify-between text-sm">
- <span class="text-gray-500">联系电话:</span>
- <span class="text-gray-700">139****6666</span>
- </div>
- </div>
- <p class="text-gray-600 text-sm leading-relaxed">
- 施工过程中如有任何问题,请及时联系调度中心。服务完成后,请及时验收确认。
- </p>
- </div>
- </div>
- </div>
- </div>
- <!-- 修改密码页 -->
- <div id="changePasswordPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToPage('profilePage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">修改密码</h1>
- </div>
- </div>
- <!-- 修改密码表单 -->
- <div class="px-4 py-4">
- <div class="card p-4">
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>当前密码</label>
- <input type="password" id="currentPassword" class="form-input" placeholder="请输入当前密码">
- </div>
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>新密码</label>
- <input type="password" id="newPassword" class="form-input" placeholder="请输入新密码(6-20位)">
- </div>
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>确认新密码</label>
- <input type="password" id="confirmNewPassword" class="form-input" placeholder="请再次输入新密码">
- </div>
- <div class="mt-4">
- <div class="bg-blue-50 rounded-lg p-3 mb-4">
- <p class="text-blue-600 text-sm"><i class="fas fa-info-circle mr-1"></i>密码要求:</p>
- <ul class="text-gray-500 text-xs mt-2 space-y-1">
- <li>• 长度6-20位</li>
- <li>• 必须包含字母和数字</li>
- <li>• 不能与当前密码相同</li>
- </ul>
- </div>
- <button class="w-full py-3 bg-blue-500 text-white rounded-xl font-medium" onclick="submitChangePassword()">
- 确认修改
- </button>
- </div>
- </div>
- </div>
- </div>
- <!-- 帮助中心页 -->
- <div id="helpCenterPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToPage('profilePage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">帮助中心</h1>
- </div>
- </div>
- <!-- 帮助中心内容 -->
- <div class="px-4 py-4">
- <!-- 常见问题 -->
- <div class="bg-white rounded-xl p-4 mb-4 shadow-sm">
- <h3 class="text-base font-semibold text-gray-800 mb-4"><i class="fas fa-question-circle text-blue-500 mr-2"></i>常见问题</h3>
- <div class="space-y-3">
- <div class="border-b border-gray-100 pb-3">
- <div class="flex justify-between items-center cursor-pointer" onclick="toggleFaq(this)">
- <span class="text-sm text-gray-700">如何提交新的任务工单?</span>
- <i class="fas fa-chevron-down text-gray-400 text-xs"></i>
- </div>
- <div class="hidden mt-2 text-gray-500 text-sm">
- 在首页点击右下角的"+"按钮,选择"发布任务",填写项目信息和服务信息后提交即可。
- </div>
- </div>
- <div class="border-b border-gray-100 pb-3">
- <div class="flex justify-between items-center cursor-pointer" onclick="toggleFaq(this)">
- <span class="text-sm text-gray-700">如何查看任务进度?</span>
- <i class="fas fa-chevron-down text-gray-400 text-xs"></i>
- </div>
- <div class="hidden mt-2 text-gray-500 text-sm">
- 进入"任务"页面,点击相应任务卡片即可查看任务详情和当前进度。
- </div>
- </div>
- <div class="border-b border-gray-100 pb-3">
- <div class="flex justify-between items-center cursor-pointer" onclick="toggleFaq(this)">
- <span class="text-sm text-gray-700">如何修改个人信息?</span>
- <i class="fas fa-chevron-down text-gray-400 text-xs"></i>
- </div>
- <div class="hidden mt-2 text-gray-500 text-sm">
- 进入"我的"页面,点击相应的信息项即可进行修改。
- </div>
- </div>
- <div class="border-b border-gray-100 pb-3">
- <div class="flex justify-between items-center cursor-pointer" onclick="toggleFaq(this)">
- <span class="text-sm text-gray-700">任务被驳回怎么办?</span>
- <i class="fas fa-chevron-down text-gray-400 text-xs"></i>
- </div>
- <div class="hidden mt-2 text-gray-500 text-sm">
- 您可以查看驳回原因,修改任务信息后重新提交,或联系调度中心咨询。
- </div>
- </div>
- <div>
- <div class="flex justify-between items-center cursor-pointer" onclick="toggleFaq(this)">
- <span class="text-sm text-gray-700">如何联系客服?</span>
- <i class="fas fa-chevron-down text-gray-400 text-xs"></i>
- </div>
- <div class="hidden mt-2 text-gray-500 text-sm">
- 可以在"我的"页面点击"联系客服",或拨打客服热线:400-888-8888。
- </div>
- </div>
- </div>
- </div>
- <!-- 联系客服 -->
- <div class="bg-white rounded-xl p-4 shadow-sm">
- <h3 class="text-base font-semibold text-gray-800 mb-4"><i class="fas fa-headset text-green-500 mr-2"></i>联系客服</h3>
- <div class="flex items-center justify-between py-3 border-b border-gray-100">
- <div class="flex items-center">
- <i class="fas fa-phone text-blue-500 mr-3"></i>
- <span class="text-sm text-gray-700">客服热线</span>
- </div>
- <span class="text-blue-500 text-sm">400-888-8888</span>
- </div>
- <div class="flex items-center justify-between py-3 border-b border-gray-100">
- <div class="flex items-center">
- <i class="fas fa-envelope text-blue-500 mr-3"></i>
- <span class="text-sm text-gray-700">电子邮箱</span>
- </div>
- <span class="text-gray-600 text-sm">service@qingdaofu.com</span>
- </div>
- <div class="flex items-center justify-between py-3">
- <div class="flex items-center">
- <i class="fas fa-clock text-blue-500 mr-3"></i>
- <span class="text-sm text-gray-700">服务时间</span>
- </div>
- <span class="text-gray-600 text-sm">9:00-18:00</span>
- </div>
- </div>
- </div>
- </div>
- <!-- 通知公告列表页 - 二级页面,隐藏底部导航 -->
- <div id="noticeListPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToPage('salesPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">通知公告</h1>
- </div>
- </div>
- <!-- 公告列表 -->
- <div class="bg-white">
- <div class="notice-item" onclick="goToPage('noticeDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <h3 class="font-medium text-gray-800 flex-1 pr-2">关于2024年第一季度销售激励方案的通知</h3>
- <span class="text-gray-400 text-xs whitespace-nowrap">01-15</span>
- </div>
- <p class="text-gray-500 text-sm line-clamp-2">为激励销售团队积极性,公司决定对2024年第一季度表现优秀的销售人员给予额外奖励...</p>
- </div>
- <div class="notice-item" onclick="goToPage('noticeDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <h3 class="font-medium text-gray-800 flex-1 pr-2">春节期间服务安排调整公告</h3>
- <span class="text-gray-400 text-xs whitespace-nowrap">01-10</span>
- </div>
- <p class="text-gray-500 text-sm line-clamp-2">根据国家法定节假日安排,结合公司实际情况,现对春节期间的服务工作进行如下调整...</p>
- </div>
- <div class="notice-item" onclick="goToPage('noticeDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <h3 class="font-medium text-gray-800 flex-1 pr-2">新增设施类型服务标准说明</h3>
- <span class="text-gray-400 text-xs whitespace-nowrap">01-05</span>
- </div>
- <p class="text-gray-500 text-sm line-clamp-2">为更好地满足客户需求,公司新增了高压水射流清洗和CCTV管道检测两项服务...</p>
- </div>
- <div class="notice-item" onclick="goToPage('noticeDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <h3 class="font-medium text-gray-800 flex-1 pr-2">2023年度优秀员工表彰名单</h3>
- <span class="text-gray-400 text-xs whitespace-nowrap">12-28</span>
- </div>
- <p class="text-gray-500 text-sm line-clamp-2">经公司研究决定,对在2023年度工作中表现突出的员工进行表彰...</p>
- </div>
- <div class="notice-item" onclick="goToPage('noticeDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <h3 class="font-medium text-gray-800 flex-1 pr-2">系统升级维护通知</h3>
- <span class="text-gray-400 text-xs whitespace-nowrap">12-20</span>
- </div>
- <p class="text-gray-500 text-sm line-clamp-2">为提升系统性能和服务稳定性,计划于12月25日凌晨进行系统升级维护...</p>
- </div>
- </div>
- </div>
- <!-- 通知公告详情页 - 二级页面,隐藏底部导航 -->
- <div id="noticeDetailPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToPage('noticeListPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">公告详情</h1>
- </div>
- </div>
- <!-- 详情内容 -->
- <div class="px-4 py-4">
- <div class="card p-4">
- <h2 class="text-lg font-bold text-gray-800 mb-2">关于2024年第一季度销售激励方案的通知</h2>
- <p class="text-gray-400 text-sm mb-4"><i class="far fa-clock mr-1"></i>2024-01-15 10:30</p>
- <div class="border-t border-gray-100 pt-4">
- <p class="text-gray-600 text-sm leading-relaxed mb-4">
- 各位销售同事:
- </p>
- <p class="text-gray-600 text-sm leading-relaxed mb-4">
- 为激励销售团队积极性,完成公司年度销售目标,经管理层研究决定,对2024年第一季度表现优秀的销售人员给予额外奖励,具体方案如下:
- </p>
- <p class="text-gray-600 text-sm leading-relaxed mb-4">
- <strong>一、激励对象</strong><br>
- 所有在册销售人员
- </p>
- <p class="text-gray-600 text-sm leading-relaxed mb-4">
- <strong>二、激励措施</strong><br>
- 1. 完成季度指标的120%以上,奖励5000元<br>
- 2. 完成季度指标的100%-120%,奖励3000元<br>
- 3. 完成季度指标的80%-100%,奖励1000元
- </p>
- <p class="text-gray-600 text-sm leading-relaxed mb-4">
- <strong>三、发放时间</strong><br>
- 奖金将于次季度首月随工资发放
- </p>
- <p class="text-gray-600 text-sm leading-relaxed">
- 希望各位同事积极开拓市场,争取佳绩!
- </p>
- <p class="text-gray-500 text-sm leading-relaxed mt-4 text-right">
- 清道夫科技有限公司<br>
- 2024年1月15日
- </p>
- </div>
- </div>
- </div>
- </div>
- <!-- 行业知识列表页 - 二级页面,隐藏底部导航 -->
- <div id="knowledgeListPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToPage('salesPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">行业知识</h1>
- </div>
- </div>
- <!-- 知识列表 -->
- <div class="px-4 py-4">
- <div class="knowledge-card flex" onclick="goToPage('knowledgeDetailPage')">
- <div class="w-24 h-24 bg-gradient-to-br from-blue-400 to-blue-600 rounded-xl flex items-center justify-center mr-3 flex-shrink-0">
- <i class="fas fa-chart-pie text-white text-2xl"></i>
- </div>
- <div class="flex-1 flex flex-col justify-center">
- <h3 class="font-medium text-gray-800 mb-1">2024年清洁行业市场分析报告</h3>
- <p class="text-gray-400 text-xs line-clamp-2">全面解读清洁行业发展趋势、市场规模及竞争格局,为企业战略规划提供数据支撑...</p>
- <p class="text-gray-300 text-xs mt-1">2024-01-12</p>
- </div>
- </div>
- <div class="knowledge-card flex" onclick="goToPage('knowledgeDetailPage')">
- <div class="w-24 h-24 bg-gradient-to-br from-yellow-400 to-orange-500 rounded-xl flex items-center justify-center mr-3 flex-shrink-0">
- <i class="fas fa-lightbulb text-white text-2xl"></i>
- </div>
- <div class="flex-1 flex flex-col justify-center">
- <h3 class="font-medium text-gray-800 mb-1">客户开发技巧与话术指南</h3>
- <p class="text-gray-400 text-xs line-clamp-2">提升销售业绩的实战技巧,有效沟通方法汇总,助你快速成交...</p>
- <p class="text-gray-300 text-xs mt-1">2024-01-08</p>
- </div>
- </div>
- <div class="knowledge-card flex" onclick="goToPage('knowledgeDetailPage')">
- <div class="w-24 h-24 bg-gradient-to-br from-green-400 to-emerald-600 rounded-xl flex items-center justify-center mr-3 flex-shrink-0">
- <i class="fas fa-handshake text-white text-2xl"></i>
- </div>
- <div class="flex-1 flex flex-col justify-center">
- <h3 class="font-medium text-gray-800 mb-1">大客户维护策略</h3>
- <p class="text-gray-400 text-xs line-clamp-2">深度解析大客户维护技巧,建立长期稳定合作关系,提升客户续约率...</p>
- <p class="text-gray-300 text-xs mt-1">2024-01-05</p>
- </div>
- </div>
- <div class="knowledge-card flex" onclick="goToPage('knowledgeDetailPage')">
- <div class="w-24 h-24 bg-gradient-to-br from-purple-400 to-violet-600 rounded-xl flex items-center justify-center mr-3 flex-shrink-0">
- <i class="fas fa-clipboard-check text-white text-2xl"></i>
- </div>
- <div class="flex-1 flex flex-col justify-center">
- <h3 class="font-medium text-gray-800 mb-1">项目报价方案设计要点</h3>
- <p class="text-gray-400 text-xs line-clamp-2">专业报价方案设计指南,包含成本核算、利润空间把控及竞品分析...</p>
- <p class="text-gray-300 text-xs mt-1">2023-12-28</p>
- </div>
- </div>
- <div class="knowledge-card flex" onclick="goToPage('knowledgeDetailPage')">
- <div class="w-24 h-24 bg-gradient-to-br from-red-400 to-rose-600 rounded-xl flex items-center justify-center mr-3 flex-shrink-0">
- <i class="fas fa-file-contract text-white text-2xl"></i>
- </div>
- <div class="flex-1 flex flex-col justify-center">
- <h3 class="font-medium text-gray-800 mb-1">合同签订注意事项</h3>
- <p class="text-gray-400 text-xs line-clamp-2">销售合同签订全流程解析,规避法律风险,确保企业利益...</p>
- <p class="text-gray-300 text-xs mt-1">2023-12-20</p>
- </div>
- </div>
- </div>
- </div>
- <!-- 行业知识详情页 - 二级页面,隐藏底部导航 -->
- <div id="knowledgeDetailPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToPage('knowledgeListPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">知识详情</h1>
- </div>
- </div>
- <!-- 详情内容 -->
- <div class="px-4 py-4">
- <div class="card overflow-hidden">
- <!-- 封面图 -->
- <div class="h-48 bg-gradient-to-br from-blue-400 to-blue-600 flex items-center justify-center">
- <i class="fas fa-chart-pie text-white text-5xl"></i>
- </div>
- <div class="p-4">
- <h2 class="text-lg font-bold text-gray-800 mb-2">2024年清洁行业市场分析报告</h2>
- <p class="text-gray-400 text-sm mb-4"><i class="far fa-clock mr-1"></i>2024-01-12</p>
- <div class="border-t border-gray-100 pt-4 space-y-4">
- <div class="bg-blue-50 rounded-xl p-4">
- <h3 class="font-medium text-blue-600 mb-2"><i class="fas fa-chart-line mr-2"></i>市场规模</h3>
- <p class="text-gray-600 text-sm">2024年中国清洁服务市场规模预计达到2000亿元,同比增长15%。其中,商业清洁占比45%,工业清洁占比30%,家庭清洁占比25%。</p>
- </div>
- <div class="bg-green-50 rounded-xl p-4">
- <h3 class="font-medium text-green-600 mb-2"><i class="fas fa-users mr-2"></i>市场格局</h3>
- <p class="text-gray-600 text-sm">行业集中度较低,TOP10企业市场份额不足20%。未来3-5年将进入整合期,具有品牌优势和规模效应的企业将获得更大发展空间。</p>
- </div>
- <div class="bg-purple-50 rounded-xl p-4">
- <h3 class="font-medium text-purple-600 mb-2"><i class="fas fa-rocket mr-2"></i>发展趋势</h3>
- <p class="text-gray-600 text-sm">
- 1. <strong>智能化升级</strong>:智能清洁设备渗透率将提升至30%<br>
- 2. <strong>专业化分工</strong>:细分领域专业服务商崛起<br>
- 3. <strong>服务标准化</strong>:行业服务标准体系逐步完善<br>
- 4. <strong>品牌化运营</strong>:客户对品牌认知度不断提升
- </p>
- </div>
- <div class="bg-orange-50 rounded-xl p-4">
- <h3 class="font-medium text-orange-600 mb-2"><i class="fas fa-bullseye mr-2"></i>业务机会</h3>
- <p class="text-gray-600 text-sm">
- • 工业园区和写字楼的物业清洁外包需求增长<br>
- • 医疗机构和食品工厂的专业清洁服务需求旺盛<br>
- • 老旧小区改造带来的清洁服务增量市场
- </p>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- 发布任务页 - 单页面两板块结构 -->
- <div id="publishTaskPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToPage('taskPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">发布任务</h1>
- </div>
- </div>
- </div>
- <!-- 页面内容 -->
- <div class="px-4 py-4 pb-24">
- <!-- 板块一:项目基本信息 -->
- <div class="card p-4 mb-4" id="sectionProject">
- <!-- 板块标题 -->
- <div class="flex items-center mb-4">
- <div class="w-8 h-8 bg-blue-100 rounded-lg flex items-center justify-center mr-3">
- <i class="fas fa-building text-blue-500"></i>
- </div>
- <h2 class="text-base font-semibold text-gray-800">项目基本信息</h2>
- </div>
- <!-- 项目选择提示 -->
- <div id="projectSelectHint" class="bg-blue-50 rounded-lg px-3 py-2 mb-4 flex items-center">
- <i class="fas fa-info-circle text-blue-500 mr-2 text-sm"></i>
- <span class="text-blue-600 text-sm" id="projectHintText">请从项目库选择或新增项目</span>
- </div>
- <!-- 项目选择 -->
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>选择项目</label>
- <select id="projectSelect" class="form-select" onchange="onProjectSelectChange()">
- <option value="">请选择项目</option>
- <option value="积丹白鹭">积丹白鹭</option>
- <option value="富源同坐">富源同坐</option>
- <option value="俊发城">俊发城</option>
- <option value="逸安新城A区">逸安新城A区</option>
- <option value="逸安新城B区">逸安新城B区</option>
- <option value="new">+ 新增项目</option>
- </select>
- </div>
- <!-- 已选项目信息(自动带出) -->
- <div id="projectAutoInfo" class="bg-green-50 rounded-xl p-3" style="display: none;">
- <div class="flex items-center justify-between mb-3">
- <span class="text-green-600 text-sm font-medium">
- <i class="fas fa-check-circle mr-1"></i>已选择:<span id="selectedProjectName"></span>
- </span>
- <button class="text-green-500 text-xs" onclick="resetProjectSelection()">重新选择</button>
- </div>
- <div class="space-y-2">
- <div class="flex justify-between text-sm">
- <span class="text-gray-500">合作类型:</span>
- <span class="text-gray-700" id="autoCoopType">-</span>
- </div>
- <div class="flex justify-between text-sm">
- <span class="text-gray-500">设施类型:</span>
- <span class="text-gray-700" id="autoFacilityType">-</span>
- </div>
- <div class="flex justify-between text-sm">
- <span class="text-gray-500">项目地址:</span>
- <span class="text-gray-700" id="autoProjectAddress">-</span>
- </div>
- </div>
- </div>
- <!-- 新增项目表单 -->
- <div id="newProjectForm" style="display: none;">
- <div class="bg-orange-50 rounded-lg px-3 py-2 mb-4 flex items-center">
- <i class="fas fa-edit text-orange-500 mr-2 text-sm"></i>
- <span class="text-orange-600 text-sm">新增项目 - 请填写以下信息</span>
- </div>
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>项目名称</label>
- <input type="text" id="newProjectName" class="form-input" placeholder="请输入项目名称">
- </div>
- <div class="inline-selector mb-4">
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>合作类型</label>
- <select id="newCoopType" class="form-select">
- <option value="">请选择</option>
- <option value="包年">包年</option>
- <option value="单次">单次</option>
- <option value="季度">季度</option>
- <option value="月付">月付</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>设施类型</label>
- <select id="newFacilityType" class="form-select">
- <option value="">请选择</option>
- <option value="住宅">住宅</option>
- <option value="商业">商业</option>
- <option value="工业">工业</option>
- <option value="市政">市政</option>
- </select>
- </div>
- </div>
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>项目地址</label>
- <input type="text" id="newProjectAddress" class="form-input" placeholder="请输入项目地址">
- </div>
- </div>
- <!-- 联系人列表 -->
- <div class="form-group mb-0">
- <label class="form-label">联系人</label>
- <div id="contactListContainer">
- <!-- 联系人列表动态生成 -->
- </div>
- <button type="button" class="add-item-btn mt-2" onclick="addContactItem()">
- <i class="fas fa-plus"></i> 添加联系人
- </button>
- </div>
- </div>
- <!-- 板块二:服务信息 -->
- <div class="card p-4" id="sectionService">
- <!-- 板块标题 -->
- <div class="flex items-center mb-4">
- <div class="w-8 h-8 bg-purple-100 rounded-lg flex items-center justify-center mr-3">
- <i class="fas fa-tools text-purple-500"></i>
- </div>
- <h2 class="text-base font-semibold text-gray-800">服务信息</h2>
- </div>
- <!-- 服务时间 -->
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>服务时间</label>
- <div class="datetime-input">
- <input type="date" id="serviceDate" class="form-input">
- <input type="time" id="serviceTime" class="form-input" style="flex: 0.6;">
- </div>
- </div>
- <!-- 故障位置 -->
- <div class="form-group">
- <div class="auto-filled-label" id="faultLocationLabel" style="display: none;">
- <i class="fas fa-magic mr-1"></i>已自动填充
- </div>
- <label class="form-label"><span class="text-red-500">*</span>故障位置</label>
- <input type="text" id="faultLocation" class="form-input" placeholder="请输入故障位置">
- </div>
- <!-- 地理位置(地图) -->
- <div class="form-group">
- <label class="form-label">地理位置</label>
- <div class="bg-gray-100 rounded-xl h-24 flex items-center justify-center border border-gray-200 cursor-pointer" onclick="showToast('地图定位功能开发中')">
- <div class="text-center">
- <i class="fas fa-map-marked-alt text-gray-400 text-2xl mb-1"></i>
- <p class="text-gray-400 text-xs">点击获取当前位置</p>
- </div>
- </div>
- </div>
- <!-- 故障类型 -->
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>故障类型</label>
- <div class="tag-selector">
- <div class="tag-option" onclick="toggleTag(this)">堵塞</div>
- <div class="tag-option" onclick="toggleTag(this)">满溢</div>
- <div class="tag-option" onclick="toggleTag(this)">排水慢</div>
- <div class="tag-option" onclick="toggleTag(this)">异味</div>
- <div class="tag-option" onclick="toggleTag(this)">其他</div>
- </div>
- </div>
- <!-- 故障描述 - 客户原话 -->
- <div class="form-group">
- <label class="form-label">客户原话</label>
- <textarea id="customerOriginalWords" class="form-textarea" placeholder="请记录客户原话描述..."></textarea>
- </div>
- <!-- 故障描述 - 客服转译 -->
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>故障描述</label>
- <textarea id="faultDesc" class="form-textarea" placeholder="请详细描述故障情况..."></textarea>
- </div>
- <!-- 发生时间和反复情况 -->
- <div class="inline-selector mb-4">
- <div class="form-group">
- <label class="form-label">首次出现时间</label>
- <input type="date" id="firstOccurrenceTime" class="form-input">
- </div>
- <div class="form-group">
- <label class="form-label">近期反复情况</label>
- <select id="recurrenceFrequency" class="form-select">
- <option value="">请选择</option>
- <option value="无">无</option>
- <option value="偶尔">偶尔</option>
- <option value="频繁">频繁</option>
- </select>
- </div>
- </div>
- <!-- 影响范围 -->
- <div class="form-group">
- <label class="form-label">影响范围</label>
- <div class="tag-selector">
- <div class="tag-option" onclick="toggleTag(this)">单户</div>
- <div class="tag-option" onclick="toggleTag(this)">楼栋</div>
- <div class="tag-option" onclick="toggleTag(this)">小区主干道</div>
- <div class="tag-option" onclick="toggleTag(this)">商铺门口</div>
- </div>
- </div>
- <!-- 故障图片/视频 -->
- <div class="form-group">
- <label class="form-label">故障图片/视频</label>
- <div class="border-2 border-dashed border-gray-200 rounded-xl p-6 text-center cursor-pointer" onclick="showToast('上传功能开发中')">
- <i class="fas fa-cloud-upload-alt text-gray-300 text-2xl mb-2"></i>
- <p class="text-gray-400 text-sm">点击上传图片或视频</p>
- <p class="text-gray-300 text-xs mt-1">支持 JPG、PNG、MP4 格式</p>
- </div>
- </div>
- <!-- 施工类型 & 施工设施(一行) -->
- <div class="inline-selector mb-4">
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>施工类型</label>
- <select id="serviceType" class="form-select">
- <option value="">请选择</option>
- <option value="疏通">疏通</option>
- <option value="清淤">清淤</option>
- <option value="排查">排查</option>
- </select>
- </div>
- </div>
- <!-- 服务与结算数据区 -->
- <div class="card p-4 mb-4" style="background:#fef3c7;">
- <div class="detail-section-title cursor-pointer">
- <i class="fas fa-yen-sign text-yellow-600"></i>
- <span>服务与结算数据</span>
- <i class="fas fa-chevron-down toggle-icon ml-auto"></i>
- </div>
- <div class="section-content p-4">
- <div class="inline-selector">
- <div class="form-group">
- <label class="form-label">期望到达时间</label>
- <input type="datetime-local" id="dispatchExpectTime" class="form-input">
- </div>
- <div class="form-group">
- <label class="form-label">最晚处理时限</label>
- <input type="datetime-local" id="dispatchDeadline" class="form-input">
- </div>
- </div>
- <div class="form-group">
- <label class="form-label">验收标准</label>
- <select id="dispatchAcceptStandard" class="form-select">
- <option value="">请选择</option>
- <option value="客户自定义">客户自定义</option>
- <option value="公司标准">公司标准</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label">结算方式</label>
- <div class="tag-selector">
- <div class="tag-option" onclick="toggleTag(this)">签单</div>
- <div class="tag-option" onclick="toggleTag(this)">现结</div>
- <div class="tag-option" onclick="toggleTag(this)">对公转账</div>
- <div class="tag-option" onclick="toggleTag(this)">二维码</div>
- </div>
- </div>
- <div class="inline-selector">
- <div class="form-group">
- <label class="form-label">堵点个数</label>
- <input type="number" id="dispatchBlockageCount" class="form-input" placeholder="个">
- </div>
- <div class="form-group">
- <label class="form-label">清淤方量</label>
- <div class="flex items-center gap-2">
- <input type="number" id="dispatchDredgeVolume" class="form-input" placeholder="0" step="0.1">
- <span class="text-gray-500">m³</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- 工单生成数据区 -->
- <div class="card p-4 mb-4" style="background:#ede9fe;">
- <div class="detail-section-title cursor-pointer">
- <i class="fas fa-file-alt text-purple-600"></i>
- <span>工单生成数据</span>
- <i class="fas fa-chevron-down toggle-icon ml-auto"></i>
- </div>
- <div class="section-content p-4">
- <div class="form-group">
- <label class="form-label">施工指令</label>
- <textarea id="dispatchConstructionInstruction" class="form-textarea" placeholder="请输入施工指令..."></textarea>
- </div>
- <div class="form-group">
- <label class="form-label">风险提示</label>
- <div class="bg-yellow-50 rounded-lg p-3 text-sm text-yellow-700">
- <i class="fas fa-exclamation-circle mr-1"></i>有限空间作业,需通风检测后方可进入
- </div>
- </div>
- </div>
- </div>
- <!-- 派单结果判定区 -->
- <div class="card p-4 mb-4" style="background:#dcfce7;">
- <div class="detail-section-title cursor-pointer">
- <i class="fas fa-check-circle text-green-600"></i>
- <span>派单结果判定</span>
- <i class="fas fa-chevron-down toggle-icon ml-auto"></i>
- </div>
- <div class="section-content p-4">
- <div class="form-group">
- <label class="form-label">派单结果</label>
- <div class="tag-selector">
- <div class="tag-option selected" onclick="toggleTag(this)">派单成功</div>
- <div class="tag-option" onclick="toggleTag(this)">暂缓派单</div>
- <div class="tag-option" onclick="toggleTag(this)">拒绝派单</div>
- </div>
- </div>
- </div>
- </div>
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>施工设施</label>
- <select id="serviceFacilityType" class="form-select">
- <option value="">请选择</option>
- <option value="PVC">PVC</option>
- <option value="直抽直排">直抽直排</option>
- <option value="油污">油污</option>
- <option value="排污">排污</option>
- <option value="油污管">油污管</option>
- <option value="化粪池">化粪池</option>
- </select>
- </div>
- </div>
- <!-- 服务方式 & 建议出车(一行) -->
- <div class="inline-selector mb-4">
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>服务方式</label>
- <select id="serviceMode" class="form-select">
- <option value="">请选择</option>
- <option value="应急">应急</option>
- <option value="月计划">月计划</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>建议出车</label>
- <select id="vehicleType" class="form-select">
- <option value="">请选择</option>
- <option value="疏通车">疏通车</option>
- <option value="吸污车">吸污车</option>
- <option value="高压清洗车">高压清洗车</option>
- </select>
- </div>
- </div>
- <!-- 取水距离 & 化粪池排口是否正常(一行) -->
- <div class="inline-selector mb-4">
- <div class="form-group">
- <label class="form-label">取水距离</label>
- <select id="waterSource" class="form-select">
- <option value="">请选择</option>
- <option value="有消防水">有消防水</option>
- <option value="无消防水">无消防水</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label">化粪池排口是否正常</label>
- <select id="septicTank" class="form-select">
- <option value="">请选择</option>
- <option value="是">是</option>
- <option value="否">否</option>
- </select>
- </div>
- </div>
- <!-- 施工助力信息(非必填,多行文本) -->
- <div class="form-group">
- <label class="form-label">施工助力信息</label>
- <textarea id="constructionHelp" class="form-textarea" placeholder="如地库限高、需搭脚手架、登高作业等"></textarea>
- </div>
- <!-- 预计作业量 & 预计工时(一行) -->
- <div class="inline-selector mb-4">
- <div class="form-group">
- <label class="form-label">预计作业量</label>
- <input type="text" id="estimatedQuantity" class="form-input" placeholder="如 2个堵点">
- </div>
- <div class="form-group">
- <label class="form-label">预计工时</label>
- <input type="text" id="estimatedHours" class="form-input" placeholder="如 2小时">
- </div>
- </div>
- <!-- 验收要求 & 是否有前期施工关联(一行) -->
- <div class="inline-selector mb-4">
- <div class="form-group">
- <label class="form-label">验收要求</label>
- <input type="text" id="acceptanceReq" class="form-input" placeholder="如 正常走水">
- </div>
- <div class="form-group">
- <label class="form-label">是否有前期施工关联</label>
- <select id="previousConstruction" class="form-select">
- <option value="">请选择</option>
- <option value="是">是</option>
- <option value="否">否</option>
- </select>
- </div>
- </div>
- <!-- 验收方式 -->
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>验收方式</label>
- <select id="acceptType" class="form-select">
- <option value="">请选择</option>
- <option value="签署验收计量单">签署验收计量单</option>
- <option value="累计自动计费">累计自动计费</option>
- </select>
- </div>
- <!-- 甲方当事人 -->
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>甲方当事人</label>
- <div id="partyAContactList">
- <!-- 联系人列表动态生成 -->
- </div>
- <button type="button" class="add-item-btn mt-2" onclick="addPartyAContact()">
- <i class="fas fa-plus"></i> 添加甲方当事人
- </button>
- </div>
- <!-- 备注 -->
- <div class="form-group mb-0">
- <label class="form-label">备注</label>
- <textarea id="remark" class="form-textarea" placeholder="如有其他要求请备注..."></textarea>
- </div>
- </div>
- </div>
- <!-- 底部固定提交按钮 -->
- <div class="fixed bottom-0 left-1/2 transform -translate-x-1/2 w-full max-w-[430px] bg-white border-t border-gray-100 p-4 z-20">
- <button class="w-full py-3 bg-blue-500 text-white rounded-xl font-medium text-base" onclick="submitTask()">
- <i class="fas fa-paper-plane mr-2"></i>提交任务
- </button>
- </div>
- </div>
- <!-- 任务详情页 - 二级页面,隐藏底部导航 -->
- <div id="taskDetailPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToPage('taskPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">任务详情</h1>
- </div>
- <button class="text-blue-500 text-sm">
- <i class="fas fa-ellipsis-h"></i>
- </button>
- </div>
- </div>
- <!-- 详情内容 -->
- <div class="px-4 space-y-3 pb-20">
- <!-- 状态标签 -->
- <div class="pt-3 pb-1">
- <span class="status-tag status-scheduling" id="detailStatusTag">调度中</span>
- </div>
- <!-- 项目信息区块 -->
- <div class="detail-block" id="projectBlock">
- <div class="detail-block-header">
- <i class="fas fa-building text-blue-500"></i>
- 项目信息
- </div>
- <div class="detail-row">
- <span class="detail-label">项目名称</span>
- <span class="detail-value font-medium" id="detailProjectName">积丹白鹭</span>
- </div>
- <div class="detail-row">
- <span class="detail-label">合作类型</span>
- <span class="detail-value" id="detailCoopType"><span class="tag tag-blue">包年</span></span>
- </div>
- <div class="detail-row">
- <span class="detail-label">设施类型</span>
- <span class="detail-value" id="detailFacilityType">油污管</span>
- </div>
- <div class="detail-row">
- <span class="detail-label">项目地址</span>
- <span class="detail-value" id="detailAddress">积丹白鹭小区</span>
- </div>
- <div class="detail-row" style="flex-direction: column; align-items: flex-start;">
- <span class="detail-label mb-2">联系人列表</span>
- <div class="w-full" id="detailProjectContacts">
- <!-- 联系人列表动态生成 -->
- </div>
- </div>
- </div>
- <!-- 施工信息区块 -->
- <div class="detail-block" id="constructionBlock">
- <div class="detail-block-header">
- <i class="fas fa-tools text-green-500"></i>
- 施工信息
- </div>
- <div class="detail-row">
- <span class="detail-label">服务时间</span>
- <span class="detail-value" id="detailServiceTime">2024-01-21 09:00</span>
- </div>
- <div class="detail-row">
- <span class="detail-label">故障位置</span>
- <span class="detail-value" id="detailFaultLocation">积丹白鹭小区地下停车场B1层</span>
- </div>
- <div class="detail-row">
- <span class="detail-label">地理位置</span>
- <span class="detail-value text-blue-500" id="detailGeoLocation">
- <i class="fas fa-map-marker-alt mr-1"></i>点击查看地图
- </span>
- </div>
- <div class="detail-row" style="flex-direction: column; align-items: flex-start;">
- <span class="detail-label mb-1">故障描述</span>
- <span class="detail-value text-gray-600 text-sm" id="detailFaultDesc">管道堵塞,污水溢出,需要紧急疏通处理</span>
- </div>
- <div class="detail-row" style="flex-direction: column; align-items: flex-start;">
- <span class="detail-label mb-2">故障图片/视频</span>
- <div class="flex gap-2" id="detailMedia">
- <div class="w-16 h-16 bg-gray-100 rounded-lg flex items-center justify-center">
- <i class="fas fa-image text-gray-400"></i>
- </div>
- </div>
- </div>
- <div class="detail-row">
- <span class="detail-label">施工类型</span>
- <span class="detail-value" id="detailServiceType">疏通</span>
- </div>
- <div class="detail-row">
- <span class="detail-label">施工设施</span>
- <span class="detail-value" id="detailFacility">油污管</span>
- </div>
- <div class="detail-row">
- <span class="detail-label">服务方式</span>
- <span class="detail-value" id="detailServiceMode">应急</span>
- </div>
- <div class="detail-row">
- <span class="detail-label">建议出车</span>
- <span class="detail-value" id="detailVehicle">疏通车</span>
- </div>
- <div class="detail-row">
- <span class="detail-label">取水距离</span>
- <span class="detail-value" id="detailWaterSource">有消防水</span>
- </div>
- <div class="detail-row">
- <span class="detail-label">化粪池排口</span>
- <span class="detail-value" id="detailSepticTank">正常</span>
- </div>
- <div class="detail-row" style="flex-direction: column; align-items: flex-start;">
- <span class="detail-label mb-1">施工助力信息</span>
- <span class="detail-value text-gray-600 text-sm" id="detailConstructionHelp">地库限高2.2米,需注意</span>
- </div>
- <div class="detail-row">
- <span class="detail-label">预计作业量</span>
- <span class="detail-value" id="detailEstimatedQuantity">2个堵点</span>
- </div>
- <div class="detail-row">
- <span class="detail-label">预计工时</span>
- <span class="detail-value" id="detailEstimatedHours">2小时</span>
- </div>
- <div class="detail-row">
- <span class="detail-label">验收要求</span>
- <span class="detail-value" id="detailAcceptRequirement">正常走水</span>
- </div>
- <div class="detail-row">
- <span class="detail-label">前期施工关联</span>
- <span class="detail-value" id="detailPreviousConstruction">否</span>
- </div>
- <div class="detail-row">
- <span class="detail-label">验收方式</span>
- <span class="detail-value" id="detailAcceptType">签署验收计量单</span>
- </div>
- <div class="detail-row" style="flex-direction: column; align-items: flex-start;">
- <span class="detail-label mb-2">甲方当事人</span>
- <div class="w-full" id="detailPartyAContacts">
- <!-- 甲方当事人列表动态生成 -->
- </div>
- </div>
- <div class="detail-row" style="flex-direction: column; align-items: flex-start;">
- <span class="detail-label mb-1">备注</span>
- <span class="detail-value text-gray-600 text-sm" id="detailRemark">-</span>
- </div>
- </div>
- <!-- 任务进度区块 -->
- <div class="detail-block">
- <div class="detail-block-header">
- <i class="fas fa-tasks text-purple-500"></i>
- 任务进度
- </div>
- <div class="p-4">
- <div class="flex justify-between items-center mb-2">
- <span class="text-gray-500 text-xs">发布</span>
- <span class="text-gray-500 text-xs">调度确认</span>
- <span class="text-gray-500 text-xs">施工</span>
- <span class="text-gray-500 text-xs">完成</span>
- </div>
- <div class="progress-bar-track" style="height: 6px;">
- <div class="progress-bar-fill" id="detailProgressFill" style="width: 25%"></div>
- <div class="progress-bar-step" id="detailStep1" style="width: 16px; height: 16px;"></div>
- <div class="progress-bar-step" id="detailStep2" style="width: 16px; height: 16px;"></div>
- <div class="progress-bar-step" id="detailStep3" style="width: 16px; height: 16px;"></div>
- <div class="progress-bar-step" id="detailStep4" style="width: 16px; height: 16px;"></div>
- </div>
- </div>
- </div>
- <!-- 处理记录区块 -->
- <div class="detail-block" id="recordBlock">
- <div class="detail-block-header">
- <i class="fas fa-history text-orange-500"></i>
- 处理记录
- </div>
- <div id="timelineRecords">
- <!-- 时间线记录动态生成 -->
- </div>
- </div>
- <!-- 操作日志 -->
- <div class="detail-block">
- <div class="detail-block-header">
- <i class="fas fa-list-alt text-green-500"></i>
- 操作日志
- </div>
- <div class="p-4 space-y-3" id="sales_taskLogList">
- <div class="flex items-start text-sm">
- <span class="text-gray-400 w-20 flex-shrink-0">04-21 09:30</span>
- <div class="flex-1">
- <span class="text-gray-800">销售 李明</span>
- <span class="text-gray-500">发布了任务</span>
- </div>
- </div>
- <div class="flex items-start text-sm">
- <span class="text-gray-400 w-20 flex-shrink-0">04-21 10:15</span>
- <div class="flex-1">
- <span class="text-gray-800">调度 张调度</span>
- <span class="text-gray-500">已安排班组:工程一班</span>
- </div>
- </div>
- </div>
- </div>
- <!-- 补充信息按钮 -->
- <button class="w-full py-3 bg-white border border-gray-200 text-gray-600 rounded-xl font-medium flex items-center justify-center" onclick="showSupplementModal()">
- <i class="fas fa-plus mr-2"></i>补充信息
- </button>
- </div>
- <!-- 底部操作按钮 -->
- <div class="fixed bottom-0 left-1/2 transform -translate-x-1/2 w-full max-w-[430px] bg-white border-t border-gray-100 p-4 z-20">
- <div class="flex gap-3" id="detailActions">
- <button class="flex-1 py-3 bg-white border border-gray-200 text-gray-600 rounded-xl font-medium" onclick="showCancelModal()">
- 取消任务
- </button>
- <button class="flex-1 py-3 bg-blue-500 text-white rounded-xl font-medium" onclick="showToast('催单成功')">
- <i class="fas fa-bell mr-1"></i>催单
- </button>
- </div>
- </div>
- </div>
- <!-- 取消任务模态框 -->
- <div id="cancelModal" class="modal-overlay hidden">
- <div class="modal-content">
- <div class="modal-header">
- <i class="fas fa-exclamation-triangle text-orange-500 mr-2"></i>取消任务
- </div>
- <div class="modal-body">
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>取消原因(必填)</label>
- <textarea id="cancelReason" class="form-textarea" placeholder="请输入取消原因..."></textarea>
- </div>
- </div>
- <div class="modal-footer">
- <button class="btn-cancel" onclick="hideCancelModal()">取消</button>
- <button class="btn-confirm" onclick="confirmCancel()">确认取消</button>
- </div>
- </div>
- </div>
- <!-- 添加联系人模态框 -->
- <div id="addContactModal" class="modal-overlay hidden add-contact-modal">
- <div class="modal-content">
- <div class="modal-header">
- <i class="fas fa-user-plus text-blue-500 mr-2"></i>添加联系人
- </div>
- <div class="modal-body">
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>姓名</label>
- <input type="text" id="newContactName" class="form-input" placeholder="请输入联系人姓名">
- </div>
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>电话</label>
- <input type="tel" id="newContactPhone" class="form-input" placeholder="请输入联系电话">
- </div>
- </div>
- <div class="modal-footer">
- <button class="btn-cancel" onclick="hideAddContactModal()">取消</button>
- <button class="btn-confirm" style="background: #3b82f6;" onclick="confirmAddContact()">添加</button>
- </div>
- </div>
- </div>
- <!-- Toast提示 -->
- <div id="toast" class="hidden"></div>
- </div><!-- salesApp结束 -->
- <!-- 调度端页面 -->
- <div class="app-container" id="dispatchApp">
- <div id="dispatch_homePage" class="page">
- <!-- 顶部欢迎区域 -->
- <div class="bg-gradient-to-r from-blue-500 to-blue-600 px-4 pt-8 pb-6">
- <div class="flex items-center justify-between mb-4">
- <div class="flex items-center">
- <div class="w-12 h-12 bg-white rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-clipboard-list text-blue-500 text-lg"></i>
- </div>
- <div>
- <p class="text-blue-100 text-xs">您好,欢迎回来</p>
- <p class="text-white font-medium">调度中心</p>
- </div>
- </div>
- <button class="w-10 h-10 bg-white/20 rounded-full flex items-center justify-center relative" onclick="goToDispatchPage('dispatch_notificationPage')">
- <i class="fas fa-bell text-white"></i>
- <span class="absolute -top-1 -right-1 w-5 h-5 bg-red-500 rounded-full text-white text-xs flex items-center justify-center">3</span>
- </button>
- </div>
- </div>
- <!-- 主内容区域 -->
- <div class="px-4 -mt-4">
- <!-- 今日任务统计 -->
- <div class="bg-white rounded-xl p-4 mb-4 shadow-sm">
- <h3 class="text-base font-semibold text-gray-800 mb-4">今日任务统计</h3>
- <div class="home-stats-container">
- <div class="stat-card" onclick="goToTaskListFiltered('today')">
- <div class="stat-icon" style="background: #eff6ff; color: #3b82f6;">
- <i class="fas fa-tasks"></i>
- </div>
- <div class="stat-value">15</div>
- <div class="stat-label">今日任务</div>
- </div>
- <div class="stat-card" onclick="goToTaskListFiltered('confirmed')">
- <div class="stat-icon" style="background: #fef9c3; color: #a16207;">
- <i class="fas fa-clock"></i>
- </div>
- <div class="stat-value">5</div>
- <div class="stat-label">待排班</div>
- </div>
- <div class="stat-card" onclick="goToTaskListFiltered('processing')">
- <div class="stat-icon" style="background: #fef2f2; color: #ef4444;">
- <i class="fas fa-exclamation-triangle"></i>
- </div>
- <div class="stat-value">2</div>
- <div class="stat-label">应急中</div>
- </div>
- </div>
- </div>
- <!-- 快捷操作入口 -->
- <div class="quick-entry mb-4">
- <div class="quick-item" onclick="goToDispatchPage('dispatch_schedulePage')">
- <div class="quick-icon" style="background: #eff6ff; color: #3b82f6;">
- <i class="fas fa-calendar-alt"></i>
- </div>
- <span class="quick-text">排班管理</span>
- </div>
- <div class="quick-item" onclick="goToDispatchPage('dispatch_taskPage')">
- <div class="quick-icon" style="background: #fef3c7; color: #f59e0b;">
- <i class="fas fa-tasks"></i>
- </div>
- <span class="quick-text">任务列表</span>
- </div>
- <div class="quick-item" onclick="goToDispatchPage('dispatch_vehicleListPage')">
- <div class="quick-icon" style="background: #d1fae5; color: #10b981;">
- <i class="fas fa-truck"></i>
- </div>
- <span class="quick-text">车辆管理</span>
- </div>
- <div class="quick-item" onclick="goToDispatchPage('dispatch_visualizationPage')">
- <div class="quick-icon" style="background: #fce7f3; color: #ec4899;">
- <i class="fas fa-chart-line"></i>
- </div>
- <span class="quick-text">可视化</span>
- </div>
- </div>
- <!-- 通知公告区块 -->
- <div class="card p-4 mb-4">
- <div class="flex items-center justify-between mb-4 cursor-pointer" onclick="goToDispatchPage('dispatch_noticeListPage')">
- <h2 class="font-bold text-gray-800 flex items-center">
- <i class="fas fa-bullhorn text-blue-500 mr-2"></i>
- 通知公告
- </h2>
- <span class="text-gray-400 text-xs">更多 <i class="fas fa-chevron-right"></i></span>
- </div>
- <div class="space-y-3">
- <div class="pb-3 border-b border-gray-100 cursor-pointer" onclick="goToDispatchPage('dispatch_noticeDetailPage')">
- <p class="text-gray-800 text-sm mb-1">关于调度系统升级的通知</p>
- <p class="text-gray-400 text-xs">2024-01-20</p>
- </div>
- <div class="cursor-pointer" onclick="goToDispatchPage('dispatch_noticeDetailPage')">
- <p class="text-gray-800 text-sm mb-1">春节期间值班安排公告</p>
- <p class="text-gray-400 text-xs">2024-01-15</p>
- </div>
- </div>
- </div>
- <!-- 待审核任务列表 -->
- <div class="bg-white rounded-xl p-4 mb-4 shadow-sm">
- <div class="flex items-center justify-between mb-4">
- <h3 class="text-base font-semibold text-gray-800">待审核任务</h3>
- <span class="text-xs text-blue-500 cursor-pointer" onclick="goToDispatchPage('dispatch_taskPage')">查看全部 <i class="fas fa-chevron-right"></i></span>
- </div>
- <div id="pendingTaskList">
- <!-- 待审核任务卡片 -->
- <div class="task-card border-l-4 border-orange-400 cursor-pointer" onclick="openTaskDetail('T001')">
- <div class="task-header">
- <span class="task-title">积丹白鹭小区疏通</span>
- <span class="tag tag-orange">待审核</span>
- </div>
- <div class="task-info">
- <i class="fas fa-map-marker-alt w-5"></i> 积丹白鹭小区
- </div>
- <div class="task-info">
- <i class="fas fa-clock w-5"></i> 申请时间:今天 09:30
- </div>
- </div>
- <div class="task-card border-l-4 border-orange-400 cursor-pointer" onclick="openTaskDetail('T002')">
- <div class="task-header">
- <span class="task-title">俊发城应急疏通</span>
- <span class="tag tag-orange">待审核</span>
- </div>
- <div class="task-info">
- <i class="fas fa-map-marker-alt w-5"></i> 俊发城住宅区
- </div>
- <div class="task-info">
- <i class="fas fa-clock w-5"></i> 申请时间:今天 10:15
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- ========== 排班页面 ========== -->
- <div id="dispatch_schedulePage" class="page">
- <!-- 顶部区域 - 简洁版 -->
- <div class="bg-white px-4 pt-8 pb-4 shadow-sm">
- <div class="flex items-center justify-between">
- <h1 class="text-xl font-bold text-gray-800">排班管理</h1>
- <div class="flex items-center gap-2">
- <button class="add-btn px-4 py-2 rounded-lg text-sm font-medium" onclick="openAddScheduleModal()">
- <i class="fas fa-plus mr-1"></i>新增
- </button>
- </div>
- </div>
- <div class="flex items-center justify-between mt-4">
- <div class="calendar-nav">
- <button onclick="changeMonth(-1)"><i class="fas fa-chevron-left"></i></button>
- <button onclick="changeMonth(1)"><i class="fas fa-chevron-right"></i></button>
- </div>
- <span class="calendar-title" id="calendarTitle2">2026年4月</span>
- <div style="width: 64px;"></div>
- </div>
- </div>
- <!-- 主内容区域 -->
- <div class="px-4 -mt-2">
- <!-- 资源状态卡片 -->
- <div class="flex gap-3 mb-4 mt-4">
- <div class="resource-card" onclick="goToDispatchPage('dispatch_onDutyStaffPage')">
- <div class="resource-icon">
- <i class="fas fa-users"></i>
- </div>
- <div class="resource-value">12</div>
- <div class="resource-label">在岗人员</div>
- </div>
- <div class="resource-card" onclick="goToDispatchPage('dispatch_availableVehiclesPage')">
- <div class="resource-icon">
- <i class="fas fa-truck"></i>
- </div>
- <div class="resource-value">8</div>
- <div class="resource-label">可用车辆</div>
- </div>
- <div class="resource-card" onclick="goToDispatchPage('dispatch_emergencyStandbyPage')">
- <div class="resource-icon">
- <i class="fas fa-phone-volume"></i>
- </div>
- <div class="resource-value">3</div>
- <div class="resource-label">应急待命</div>
- </div>
- </div>
- <!-- 日历区域 -->
- <div class="calendar-container" style="margin: 0 0 16px 0;">
- <div class="calendar-weekdays">
- <div class="calendar-weekday">一</div>
- <div class="calendar-weekday">二</div>
- <div class="calendar-weekday">三</div>
- <div class="calendar-weekday">四</div>
- <div class="calendar-weekday">五</div>
- <div class="calendar-weekday">六</div>
- <div class="calendar-weekday">日</div>
- </div>
- <div class="calendar-days" id="calendarDays2">
- <!-- JS生成 -->
- </div>
- </div>
- <!-- 当日排班列表 -->
- <div class="pb-4">
- <div class="flex items-center justify-between mb-3">
- <h3 class="text-base font-semibold text-gray-800" id="scheduleListTitle">4月21日 排班</h3>
- <button class="add-btn px-4 py-2 rounded-lg text-sm font-medium" onclick="openAddScheduleModal()">
- <i class="fas fa-plus mr-1"></i>新增
- </button>
- </div>
- <div id="scheduleList">
- <!-- JS生成 -->
- </div>
- </div>
- </div>
- </div>
- <!-- ========== 任务页面 ========== -->
- <div id="dispatch_taskPage" class="page">
- <!-- 顶部区域 -->
- <div class="bg-white px-4 pt-8 pb-4 shadow-sm">
- <div class="flex items-center justify-between">
- <h1 class="text-xl font-bold text-gray-800">任务管理</h1>
- <button class="add-btn px-4 py-2 rounded-lg text-sm font-medium" onclick="goToDispatchPage('dispatch_publishTaskPage')">
- <i class="fas fa-plus mr-1"></i>新增
- </button>
- </div>
- <!-- 任务状态筛选 -->
- <div class="flex gap-2 mt-4 overflow-x-auto pb-2">
- <button class="task-filter active px-4 py-2 rounded-full text-sm whitespace-nowrap bg-blue-500 text-white" onclick="filterTasks('all')">全部</button>
- <button class="task-filter px-4 py-2 rounded-full text-sm whitespace-nowrap bg-gray-100 text-gray-600" onclick="filterTasks('pending')">待审核</button>
- <button class="task-filter px-4 py-2 rounded-full text-sm whitespace-nowrap bg-gray-100 text-gray-600" onclick="filterTasks('confirmed')">待排班</button>
- <button class="task-filter px-4 py-2 rounded-full text-sm whitespace-nowrap bg-gray-100 text-gray-600" onclick="filterTasks('processing')">进行中</button>
- <button class="task-filter px-4 py-2 rounded-full text-sm whitespace-nowrap bg-gray-100 text-gray-600" onclick="filterTasks('completed')">已完成</button>
- <button class="task-filter px-4 py-2 rounded-full text-sm whitespace-nowrap bg-gray-100 text-gray-600" onclick="filterTasks('rejected')">已驳回</button>
- </div>
- </div>
- <!-- 任务列表 -->
- <div class="px-4 py-4" id="taskListContainer">
- <!-- 待审核任务 -->
- <div class="task-card border-l-4 border-orange-400" data-status="pending" onclick="openTaskDetail('T001')">
- <div class="task-header">
- <span class="task-title">积丹白鹭小区疏通</span>
- <span class="tag tag-orange">待审核</span>
- </div>
- <div class="task-info">
- <i class="fas fa-map-marker-alt w-5 text-gray-400"></i> 积丹白鹭小区A栋
- </div>
- <div class="task-info">
- <i class="fas fa-tools w-5 text-gray-400"></i> 油污管疏通
- </div>
- <div class="task-info">
- <i class="fas fa-clock w-5 text-gray-400"></i> 今天 09:30
- </div>
- <div class="flex justify-between items-center mt-2 pt-2 border-t border-gray-100">
- <span class="text-xs text-gray-400">申请人:李明</span>
- <span class="text-xs text-orange-500">需调度安排</span>
- </div>
- </div>
- <div class="task-card border-l-4 border-orange-400" data-status="pending" onclick="openTaskDetail('T002')">
- <div class="task-header">
- <span class="task-title">俊发城应急疏通</span>
- <span class="tag tag-orange">待审核</span>
- </div>
- <div class="task-info">
- <i class="fas fa-map-marker-alt w-5 text-gray-400"></i> 俊发城住宅区
- </div>
- <div class="task-info">
- <i class="fas fa-tools w-5 text-gray-400"></i> 化粪池清理
- </div>
- <div class="task-info">
- <i class="fas fa-clock w-5 text-gray-400"></i> 今天 10:15
- </div>
- <div class="flex justify-between items-center mt-2 pt-2 border-t border-gray-100">
- <span class="text-xs text-gray-400">申请人:王芳</span>
- <span class="text-xs text-orange-500">需调度安排</span>
- </div>
- </div>
- <!-- 进行中任务 -->
- <div class="task-card border-l-4 border-blue-400" data-status="processing" onclick="openTaskDetail('T003')">
- <div class="task-header">
- <span class="task-title">逸安新城日常维护</span>
- <span class="tag tag-blue">进行中</span>
- </div>
- <div class="task-info">
- <i class="fas fa-map-marker-alt w-5 text-gray-400"></i> 逸安新城A区
- </div>
- <div class="task-info">
- <i class="fas fa-users w-5 text-gray-400"></i> 张师傅组 · 疏通车01
- </div>
- <div class="task-info">
- <i class="fas fa-play-circle w-5 text-gray-400"></i> 开始时间:今天 08:00
- </div>
- </div>
- <!-- 已完成任务 -->
- <div class="task-card border-l-4 border-green-400" data-status="completed" onclick="openTaskDetail('T004')">
- <div class="task-header">
- <span class="task-title">富源同坐管道检修</span>
- <span class="tag tag-green">已完成</span>
- </div>
- <div class="task-info">
- <i class="fas fa-map-marker-alt w-5 text-gray-400"></i> 富源同坐商业广场
- </div>
- <div class="task-info">
- <i class="fas fa-users w-5 text-gray-400"></i> 王师傅组 · 吸污车03
- </div>
- <div class="task-info">
- <i class="fas fa-check-circle w-5 text-gray-400"></i> 完成时间:昨天 16:30
- </div>
- </div>
- <!-- 已驳回任务 -->
- <div class="task-card border-l-4 border-red-400" data-status="rejected" onclick="openTaskDetail('T005')">
- <div class="task-header">
- <span class="task-title">云岩大厦排污</span>
- <span class="tag tag-red">已驳回</span>
- </div>
- <div class="task-info">
- <i class="fas fa-map-marker-alt w-5 text-gray-400"></i> 云岩大厦
- </div>
- <div class="task-info">
- <i class="fas fa-clock w-5 text-gray-400"></i> 申请时间:昨天 14:20
- </div>
- <div class="task-info text-red-500">
- <i class="fas fa-info-circle w-5"></i> 驳回原因:设备临时故障
- </div>
- </div>
- <!-- 待排班任务 -->
- <div class="task-card border-l-4 border-yellow-400" data-status="confirmed" onclick="openTaskDetail('T006')">
- <div class="task-header">
- <span class="task-title">新都国际管道维修</span>
- <span class="tag tag-yellow">待排班</span>
- </div>
- <div class="task-info">
- <i class="fas fa-map-marker-alt w-5 text-gray-400"></i> 新都国际小区
- </div>
- <div class="task-info">
- <i class="fas fa-tools w-5 text-gray-400"></i> 管道维修
- </div>
- <div class="task-info">
- <i class="fas fa-clock w-5 text-gray-400"></i> 今天 11:00
- </div>
- <div class="flex justify-between items-center mt-2 pt-2 border-t border-gray-100">
- <span class="text-xs text-gray-400">申请人:周经理</span>
- <span class="text-xs text-yellow-600">待安排班组</span>
- </div>
- </div>
- </div>
- </div>
- <!-- ========== 我的页面 ========== -->
- <div id="dispatch_myPage" class="page">
- <!-- 顶部用户信息区域 -->
- <div class="bg-gradient-to-br from-blue-900 to-blue-800 text-white pt-10 pb-6 px-5">
- <div class="flex items-center gap-4">
- <div class="w-14 h-14 bg-white/20 rounded-full flex items-center justify-center text-2xl">
- <i class="fas fa-user"></i>
- </div>
- <div>
- <h2 class="text-lg font-bold">张调度</h2>
- <p class="text-blue-200 text-xs">调度中心 · 工号 DIS001</p>
- </div>
- </div>
- </div>
- <!-- 功能列表 -->
- <div class="px-4 -mt-3 space-y-4 pb-4">
- <!-- 基本信息卡片 -->
- <div class="bg-white rounded-xl p-4 shadow-sm">
- <div class="flex justify-between items-center py-2 border-b border-gray-100 cursor-pointer" onclick="showToast('查看基本信息')">
- <span class="text-gray-500 text-sm"><i class="fas fa-building w-5 text-blue-400"></i>部门</span>
- <span class="text-sm">调度中心</span>
- </div>
- <div class="flex justify-between items-center py-2 border-b border-gray-100">
- <span class="text-gray-500 text-sm"><i class="fas fa-id-badge w-5 text-blue-400"></i>职位</span>
- <span class="text-sm">调度主管</span>
- </div>
- <div class="flex justify-between items-center py-2">
- <span class="text-gray-500 text-sm"><i class="fas fa-phone w-5 text-blue-400"></i>电话</span>
- <span class="text-sm">139****6666</span>
- </div>
- </div>
- <!-- 功能入口卡片 -->
- <div class="bg-white rounded-xl p-4 shadow-sm">
- <div class="flex justify-between items-center py-3 border-b border-gray-100 cursor-pointer" onclick="goToDispatchPage('dispatch_basicInfoPage')">
- <span class="text-sm text-gray-700"><i class="fas fa-user-circle text-gray-400 w-6"></i>基本信息</span>
- <i class="fas fa-chevron-right text-gray-300 text-xs"></i>
- </div>
- <div class="flex justify-between items-center py-3 border-b border-gray-100 cursor-pointer" onclick="goToDispatchPage('dispatch_changePasswordPage')">
- <span class="text-sm text-gray-700"><i class="fas fa-lock text-gray-400 w-6"></i>修改密码</span>
- <i class="fas fa-chevron-right text-gray-300 text-xs"></i>
- </div>
- <div class="flex justify-between items-center py-3 border-b border-gray-100 cursor-pointer" onclick="goToDispatchPage('dispatch_notificationPage')">
- <span class="text-sm text-gray-700"><i class="fas fa-bell text-gray-400 w-6"></i>消息通知</span>
- <div class="flex items-center">
- <span class="w-2 h-2 bg-red-500 rounded-full mr-2"></span>
- <i class="fas fa-chevron-right text-gray-300 text-xs"></i>
- </div>
- </div>
- <div class="flex justify-between items-center py-3 cursor-pointer" onclick="goToDispatchPage('dispatch_helpCenterPage')">
- <span class="text-sm text-gray-700"><i class="fas fa-question-circle text-gray-400 w-6"></i>帮助中心</span>
- <i class="fas fa-chevron-right text-gray-300 text-xs"></i>
- </div>
- </div>
- <!-- 退出登录按钮 -->
- <button class="w-full py-3 mt-4 bg-red-500 text-white rounded-xl font-medium cursor-pointer active:bg-red-600 transition-colors" onclick="backToLogin()">
- 退出登录
- </button>
- </div>
- </div>
- <!-- ========== 基本信息页 ========== -->
- <div id="dispatch_basicInfoPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToDispatchPage('dispatch_myPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">基本信息</h1>
- </div>
- </div>
- <!-- 基本信息内容 -->
- <div class="px-4 py-4">
- <div class="bg-white rounded-xl p-4 shadow-sm">
- <div class="flex items-center justify-between py-3 border-b border-gray-100">
- <span class="text-gray-500 text-sm"><i class="fas fa-user w-5 text-blue-400"></i>姓名</span>
- <span class="text-sm text-gray-800">张调度</span>
- </div>
- <div class="flex items-center justify-between py-3 border-b border-gray-100">
- <span class="text-gray-500 text-sm"><i class="fas fa-building w-5 text-blue-400"></i>部门</span>
- <span class="text-sm text-gray-800">调度中心</span>
- </div>
- <div class="flex items-center justify-between py-3 border-b border-gray-100">
- <span class="text-gray-500 text-sm"><i class="fas fa-id-badge w-5 text-blue-400"></i>职位</span>
- <span class="text-sm text-gray-800">调度主管</span>
- </div>
- <div class="flex items-center justify-between py-3 border-b border-gray-100">
- <span class="text-gray-500 text-sm"><i class="fas fa-id-card w-5 text-blue-400"></i>工号</span>
- <span class="text-sm text-gray-800">DIS001</span>
- </div>
- <div class="flex items-center justify-between py-3 border-b border-gray-100">
- <span class="text-gray-500 text-sm"><i class="fas fa-phone w-5 text-blue-400"></i>电话</span>
- <span class="text-sm text-gray-800">139****6666</span>
- </div>
- <div class="flex items-center justify-between py-3 border-b border-gray-100">
- <span class="text-gray-500 text-sm"><i class="fas fa-envelope w-5 text-blue-400"></i>邮箱</span>
- <span class="text-sm text-gray-800">zhang@qingdaofu.com</span>
- </div>
- <div class="flex items-center justify-between py-3">
- <span class="text-gray-500 text-sm"><i class="fas fa-calendar w-5 text-blue-400"></i>入职日期</span>
- <span class="text-sm text-gray-800">2022-03-15</span>
- </div>
- </div>
- <div class="mt-4">
- <button class="w-full py-3 bg-blue-500 text-white rounded-xl font-medium" onclick="showToast('编辑功能开发中')">
- <i class="fas fa-edit mr-2"></i>编辑信息
- </button>
- </div>
- </div>
- </div>
- <!-- ========== 修改密码页 ========== -->
- <div id="dispatch_changePasswordPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToDispatchPage('dispatch_myPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">修改密码</h1>
- </div>
- </div>
- <!-- 修改密码表单 -->
- <div class="px-4 py-4">
- <div class="bg-white rounded-xl p-4 shadow-sm">
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>当前密码</label>
- <input type="password" id="dispatchCurrentPassword" class="form-input" placeholder="请输入当前密码">
- </div>
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>新密码</label>
- <input type="password" id="dispatchNewPassword" class="form-input" placeholder="请输入新密码(6-20位)">
- </div>
- <div class="form-group mb-0">
- <label class="form-label"><span class="text-red-500">*</span>确认新密码</label>
- <input type="password" id="dispatchConfirmNewPassword" class="form-input" placeholder="请再次输入新密码">
- </div>
- <div class="mt-4">
- <div class="bg-blue-50 rounded-lg p-3 mb-4">
- <p class="text-blue-600 text-sm"><i class="fas fa-info-circle mr-1"></i>密码要求:</p>
- <ul class="text-gray-500 text-xs mt-2 space-y-1">
- <li>• 长度6-20位</li>
- <li>• 必须包含字母和数字</li>
- <li>• 不能与当前密码相同</li>
- </ul>
- </div>
- <button class="w-full py-3 bg-blue-500 text-white rounded-xl font-medium" onclick="submitDispatchChangePassword()">
- 确认修改
- </button>
- </div>
- </div>
- </div>
- </div>
- <!-- ========== 帮助中心页 ========== -->
- <div id="dispatch_helpCenterPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToDispatchPage('dispatch_myPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">帮助中心</h1>
- </div>
- </div>
- <!-- 帮助中心内容 -->
- <div class="px-4 py-4">
- <!-- 常见问题 -->
- <div class="bg-white rounded-xl p-4 mb-4 shadow-sm">
- <h3 class="text-base font-semibold text-gray-800 mb-4"><i class="fas fa-question-circle text-blue-500 mr-2"></i>常见问题</h3>
- <div class="space-y-3">
- <div class="border-b border-gray-100 pb-3">
- <div class="flex justify-between items-center cursor-pointer" onclick="toggleDispatchFaq(this)">
- <span class="text-sm text-gray-700">如何审核任务工单?</span>
- <i class="fas fa-chevron-down text-gray-400 text-xs"></i>
- </div>
- <div class="hidden mt-2 text-gray-500 text-sm">
- 进入"任务"页面,点击待审核任务卡片,查看详情后点击"确认"或"驳回"按钮即可。
- </div>
- </div>
- <div class="border-b border-gray-100 pb-3">
- <div class="flex justify-between items-center cursor-pointer" onclick="toggleDispatchFaq(this)">
- <span class="text-sm text-gray-700">如何安排班组和车辆?</span>
- <i class="fas fa-chevron-down text-gray-400 text-xs"></i>
- </div>
- <div class="hidden mt-2 text-gray-500 text-sm">
- 在任务详情页确认任务后,选择可用的班组和车辆进行分配。
- </div>
- </div>
- <div class="border-b border-gray-100 pb-3">
- <div class="flex justify-between items-center cursor-pointer" onclick="toggleDispatchFaq(this)">
- <span class="text-sm text-gray-700">如何查看资源状态?</span>
- <i class="fas fa-chevron-down text-gray-400 text-xs"></i>
- </div>
- <div class="hidden mt-2 text-gray-500 text-sm">
- 在首页或"排班"页面可以查看人员、车辆的实时状态和可用情况。
- </div>
- </div>
- <div class="border-b border-gray-100 pb-3">
- <div class="flex justify-between items-center cursor-pointer" onclick="toggleDispatchFaq(this)">
- <span class="text-sm text-gray-700">如何创建月计划排班?</span>
- <i class="fas fa-chevron-down text-gray-400 text-xs"></i>
- </div>
- <div class="hidden mt-2 text-gray-500 text-sm">
- 在"排班"页面点击"添加排班",选择日期和班组车辆,设置为"月计划"类型即可。
- </div>
- </div>
- <div>
- <div class="flex justify-between items-center cursor-pointer" onclick="toggleDispatchFaq(this)">
- <span class="text-sm text-gray-700">如何联系相关人员?</span>
- <i class="fas fa-chevron-down text-gray-400 text-xs"></i>
- </div>
- <div class="hidden mt-2 text-gray-500 text-sm">
- 可以在任务详情中查看申请人联系方式,或通过调度中心电话联系施工班组。
- </div>
- </div>
- </div>
- </div>
- <!-- 联系客服 -->
- <div class="bg-white rounded-xl p-4 shadow-sm">
- <h3 class="text-base font-semibold text-gray-800 mb-4"><i class="fas fa-headset text-green-500 mr-2"></i>联系支持</h3>
- <div class="flex items-center justify-between py-3 border-b border-gray-100">
- <div class="flex items-center">
- <i class="fas fa-phone text-blue-500 mr-3"></i>
- <span class="text-sm text-gray-700">技术支持</span>
- </div>
- <span class="text-blue-500 text-sm">400-888-8888</span>
- </div>
- <div class="flex items-center justify-between py-3 border-b border-gray-100">
- <div class="flex items-center">
- <i class="fas fa-envelope text-blue-500 mr-3"></i>
- <span class="text-sm text-gray-700">电子邮箱</span>
- </div>
- <span class="text-gray-600 text-sm">support@qingdaofu.com</span>
- </div>
- <div class="flex items-center justify-between py-3">
- <div class="flex items-center">
- <i class="fas fa-clock text-blue-500 mr-3"></i>
- <span class="text-sm text-gray-700">服务时间</span>
- </div>
- <span class="text-gray-600 text-sm">7×24小时</span>
- </div>
- </div>
- </div>
- </div>
- <!-- ========== 通知公告列表页 ========== -->
- <div id="dispatch_noticeListPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToDispatchPage('dispatch_homePage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">通知公告</h1>
- </div>
- </div>
- <!-- 公告列表 -->
- <div class="bg-white">
- <div class="notice-item" onclick="goToDispatchPage('dispatch_noticeDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <h3 class="font-medium text-gray-800 flex-1 pr-2">关于调度系统升级的通知</h3>
- <span class="text-gray-400 text-xs whitespace-nowrap">01-20</span>
- </div>
- <p class="text-gray-500 text-sm line-clamp-2">为提升系统性能和服务稳定性,计划于近期进行系统升级...</p>
- </div>
- <div class="notice-item" onclick="goToDispatchPage('dispatch_noticeDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <h3 class="font-medium text-gray-800 flex-1 pr-2">春节期间值班安排公告</h3>
- <span class="text-gray-400 text-xs whitespace-nowrap">01-15</span>
- </div>
- <p class="text-gray-500 text-sm line-clamp-2">根据国家法定节假日安排,结合公司实际情况,现对春节期间的服务工作进行如下调整...</p>
- </div>
- <div class="notice-item" onclick="goToDispatchPage('dispatch_noticeDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <h3 class="font-medium text-gray-800 flex-1 pr-2">新增服务类型标准说明</h3>
- <span class="text-gray-400 text-xs whitespace-nowrap">01-10</span>
- </div>
- <p class="text-gray-500 text-sm line-clamp-2">为更好地满足客户需求,公司新增了高压水射流清洗和CCTV管道检测两项服务...</p>
- </div>
- </div>
- </div>
- <!-- ========== 通知公告详情页 ========== -->
- <div id="dispatch_noticeDetailPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToDispatchPage('dispatch_noticeListPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">公告详情</h1>
- </div>
- </div>
- <!-- 详情内容 -->
- <div class="px-4 py-4">
- <div class="card p-4">
- <h2 class="text-lg font-bold text-gray-800 mb-2">关于调度系统升级的通知</h2>
- <p class="text-gray-400 text-sm mb-4"><i class="far fa-clock mr-1"></i>2024-01-20 10:30</p>
- <div class="border-t border-gray-100 pt-4">
- <p class="text-gray-600 text-sm leading-relaxed mb-4">
- 各位调度同事:
- </p>
- <p class="text-gray-600 text-sm leading-relaxed mb-4">
- 为提升系统性能和服务稳定性,计划于近期进行系统升级。现将有关事项通知如下:
- </p>
- <p class="text-gray-600 text-sm leading-relaxed mb-4">
- <strong>一、升级时间</strong><br>
- 预计升级时间:2024年1月25日 凌晨00:00-06:00
- </p>
- <p class="text-gray-600 text-sm leading-relaxed mb-4">
- <strong>二、升级内容</strong><br>
- 1. 优化任务调度算法<br>
- 2. 新增排班管理功能<br>
- 3. 完善消息通知系统
- </p>
- <p class="text-gray-600 text-sm leading-relaxed mb-4">
- <strong>三、注意事项</strong><br>
- 升级期间系统暂停服务,请提前做好相关工作安排。
- </p>
- <p class="text-gray-600 text-sm leading-relaxed">
- 如有疑问,请联系技术支持。
- </p>
- <p class="text-gray-500 text-sm leading-relaxed mt-4 text-right">
- 调度管理中心<br>
- 2024年1月20日
- </p>
- </div>
- </div>
- </div>
- </div>
- <!-- ========== 在岗人员页 ========== -->
- <div id="dispatch_onDutyStaffPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToDispatchPage('dispatch_schedulePage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">在岗人员</h1>
- </div>
- </div>
- <!-- 人员列表 -->
- <div class="px-4 py-4">
- <div class="space-y-3">
- <div class="card p-4">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <div class="w-12 h-12 bg-blue-100 rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-user text-blue-500"></i>
- </div>
- <div>
- <p class="font-medium text-gray-800">张三</p>
- <p class="text-sm text-gray-500">工程一班 · 班组长</p>
- </div>
- </div>
- <span class="tag tag-green">在岗</span>
- </div>
- <div class="info-expansion">
- <div class="info-expansion-item">
- <span class="label">班组成员</span>
- <span class="value">张三(组长)、李四、王五</span>
- </div>
- <div class="info-expansion-item">
- <span class="label">技能等级</span>
- <span class="value"><span class="tag tag-green text-xs">高级</span></span>
- </div>
- <div class="info-expansion-item">
- <span class="label">持有资质</span>
- <span class="value"><span class="qualification-tag">高压电工</span><span class="qualification-tag">有限空间</span></span>
- </div>
- </div>
- </div>
- <div class="card p-4">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <div class="w-12 h-12 bg-green-100 rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-user text-green-500"></i>
- </div>
- <div>
- <p class="font-medium text-gray-800">李四</p>
- <p class="text-sm text-gray-500">工程一班 · 队员</p>
- </div>
- </div>
- <span class="tag tag-green">在岗</span>
- </div>
- </div>
- <div class="card p-4">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <div class="w-12 h-12 bg-purple-100 rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-user text-purple-500"></i>
- </div>
- <div>
- <p class="font-medium text-gray-800">王五</p>
- <p class="text-sm text-gray-500">工程二班 · 班组长</p>
- </div>
- </div>
- <span class="tag tag-green">在岗</span>
- </div>
- </div>
- <div class="card p-4">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <div class="w-12 h-12 bg-orange-100 rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-user text-orange-500"></i>
- </div>
- <div>
- <p class="font-medium text-gray-800">赵六</p>
- <p class="text-sm text-gray-500">工程二班 · 队员</p>
- </div>
- </div>
- <span class="tag tag-green">在岗</span>
- </div>
- </div>
- <div class="card p-4">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <div class="w-12 h-12 bg-red-100 rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-user text-red-500"></i>
- </div>
- <div>
- <p class="font-medium text-gray-800">刘七</p>
- <p class="text-sm text-gray-500">工程三班 · 班组长</p>
- </div>
- </div>
- <span class="tag tag-blue">休息</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- ========== 可用车辆页 ========== -->
- <div id="dispatch_availableVehiclesPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToDispatchPage('dispatch_schedulePage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">可用车辆</h1>
- </div>
- </div>
- <!-- 车辆列表 -->
- <div class="px-4 py-4">
- <div class="space-y-3">
- <div class="card p-4">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <div class="w-12 h-12 bg-green-100 rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-truck text-green-500"></i>
- </div>
- <div>
- <p class="font-medium text-gray-800">疏通车01</p>
- <p class="text-sm text-gray-500">贵A81356</p>
- </div>
- </div>
- <span class="tag tag-green">空闲</span>
- </div>
- <div class="info-expansion">
- <div class="info-expansion-item">
- <span class="label">车辆类型</span>
- <span class="value">联合疏通车</span>
- </div>
- <div class="info-expansion-item">
- <span class="label">车辆尺寸</span>
- <span class="value">7.2×2.3×2.8m</span>
- </div>
- <div class="info-expansion-item">
- <span class="label">空载/满载</span>
- <span class="value">6.5t / 12t</span>
- </div>
- <div class="info-expansion-item">
- <span class="label">驾驶员</span>
- <span class="value">张师傅</span>
- </div>
- </div>
- </div>
- <div class="card p-4">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <div class="w-12 h-12 bg-green-100 rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-truck text-green-500"></i>
- </div>
- <div>
- <p class="font-medium text-gray-800">疏通车02</p>
- <p class="text-sm text-gray-500">贵A82345</p>
- </div>
- </div>
- <span class="tag tag-green">空闲</span>
- </div>
- </div>
- <div class="card p-4">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <div class="w-12 h-12 bg-orange-100 rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-truck text-orange-500"></i>
- </div>
- <div>
- <p class="font-medium text-gray-800">吸污车03</p>
- <p class="text-sm text-gray-500">贵A83456</p>
- </div>
- </div>
- <span class="tag tag-orange">使用中</span>
- </div>
- </div>
- <div class="card p-4">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <div class="w-12 h-12 bg-green-100 rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-truck text-green-500"></i>
- </div>
- <div>
- <p class="font-medium text-gray-800">吸污车04</p>
- <p class="text-sm text-gray-500">贵A84567</p>
- </div>
- </div>
- <span class="tag tag-green">空闲</span>
- </div>
- </div>
- <div class="card p-4">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <div class="w-12 h-12 bg-blue-100 rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-truck text-blue-500"></i>
- </div>
- <div>
- <p class="font-medium text-gray-800">高压清洗车05</p>
- <p class="text-sm text-gray-500">贵A85678</p>
- </div>
- </div>
- <span class="tag tag-green">空闲</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- ========== 应急待命页 ========== -->
- <div id="dispatch_emergencyStandbyPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToDispatchPage('dispatch_schedulePage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">应急待命</h1>
- </div>
- </div>
- <!-- 应急待命信息 -->
- <div class="px-4 py-4">
- <div class="card p-4 mb-4">
- <div class="flex items-center mb-3">
- <div class="w-10 h-10 bg-red-100 rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-phone-volume text-red-500"></i>
- </div>
- <div>
- <p class="font-medium text-gray-800">应急调度热线</p>
- <p class="text-sm text-gray-500">24小时畅通</p>
- </div>
- </div>
- <p class="text-gray-600 text-sm">紧急情况下,请立即拨打应急热线:400-888-8888</p>
- </div>
- <h3 class="text-base font-semibold text-gray-800 mb-3">待命班组</h3>
- <div class="space-y-3">
- <div class="card p-4">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <div class="w-12 h-12 bg-red-100 rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-users text-red-500"></i>
- </div>
- <div>
- <p class="font-medium text-gray-800">应急一班</p>
- <p class="text-sm text-gray-500">组长:陈师傅</p>
- </div>
- </div>
- <span class="tag tag-orange">待命</span>
- </div>
- <div class="mt-3 pt-3 border-t border-gray-100 flex justify-between items-center">
- <span class="text-sm text-gray-500"><i class="fas fa-truck w-4 inline-block"></i>疏通车03 · 贵A89999</span>
- <button class="px-3 py-1 bg-green-500 text-white rounded-lg text-xs">
- <i class="fas fa-phone-alt mr-1"></i>联系
- </button>
- </div>
- </div>
- <div class="card p-4">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <div class="w-12 h-12 bg-orange-100 rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-users text-orange-500"></i>
- </div>
- <div>
- <p class="font-medium text-gray-800">应急二班</p>
- <p class="text-sm text-gray-500">组长:周师傅</p>
- </div>
- </div>
- <span class="tag tag-orange">待命</span>
- </div>
- <div class="mt-3 pt-3 border-t border-gray-100 flex justify-between items-center">
- <span class="text-sm text-gray-500"><i class="fas fa-truck w-4 inline-block"></i>高压清洗车02 · 贵A87777</span>
- <button class="px-3 py-1 bg-green-500 text-white rounded-lg text-xs">
- <i class="fas fa-phone-alt mr-1"></i>联系
- </button>
- </div>
- </div>
- <div class="card p-4">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <div class="w-12 h-12 bg-yellow-100 rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-users text-yellow-600"></i>
- </div>
- <div>
- <p class="font-medium text-gray-800">应急三班</p>
- <p class="text-sm text-gray-500">组长:吴师傅</p>
- </div>
- </div>
- <span class="tag tag-orange">待命</span>
- </div>
- <div class="mt-3 pt-3 border-t border-gray-100 flex justify-between items-center">
- <span class="text-sm text-gray-500"><i class="fas fa-truck w-4 inline-block"></i>吸污车05 · 贵A86666</span>
- <button class="px-3 py-1 bg-green-500 text-white rounded-lg text-xs">
- <i class="fas fa-phone-alt mr-1"></i>联系
- </button>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- ========== 发布任务页 ========== -->
- <div id="dispatch_publishTaskPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToDispatchPage('dispatch_taskPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">发布任务</h1>
- </div>
- </div>
- </div>
- <!-- 页面内容 -->
- <div class="px-4 py-4 pb-24">
- <!-- 板块一:项目基本信息 -->
- <div class="card p-4 mb-4" id="dispatchSectionProject">
- <!-- 板块标题 -->
- <div class="flex items-center mb-4">
- <div class="w-8 h-8 bg-blue-100 rounded-lg flex items-center justify-center mr-3">
- <i class="fas fa-building text-blue-500"></i>
- </div>
- <h2 class="text-base font-semibold text-gray-800">项目基本信息</h2>
- </div>
- <!-- 项目选择提示 -->
- <div id="dispatchProjectSelectHint" class="bg-blue-50 rounded-lg px-3 py-2 mb-4 flex items-center">
- <i class="fas fa-info-circle text-blue-500 mr-2 text-sm"></i>
- <span class="text-blue-600 text-sm" id="dispatchProjectHintText">请从项目库选择或新增项目</span>
- </div>
- <!-- 项目选择 -->
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>选择项目</label>
- <select id="dispatchProjectSelect" class="form-select" onchange="dispatchOnProjectSelectChange()">
- <option value="">请选择项目</option>
- <option value="积丹白鹭">积丹白鹭</option>
- <option value="富源同坐">富源同坐</option>
- <option value="俊发城">俊发城</option>
- <option value="逸安新城A区">逸安新城A区</option>
- <option value="逸安新城B区">逸安新城B区</option>
- <option value="new">+ 新增项目</option>
- </select>
- </div>
- <!-- 已选项目信息(自动带出) -->
- <div id="dispatchProjectAutoInfo" class="bg-green-50 rounded-xl p-3" style="display: none;">
- <div class="flex items-center justify-between mb-3">
- <span class="text-green-600 text-sm font-medium">
- <i class="fas fa-check-circle mr-1"></i>已选择:<span id="dispatchSelectedProjectName"></span>
- </span>
- <button class="text-green-500 text-xs" onclick="dispatchResetProjectSelection()">重新选择</button>
- </div>
- <div class="space-y-2">
- <div class="flex justify-between text-sm">
- <span class="text-gray-500">合作类型:</span>
- <span class="text-gray-700" id="dispatchAutoCoopType">-</span>
- </div>
- <div class="flex justify-between text-sm">
- <span class="text-gray-500">设施类型:</span>
- <span class="text-gray-700" id="dispatchAutoFacilityType">-</span>
- </div>
- <div class="flex justify-between text-sm">
- <span class="text-gray-500">项目地址:</span>
- <span class="text-gray-700" id="dispatchAutoProjectAddress">-</span>
- </div>
- </div>
- </div>
- <!-- 新增项目表单 -->
- <div id="dispatchNewProjectForm" style="display: none;">
- <div class="bg-orange-50 rounded-lg px-3 py-2 mb-4 flex items-center">
- <i class="fas fa-edit text-orange-500 mr-2 text-sm"></i>
- <span class="text-orange-600 text-sm">新增项目 - 请填写以下信息</span>
- </div>
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>项目名称</label>
- <input type="text" id="dispatchNewProjectName" class="form-input" placeholder="请输入项目名称">
- </div>
- <div class="inline-selector mb-4">
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>合作类型</label>
- <select id="dispatchNewCoopType" class="form-select">
- <option value="">请选择</option>
- <option value="包年">包年</option>
- <option value="单次">单次</option>
- <option value="季度">季度</option>
- <option value="月付">月付</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>设施类型</label>
- <select id="dispatchNewFacilityType" class="form-select">
- <option value="">请选择</option>
- <option value="住宅">住宅</option>
- <option value="商业">商业</option>
- <option value="工业">工业</option>
- <option value="市政">市政</option>
- </select>
- </div>
- </div>
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>项目地址</label>
- <input type="text" id="dispatchNewProjectAddress" class="form-input" placeholder="请输入项目地址">
- </div>
- </div>
- <!-- 联系人列表 -->
- <div class="form-group mb-0">
- <label class="form-label">联系人</label>
- <div id="dispatchContactListContainer">
- <!-- 联系人列表动态生成 -->
- </div>
- <button type="button" class="add-item-btn mt-2" onclick="dispatchAddContactItem()">
- <i class="fas fa-plus"></i> 添加联系人
- </button>
- </div>
- </div>
- <!-- 板块二:服务信息 -->
- <div class="card p-4" id="dispatchSectionService">
- <!-- 板块标题 -->
- <div class="flex items-center mb-4">
- <div class="w-8 h-8 bg-purple-100 rounded-lg flex items-center justify-center mr-3">
- <i class="fas fa-tools text-purple-500"></i>
- </div>
- <h2 class="text-base font-semibold text-gray-800">服务信息</h2>
- </div>
- <!-- 服务时间 -->
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>服务时间</label>
- <div class="datetime-input">
- <input type="date" id="dispatchServiceDate" class="form-input">
- <input type="time" id="dispatchServiceTime" class="form-input" style="flex: 0.6;">
- </div>
- </div>
- <!-- 故障位置 -->
- <div class="form-group">
- <div class="auto-filled-label" id="dispatchFaultLocationLabel" style="display: none;">
- <i class="fas fa-magic mr-1"></i>已自动填充
- </div>
- <label class="form-label"><span class="text-red-500">*</span>故障位置</label>
- <input type="text" id="dispatchFaultLocation" class="form-input" placeholder="请输入故障位置">
- </div>
- <!-- 地理位置(地图) -->
- <div class="form-group">
- <label class="form-label">地理位置</label>
- <div class="bg-gray-100 rounded-xl h-24 flex items-center justify-center border border-gray-200 cursor-pointer" onclick="showToast('地图定位功能开发中')">
- <div class="text-center">
- <i class="fas fa-map-marked-alt text-gray-400 text-2xl mb-1"></i>
- <p class="text-gray-400 text-xs">点击获取当前位置</p>
- </div>
- </div>
- </div>
- <!-- 故障描述 -->
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>故障描述</label>
- <textarea id="dispatchFaultDesc" class="form-textarea" placeholder="请详细描述故障情况..."></textarea>
- </div>
- <!-- 故障图片/视频 -->
- <div class="form-group">
- <label class="form-label">故障图片/视频</label>
- <div class="border-2 border-dashed border-gray-200 rounded-xl p-6 text-center cursor-pointer" onclick="showToast('上传功能开发中')">
- <i class="fas fa-cloud-upload-alt text-gray-300 text-2xl mb-2"></i>
- <p class="text-gray-400 text-sm">点击上传图片或视频</p>
- <p class="text-gray-300 text-xs mt-1">支持 JPG、PNG、MP4 格式</p>
- </div>
- </div>
- <!-- 施工类型 & 施工设施(一行) -->
- <div class="inline-selector mb-4">
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>施工类型</label>
- <select id="dispatchServiceType" class="form-select">
- <option value="">请选择</option>
- <option value="疏通">疏通</option>
- <option value="清淤">清淤</option>
- <option value="排查">排查</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>施工设施</label>
- <select id="dispatchServiceFacilityType" class="form-select">
- <option value="">请选择</option>
- <option value="PVC">PVC</option>
- <option value="直抽直排">直抽直排</option>
- <option value="油污">油污</option>
- <option value="排污">排污</option>
- <option value="油污管">油污管</option>
- <option value="化粪池">化粪池</option>
- </select>
- </div>
- </div>
- <!-- 服务方式 & 建议出车(一行) -->
- <div class="inline-selector mb-4">
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>服务方式</label>
- <select id="dispatchServiceMode" class="form-select">
- <option value="">请选择</option>
- <option value="应急">应急</option>
- <option value="月计划">月计划</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>建议出车</label>
- <select id="dispatchVehicleType" class="form-select">
- <option value="">请选择</option>
- <option value="疏通车">疏通车</option>
- <option value="吸污车">吸污车</option>
- <option value="高压清洗车">高压清洗车</option>
- </select>
- </div>
- </div>
- <!-- 取水距离 & 化粪池排口是否正常(一行) -->
- <div class="inline-selector mb-4">
- <div class="form-group">
- <label class="form-label">取水距离</label>
- <select id="dispatchWaterSource" class="form-select">
- <option value="">请选择</option>
- <option value="有消防水">有消防水</option>
- <option value="无消防水">无消防水</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label">化粪池排口是否正常</label>
- <select id="dispatchSepticTank" class="form-select">
- <option value="">请选择</option>
- <option value="是">是</option>
- <option value="否">否</option>
- </select>
- </div>
- </div>
- <!-- 施工助力信息(非必填,多行文本) -->
- <div class="form-group">
- <label class="form-label">施工助力信息</label>
- <textarea id="dispatchConstructionHelp" class="form-textarea" placeholder="如地库限高、需搭脚手架、登高作业等"></textarea>
- </div>
- <!-- 预计作业量 & 预计工时(一行) -->
- <div class="inline-selector mb-4">
- <div class="form-group">
- <label class="form-label">预计作业量</label>
- <input type="text" id="dispatchEstimatedQuantity" class="form-input" placeholder="如 2个堵点">
- </div>
- <div class="form-group">
- <label class="form-label">预计工时</label>
- <input type="text" id="dispatchEstimatedHours" class="form-input" placeholder="如 2小时">
- </div>
- </div>
- <!-- 验收要求 & 是否有前期施工关联(一行) -->
- <div class="inline-selector mb-4">
- <div class="form-group">
- <label class="form-label">验收要求</label>
- <input type="text" id="dispatchAcceptanceReq" class="form-input" placeholder="如 正常走水">
- </div>
- <div class="form-group">
- <label class="form-label">是否有前期施工关联</label>
- <select id="dispatchPreviousConstruction" class="form-select">
- <option value="">请选择</option>
- <option value="是">是</option>
- <option value="否">否</option>
- </select>
- </div>
- </div>
- <!-- 验收方式 -->
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>验收方式</label>
- <select id="dispatchAcceptType" class="form-select">
- <option value="">请选择</option>
- <option value="签署验收计量单">签署验收计量单</option>
- <option value="累计自动计费">累计自动计费</option>
- </select>
- </div>
- <!-- 甲方当事人 -->
- <div class="form-group">
- <label class="form-label"><span class="text-red-500">*</span>甲方当事人</label>
- <div id="dispatchPartyAContactList">
- <!-- 联系人列表动态生成 -->
- </div>
- <button type="button" class="add-item-btn mt-2" onclick="dispatchAddPartyAContact()">
- <i class="fas fa-plus"></i> 添加甲方当事人
- </button>
- </div>
- <!-- 备注 -->
- <div class="form-group mb-0">
- <label class="form-label">备注</label>
- <textarea id="dispatchRemark" class="form-textarea" placeholder="如有其他要求请备注..."></textarea>
- </div>
- </div>
- </div>
- <!-- 底部固定提交按钮 -->
- <div class="fixed bottom-0 left-1/2 transform -translate-x-1/2 w-full max-w-[430px] bg-white border-t border-gray-100 p-4 z-20">
- <button class="w-full py-3 bg-blue-500 text-white rounded-xl font-medium text-base" onclick="dispatchSubmitTask()">
- <i class="fas fa-paper-plane mr-2"></i>提交任务
- </button>
- </div>
- </div>
- <!-- ========== 任务详情页 ========== -->
- <div id="dispatch_taskDetailPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToDispatchPage('dispatch_taskPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">任务详情</h1>
- </div>
- </div>
- </div>
- <!-- 任务详情内容 -->
- <div class="px-4 py-4 pb-32">
- <!-- 基本信息卡片 -->
- <div class="bg-white rounded-xl p-4 shadow-sm mb-4">
- <div class="flex items-center justify-between mb-4">
- <h3 class="text-base font-semibold text-gray-800">基本信息</h3>
- <span class="tag tag-orange" id="taskDetailStatus">待审核</span>
- </div>
- <div class="space-y-3">
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24"><i class="fas fa-tasks w-5 text-gray-400"></i>任务名称</span>
- <span class="text-sm text-gray-800 flex-1" id="taskDetailTitle">积丹白鹭小区疏通</span>
- </div>
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24"><i class="fas fa-map-marker-alt w-5 text-gray-400"></i>故障位置</span>
- <span class="text-sm text-gray-800 flex-1" id="taskDetailAddress">积丹白鹭小区A栋地下停车场B1层</span>
- </div>
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24"><i class="fas fa-tools w-5 text-gray-400"></i>施工类型</span>
- <span class="text-sm text-gray-800 flex-1" id="taskDetailType">疏通</span>
- </div>
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24"><i class="fas fa-clock w-5 text-gray-400"></i>服务时间</span>
- <span class="text-sm text-gray-800 flex-1" id="taskDetailTime">2026-04-21 09:30</span>
- </div>
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24"><i class="fas fa-user w-5 text-gray-400"></i>申请人</span>
- <span class="text-sm text-gray-800 flex-1" id="taskDetailApplicant">李明</span>
- </div>
- </div>
- </div>
- <!-- 项目信息卡片(新增) -->
- <div class="bg-white rounded-xl p-4 shadow-sm mb-4">
- <h3 class="text-base font-semibold text-gray-800 mb-4"><i class="fas fa-building text-blue-500 mr-2"></i>项目信息</h3>
- <div class="space-y-3">
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24"><i class="fas fa-building w-5 text-gray-400"></i>项目名称</span>
- <span class="text-sm text-gray-800 flex-1" id="taskDetailProjectName">积丹白鹭</span>
- </div>
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24"><i class="fas fa-handshake w-5 text-gray-400"></i>合作类型</span>
- <span class="text-sm"><span class="tag tag-blue" id="taskDetailCoopType">包年</span></span>
- </div>
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24"><i class="fas fa-map-marker-alt w-5 text-gray-400"></i>项目地址</span>
- <span class="text-sm text-gray-800 flex-1" id="taskDetailProjectAddress">昆明市五华区积丹白鹭小区</span>
- </div>
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24"><i class="fas fa-users w-5 text-gray-400"></i>联系人</span>
- <span class="text-sm text-gray-800 flex-1" id="taskDetailProjectContacts">张经理 138****1234</span>
- </div>
- </div>
- </div>
- <!-- 故障详情卡片(新增) -->
- <div class="bg-white rounded-xl p-4 shadow-sm mb-4">
- <h3 class="text-base font-semibold text-gray-800 mb-4"><i class="fas fa-map-marker-alt text-red-500 mr-2"></i>故障详情</h3>
- <div class="space-y-3">
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24"><i class="fas fa-map-pin w-5 text-gray-400"></i>地理位置</span>
- <span class="text-sm text-blue-500 flex-1 cursor-pointer" id="taskDetailGeoLocation">
- <i class="fas fa-external-link-alt mr-1"></i>点击查看地图
- </span>
- </div>
- <div class="flex items-start" style="flex-direction: column;">
- <span class="text-gray-500 text-sm w-24 mb-1"><i class="fas fa-image w-5 text-gray-400"></i>故障图片/视频</span>
- <div class="flex gap-2 ml-6" id="taskDetailMedia">
- <div class="w-16 h-16 bg-gray-100 rounded-lg flex items-center justify-center cursor-pointer">
- <i class="fas fa-image text-gray-400"></i>
- </div>
- <div class="w-16 h-16 bg-gray-100 rounded-lg flex items-center justify-center cursor-pointer">
- <i class="fas fa-image text-gray-400"></i>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- 施工信息卡片 -->
- <div class="bg-white rounded-xl p-4 shadow-sm mb-4">
- <h3 class="text-base font-semibold text-gray-800 mb-4">施工信息</h3>
- <div class="space-y-3">
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24">故障描述</span>
- <span class="text-sm text-gray-800 flex-1" id="taskDetailFaultDesc">管道堵塞,污水溢出,需要紧急疏通处理</span>
- </div>
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24">施工设施</span>
- <span class="text-sm text-gray-800 flex-1" id="taskDetailFacility">油污管</span>
- </div>
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24">服务方式</span>
- <span class="text-sm text-gray-800 flex-1" id="taskDetailServiceMode">应急</span>
- </div>
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24">建议出车</span>
- <span class="text-sm text-gray-800 flex-1" id="taskDetailVehicle">疏通车</span>
- </div>
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24">取水距离</span>
- <span class="text-sm text-gray-800 flex-1" id="taskDetailWaterSource">有消防水</span>
- </div>
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24">化粪池排口</span>
- <span class="text-sm text-gray-800 flex-1" id="taskDetailSepticTank">正常</span>
- </div>
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24">施工助力</span>
- <span class="text-sm text-gray-800 flex-1" id="taskDetailConstructionHelp">地库限高2.2米,需注意</span>
- </div>
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24">预计作业量</span>
- <span class="text-sm text-gray-800 flex-1" id="taskDetailQuantity">2个堵点</span>
- </div>
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24">预计工时</span>
- <span class="text-sm text-gray-800 flex-1" id="taskDetailHours">2小时</span>
- </div>
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24">验收要求</span>
- <span class="text-sm text-gray-800 flex-1" id="taskDetailAcceptReq">正常走水</span>
- </div>
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24">验收方式</span>
- <span class="text-sm text-gray-800 flex-1" id="taskDetailAcceptType">签署验收计量单</span>
- </div>
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24">甲方当事人</span>
- <span class="text-sm text-gray-800 flex-1" id="taskDetailPartyA">张经理 138****1234</span>
- </div>
- <div class="flex items-start">
- <span class="text-gray-500 text-sm w-24">备注</span>
- <span class="text-sm text-gray-800 flex-1 text-red-500" id="taskDetailRemark">A栋厨房管道堵塞,需紧急处理</span>
- </div>
- </div>
- </div>
- <!-- 审核操作卡片(待审核状态显示) -->
- <div class="bg-white rounded-xl p-4 shadow-sm mb-4" id="taskAuditSection">
- <h3 class="text-base font-semibold text-gray-800 mb-4">审核操作</h3>
- <!-- 第一步:确认/驳回按钮 -->
- <div id="auditStep1">
- <p class="text-sm text-gray-500 mb-4">请确认该任务是否可以执行,然后进行后续安排。</p>
- <div class="flex gap-3">
- <button class="btn btn-danger flex-1" onclick="rejectTaskFromDetail()">
- <i class="fas fa-times mr-1"></i>驳回
- </button>
- <button class="btn btn-success flex-1" onclick="confirmTaskStep1()">
- <i class="fas fa-check mr-1"></i>确认
- </button>
- </div>
- </div>
- <!-- 第二步:安排班组(确认后才显示) -->
- <div id="auditStep2" style="display: none;">
- <p class="text-sm text-yellow-600 mb-4">
- <i class="fas fa-info-circle mr-1"></i>任务已确认,请安排班组和车辆
- </p>
- <div class="form-group">
- <label class="form-label">调度班组</label>
- <select class="form-select" id="dispatchTeam">
- <option value="">请选择班组</option>
- <option value="zhang">张师傅组(张三、李四)</option>
- <option value="wang">王师傅组(王五、赵六)</option>
- <option value="liu">刘师傅组(刘七、陈八)</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label">调度车辆</label>
- <select class="form-select" id="dispatchVehicle">
- <option value="">请选择车辆</option>
- <option value="v1">疏通车01(贵A81356)</option>
- <option value="v2">疏通车02(贵A82345)</option>
- <option value="v3">吸污车03(贵A83456)</option>
- <option value="v4">吸污车04(贵A84567)</option>
- <option value="v5">高压清洗车05(贵A85678)</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label">审核备注(可选)</label>
- <textarea class="form-textarea" id="auditRemark" placeholder="请输入审核备注..."></textarea>
- </div>
- <div class="flex gap-3 mt-4">
- <button class="btn btn-outline flex-1" onclick="cancelConfirmStep()">
- <i class="fas fa-arrow-left mr-1"></i>返回
- </button>
- <button class="btn btn-primary flex-1" onclick="arrangeTeamStep2()">
- <i class="fas fa-check mr-1"></i>安排
- </button>
- </div>
- </div>
- </div>
- <!-- 驳回原因(已驳回状态显示) -->
- <div class="bg-white rounded-xl p-4 shadow-sm mb-4" id="taskRejectSection" style="display: none;">
- <h3 class="text-base font-semibold text-gray-800 mb-4">驳回原因</h3>
- <div class="p-3 bg-red-50 rounded-lg">
- <p class="text-sm text-red-600" id="rejectReason">设备临时故障</p>
- </div>
- </div>
- <!-- 待排班操作卡片(confirmed状态显示) -->
- <div class="bg-white rounded-xl p-4 shadow-sm mb-4" id="taskConfirmSection" style="display: none;">
- <h3 class="text-base font-semibold text-gray-800 mb-4">安排班组</h3>
- <p class="text-sm text-yellow-600 mb-4">
- <i class="fas fa-info-circle mr-1"></i>任务已确认,请安排班组和车辆
- </p>
- <div class="form-group">
- <label class="form-label">调度班组</label>
- <select class="form-select" id="confirmDispatchTeam">
- <option value="">请选择班组</option>
- <option value="zhang">张师傅组(张三、李四)</option>
- <option value="wang">王师傅组(王五、赵六)</option>
- <option value="liu">刘师傅组(刘七、陈八)</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label">调度车辆</label>
- <select class="form-select" id="confirmDispatchVehicle">
- <option value="">请选择车辆</option>
- <option value="v1">疏通车01(贵A81356)</option>
- <option value="v2">疏通车02(贵A82345)</option>
- <option value="v3">吸污车03(贵A83456)</option>
- <option value="v4">吸污车04(贵A84567)</option>
- <option value="v5">高压清洗车05(贵A85678)</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label">审核备注(可选)</label>
- <textarea class="form-textarea" id="confirmAuditRemark" placeholder="请输入审核备注..."></textarea>
- </div>
- <div class="flex gap-3 mt-4">
- <button class="btn btn-primary flex-1" onclick="arrangeTeamForConfirmed()">
- <i class="fas fa-check mr-1"></i>安排
- </button>
- </div>
- </div>
- <!-- 调度信息(已通过状态显示) -->
- <div class="bg-white rounded-xl p-4 shadow-sm mb-4" id="taskDispatchSection" style="display: none;">
- <h3 class="text-base font-semibold text-gray-800 mb-4">调度信息</h3>
- <div class="space-y-3">
- <div class="flex items-center">
- <span class="text-gray-500 text-sm w-20"><i class="fas fa-users w-5 text-gray-400"></i>执行班组</span>
- <span class="text-sm text-gray-800 flex-1" id="dispatchedTeam">张师傅组</span>
- </div>
- <div class="flex items-center">
- <span class="text-gray-500 text-sm w-20"><i class="fas fa-truck w-5 text-gray-400"></i>调度车辆</span>
- <span class="text-sm text-gray-800 flex-1" id="dispatchedVehicle">疏通车01(贵A81356)</span>
- </div>
- <div class="flex items-center">
- <span class="text-gray-500 text-sm w-20"><i class="fas fa-user w-5 text-gray-400"></i>审核人</span>
- <span class="text-sm text-gray-800 flex-1">张调度</span>
- </div>
- </div>
- </div>
- <!-- 操作日志 -->
- <div class="bg-white rounded-xl p-4 shadow-sm mb-4">
- <h3 class="text-base font-semibold text-gray-800 mb-4"><i class="fas fa-history text-green-500 mr-2"></i>操作日志</h3>
- <div class="space-y-3" id="dispatch_taskLogList">
- <div class="flex items-start text-sm">
- <span class="text-gray-400 w-20 flex-shrink-0">04-21 09:30</span>
- <div class="flex-1">
- <span class="text-gray-800">销售 李明</span>
- <span class="text-gray-500">发布了任务</span>
- </div>
- </div>
- <div class="flex items-start text-sm">
- <span class="text-gray-400 w-20 flex-shrink-0">04-21 10:15</span>
- <div class="flex-1">
- <span class="text-gray-800">调度 张调度</span>
- <span class="text-gray-500">已安排班组:工程一班</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- ========== 人员列表页 ========== -->
- <div id="dispatch_personnelPage" class="page">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-4 shadow-sm">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToDispatchPage('dispatch_schedulePage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">人员列表</h1>
- </div>
- <div class="flex items-center gap-2">
- <button class="px-3 py-1.5 bg-blue-500 text-white rounded-lg text-sm" onclick="filterPersonnel('all')">全部</button>
- <button class="px-3 py-1.5 bg-gray-100 rounded-lg text-sm" onclick="filterPersonnel('working')">施工中</button>
- <button class="px-3 py-1.5 bg-gray-100 rounded-lg text-sm" onclick="filterPersonnel('free')">空闲</button>
- </div>
- </div>
- <!-- 统计信息 -->
- <div class="flex justify-around mt-4 py-2 bg-gray-50 rounded-lg">
- <div class="text-center">
- <div class="text-lg font-bold text-blue-600" id="personnelTotal">12</div>
- <div class="text-xs text-gray-500">总人数</div>
- </div>
- <div class="text-center">
- <div class="text-lg font-bold text-orange-500" id="personnelWorking">8</div>
- <div class="text-xs text-gray-500">施工中</div>
- </div>
- <div class="text-center">
- <div class="text-lg font-bold text-green-500" id="personnelFree">4</div>
- <div class="text-xs text-gray-500">空闲</div>
- </div>
- </div>
- </div>
- <!-- 人员列表 -->
- <div class="px-4 py-4" id="personnelList">
- <!-- JS生成 -->
- </div>
- </div>
- <!-- ========== 车辆列表页 ========== -->
- <div id="dispatch_vehicleListPage" class="page">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-4 shadow-sm">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToDispatchPage('dispatch_schedulePage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">车辆列表</h1>
- </div>
- <div class="flex items-center gap-2">
- <button class="px-3 py-1.5 bg-blue-500 text-white rounded-lg text-sm" onclick="filterVehicle('all')">全部</button>
- <button class="px-3 py-1.5 bg-gray-100 rounded-lg text-sm" onclick="filterVehicle('working')">施工中</button>
- <button class="px-3 py-1.5 bg-gray-100 rounded-lg text-sm" onclick="filterVehicle('free')">空闲</button>
- </div>
- </div>
- <!-- 统计信息 -->
- <div class="flex justify-around mt-4 py-2 bg-gray-50 rounded-lg">
- <div class="text-center">
- <div class="text-lg font-bold text-blue-600" id="vehicleTotal">10</div>
- <div class="text-xs text-gray-500">总车辆</div>
- </div>
- <div class="text-center">
- <div class="text-lg font-bold text-orange-500" id="vehicleWorking">6</div>
- <div class="text-xs text-gray-500">施工中</div>
- </div>
- <div class="text-center">
- <div class="text-lg font-bold text-green-500" id="vehicleFree">4</div>
- <div class="text-xs text-gray-500">空闲</div>
- </div>
- </div>
- </div>
- <!-- 车辆列表 -->
- <div class="px-4 py-4" id="vehicleList">
- <!-- JS生成 -->
- </div>
- </div>
- <!-- ========== 应急班组页 ========== -->
- <div id="dispatch_emergencyTeamPage" class="page">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-4 shadow-sm">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToDispatchPage('dispatch_schedulePage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">应急班组</h1>
- </div>
- </div>
- <!-- 应急状态说明 -->
- <div class="mt-4 p-3 bg-orange-50 rounded-lg flex items-center">
- <i class="fas fa-info-circle text-orange-500 mr-2"></i>
- <span class="text-sm text-orange-600">应急班组处于待命状态,可随时响应紧急任务</span>
- </div>
- </div>
- <!-- 应急班组列表 -->
- <div class="px-4 py-4" id="emergencyTeamList">
- <!-- JS生成 -->
- </div>
- </div>
- <!-- ========== 消息通知页 ========== -->
- <div id="dispatch_notificationPage" class="page">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-4 shadow-sm">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToDispatchPage('dispatch_homePage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">消息通知</h1>
- </div>
- <button class="px-3 py-1.5 text-blue-500 text-sm" onclick="markAllRead()">全部已读</button>
- </div>
- <!-- 筛选标签 -->
- <div class="flex gap-2 mt-4">
- <button class="dispatch-notification-tab px-4 py-2 bg-blue-500 text-white rounded-full text-sm" onclick="filterDispatchNotifications('all', this)">全部</button>
- <button class="dispatch-notification-tab px-4 py-2 bg-gray-100 text-gray-600 rounded-full text-sm" onclick="filterDispatchNotifications('task', this)">任务分配</button>
- <button class="dispatch-notification-tab px-4 py-2 bg-gray-100 text-gray-600 rounded-full text-sm" onclick="filterDispatchNotifications('audit', this)">审核结果</button>
- <button class="dispatch-notification-tab px-4 py-2 bg-gray-100 text-gray-600 rounded-full text-sm" onclick="filterDispatchNotifications('system', this)">系统消息</button>
- </div>
- </div>
- <!-- 通知列表 -->
- <div class="px-4 py-4" id="dispatchNotificationList">
- <!-- JS生成 -->
- </div>
- </div>
- <!-- ========== 可视化大屏页 ========== -->
- <div id="dispatch_visualizationPage" class="page">
- <!-- 顶部导航 -->
- <div class="bg-gradient-to-r from-purple-600 to-pink-500 px-4 pt-8 pb-4">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToDispatchPage('dispatch_homePage')">
- <i class="fas fa-arrow-left text-white text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-white">可视化大屏</h1>
- </div>
- <span class="text-white/80 text-sm" id="vizDate"></span>
- </div>
- </div>
- <!-- 可视化内容 -->
- <div class="px-4 py-4">
- <!-- 今日任务总数 -->
- <div class="bg-white rounded-xl p-4 mb-4 shadow-sm">
- <h3 class="text-sm text-gray-500 mb-2"><i class="fas fa-tasks mr-1 text-blue-500"></i>今日任务</h3>
- <div class="flex items-end">
- <span class="text-4xl font-bold text-gray-800" id="vizTaskTotal">15</span>
- <span class="text-gray-400 ml-2 mb-1">个任务</span>
- </div>
- <div class="flex gap-4 mt-3 pt-3 border-t border-gray-100">
- <div class="text-center flex-1">
- <div class="text-lg font-bold text-orange-500">5</div>
- <div class="text-xs text-gray-400">待排班</div>
- </div>
- <div class="text-center flex-1">
- <div class="text-lg font-bold text-blue-500">8</div>
- <div class="text-xs text-gray-400">进行中</div>
- </div>
- <div class="text-center flex-1">
- <div class="text-lg font-bold text-green-500">2</div>
- <div class="text-xs text-gray-400">已完成</div>
- </div>
- </div>
- </div>
- <!-- 车辆状态 -->
- <div class="bg-white rounded-xl p-4 mb-4 shadow-sm">
- <h3 class="text-sm text-gray-500 mb-3"><i class="fas fa-truck mr-1 text-blue-500"></i>施工车辆状态</h3>
- <div class="flex items-center gap-4">
- <div class="w-20 h-20 rounded-full border-8 border-orange-400 flex items-center justify-center">
- <span class="text-2xl font-bold text-orange-500">6</span>
- </div>
- <div class="flex-1">
- <div class="flex justify-between items-center mb-2">
- <span class="text-sm text-gray-600"><i class="fas fa-circle text-orange-400 text-xs mr-1"></i>施工中</span>
- <span class="text-lg font-bold">6</span>
- </div>
- <div class="flex justify-between items-center">
- <span class="text-sm text-gray-600"><i class="fas fa-circle text-green-400 text-xs mr-1"></i>空闲</span>
- <span class="text-lg font-bold">4</span>
- </div>
- </div>
- </div>
- <div class="mt-3 pt-3 border-t border-gray-100">
- <div class="flex gap-2 overflow-x-auto">
- <span class="px-2 py-1 bg-orange-50 text-orange-600 rounded text-xs whitespace-nowrap">疏通车01 施工中</span>
- <span class="px-2 py-1 bg-orange-50 text-orange-600 rounded text-xs whitespace-nowrap">疏通车02 施工中</span>
- <span class="px-2 py-1 bg-green-50 text-green-600 rounded text-xs whitespace-nowrap">疏通车03 空闲</span>
- <span class="px-2 py-1 bg-orange-50 text-orange-600 rounded text-xs whitespace-nowrap">吸污车01 施工中</span>
- <span class="px-2 py-1 bg-green-50 text-green-600 rounded text-xs whitespace-nowrap">吸污车02 空闲</span>
- </div>
- </div>
- </div>
- <!-- 人员状态 -->
- <div class="bg-white rounded-xl p-4 mb-4 shadow-sm">
- <h3 class="text-sm text-gray-500 mb-3"><i class="fas fa-users mr-1 text-purple-500"></i>人员状态</h3>
- <div class="flex items-center gap-4">
- <div class="w-20 h-20 rounded-full border-8 border-orange-400 flex items-center justify-center">
- <span class="text-2xl font-bold text-orange-500">8</span>
- </div>
- <div class="flex-1">
- <div class="flex justify-between items-center mb-2">
- <span class="text-sm text-gray-600"><i class="fas fa-circle text-orange-400 text-xs mr-1"></i>施工中</span>
- <span class="text-lg font-bold">8</span>
- </div>
- <div class="flex justify-between items-center">
- <span class="text-sm text-gray-600"><i class="fas fa-circle text-green-400 text-xs mr-1"></i>空闲</span>
- <span class="text-lg font-bold">4</span>
- </div>
- </div>
- </div>
- <div class="mt-3 pt-3 border-t border-gray-100">
- <div class="flex gap-2 overflow-x-auto">
- <span class="px-2 py-1 bg-orange-50 text-orange-600 rounded text-xs whitespace-nowrap">张三 施工中</span>
- <span class="px-2 py-1 bg-orange-50 text-orange-600 rounded text-xs whitespace-nowrap">李四 施工中</span>
- <span class="px-2 py-1 bg-green-50 text-green-600 rounded text-xs whitespace-nowrap">王五 空闲</span>
- <span class="px-2 py-1 bg-orange-50 text-orange-600 rounded text-xs whitespace-nowrap">赵六 施工中</span>
- </div>
- </div>
- </div>
- <!-- 应急待命状态 -->
- <div class="bg-white rounded-xl p-4 shadow-sm">
- <h3 class="text-sm text-gray-500 mb-3"><i class="fas fa-phone-volume mr-1 text-red-500"></i>应急待命</h3>
- <div class="flex items-center gap-3">
- <div class="w-12 h-12 bg-red-100 rounded-lg flex items-center justify-center">
- <i class="fas fa-bolt text-red-500 text-xl"></i>
- </div>
- <div class="flex-1">
- <div class="text-xl font-bold text-gray-800">3</div>
- <div class="text-xs text-gray-400">个应急班组待命</div>
- </div>
- <div class="px-3 py-1 bg-green-100 text-green-600 rounded-full text-xs">
- 就绪
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- ========== 底部导航栏 ========== -->
- <div class="bottom-nav">
- <div class="flex justify-around items-center py-2">
- <div class="nav-item flex flex-col items-center py-1 px-4 cursor-pointer" onclick="goToDispatchPage('dispatch_homePage')" data-page="dispatch_homePage">
- <div class="nav-icon w-10 h-10 rounded-xl flex items-center justify-center mb-1 transition-all">
- <i class="fas fa-home text-lg"></i>
- </div>
- <span class="text-xs">首页</span>
- </div>
- <div class="nav-item flex flex-col items-center py-1 px-4 cursor-pointer" onclick="goToDispatchPage('dispatch_schedulePage')" data-page="dispatch_schedulePage">
- <div class="nav-icon w-10 h-10 rounded-xl flex items-center justify-center mb-1 transition-all">
- <i class="fas fa-calendar-alt text-lg"></i>
- </div>
- <span class="text-xs">排班</span>
- </div>
- <div class="nav-item flex flex-col items-center py-1 px-4 cursor-pointer" onclick="goToDispatchPage('dispatch_taskPage')" data-page="dispatch_taskPage" style="position: relative;">
- <div class="nav-icon w-10 h-10 rounded-xl flex items-center justify-center mb-1 transition-all">
- <i class="fas fa-tasks text-lg"></i>
- </div>
- <span class="text-xs">任务</span>
- <span class="pending-badge" id="pendingBadge">2</span>
- </div>
- <div class="nav-item flex flex-col items-center py-1 px-4 cursor-pointer" onclick="goToDispatchPage('dispatch_myPage')" data-page="dispatch_myPage">
- <div class="nav-icon w-10 h-10 rounded-xl flex items-center justify-center mb-1 transition-all">
- <i class="fas fa-user text-lg"></i>
- </div>
- <span class="text-xs">我的</span>
- </div>
- </div>
- </div>
- <!-- 新增排班弹窗 -->
- <div class="modal-overlay hidden" id="addScheduleModal">
- <div class="modal-content">
- <div class="modal-header">
- <span class="modal-title">新增排班</span>
- <button class="modal-close" onclick="closeAddScheduleModal()">
- <i class="fas fa-times"></i>
- </button>
- </div>
- <div class="modal-body">
- <div class="form-group">
- <label class="form-label">选择班组</label>
- <select class="form-select" id="teamSelect">
- <option value="">请选择班组</option>
- <option value="zhang">张师傅组(张三、李四)</option>
- <option value="wang">王师傅组(王五、赵六)</option>
- <option value="liu">刘师傅组(刘七、陈八)</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label">选择车辆</label>
- <select class="form-select" id="vehicleSelect">
- <option value="">请选择车辆</option>
- <option value="v1">疏通车01(贵A81356)</option>
- <option value="v2">疏通车02(贵A82345)</option>
- <option value="v3">吸污车03(贵A83456)</option>
- <option value="v4">吸污车04(贵A84567)</option>
- <option value="v5">高压清洗车05(贵A85678)</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label">排班类型</label>
- <div class="type-selector">
- <div class="type-option monthly selected" onclick="selectType('monthly')">
- <i class="fas fa-calendar-check"></i>
- <span>月计划</span>
- </div>
- <div class="type-option emergency" onclick="selectType('emergency')">
- <i class="fas fa-bolt"></i>
- <span>应急</span>
- </div>
- </div>
- </div>
- <div class="form-group">
- <label class="form-label">备注(可选)</label>
- <textarea class="form-textarea" id="scheduleRemark" placeholder="请输入备注信息..."></textarea>
- </div>
- </div>
- <div class="modal-footer">
- <button class="btn btn-outline" onclick="closeAddScheduleModal()">取消</button>
- <button class="btn btn-primary" onclick="confirmAddSchedule()">确认</button>
- </div>
- </div>
- </div>
- <!-- 日期详情弹窗 -->
- <div class="modal-overlay hidden" id="dateDetailModal">
- <div class="modal-content">
- <div class="modal-header">
- <span class="modal-title" id="dateDetailTitle">4月21日 排班详情</span>
- <button class="modal-close" onclick="closeDateDetailModal()">
- <i class="fas fa-times"></i>
- </button>
- </div>
- <div class="modal-body" id="dateDetailList">
- <!-- JS生成 -->
- </div>
- <div class="modal-footer">
- <button class="btn btn-outline" onclick="closeDateDetailModal()">关闭</button>
- <button class="btn btn-primary" onclick="addScheduleForDate()">
- <i class="fas fa-plus mr-1"></i>新增排班
- </button>
- </div>
- </div>
- </div>
- </div><!-- dispatchApp结束 -->
- <!-- 施工端容器 -->
- <div class="app-container" id="constructionApp">
- <!-- ========== 施工端首页 ========== -->
- <div id="construction_homePage" class="page">
- <!-- 顶部欢迎区域 -->
- <div class="bg-gradient-to-r from-blue-500 to-blue-600 px-4 pt-8 pb-6">
- <div class="flex items-center justify-between mb-4">
- <div class="flex items-center">
- <div class="w-12 h-12 bg-white rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-hard-hat text-blue-500 text-lg"></i>
- </div>
- <div>
- <p class="text-blue-100 text-xs">您好,欢迎回来</p>
- <p class="text-white font-medium">张师傅</p>
- </div>
- </div>
- <button class="w-10 h-10 bg-white/20 rounded-full flex items-center justify-center relative" onclick="goToConstructionPage('construction_notificationPage')">
- <i class="fas fa-bell text-white"></i>
- <span class="absolute -top-1 -right-1 w-5 h-5 bg-red-500 rounded-full text-white text-xs flex items-center justify-center">2</span>
- </button>
- </div>
- <div class="bg-white/20 backdrop-blur rounded-xl p-3">
- <p class="text-white text-sm"><i class="fas fa-users mr-2"></i>班组:工程一班</p>
- </div>
- </div>
- <!-- 主内容区域 -->
- <div class="px-4 -mt-4 space-y-4">
- <!-- 数据统计卡片 -->
- <div class="grid grid-cols-3 gap-3">
- <div class="rounded-xl p-3 text-center text-white cursor-pointer" style="background: linear-gradient(135deg, #f97316 0%, #ea580c 100%);" onclick="goToConstructionPage('construction_historyTaskPage')">
- <p class="text-2xl font-bold">156</p>
- <p class="text-xs opacity-90">历史完成</p>
- </div>
- <div class="rounded-xl p-3 text-center text-white cursor-pointer" style="background: linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%);" onclick="goToConstructionPage('construction_taskPage')">
- <p class="text-2xl font-bold">3</p>
- <p class="text-xs opacity-90">当前任务</p>
- </div>
- <div class="rounded-xl p-3 text-center text-white cursor-pointer" style="background: linear-gradient(135deg, #06b6d4 0%, #0891b2 100%);" onclick="goToConstructionPage('construction_tomorrowTaskPage')">
- <p class="text-2xl font-bold">2</p>
- <p class="text-xs opacity-90">明日任务</p>
- </div>
- </div>
- <!-- 每日任务卡片 -->
- <div class="card p-4 cursor-pointer" onclick="goToConstructionPage('construction_dailyTaskPage')">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <div class="w-12 h-12 bg-blue-100 rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-clipboard-check text-blue-500"></i>
- </div>
- <div>
- <p class="font-semibold text-gray-800">每日任务</p>
- <p class="text-sm text-gray-500">今日检查待完成</p>
- </div>
- </div>
- <div class="flex items-center">
- <span class="w-2 h-2 bg-red-500 rounded-full mr-2"></span>
- <i class="fas fa-chevron-right text-gray-400"></i>
- </div>
- </div>
- </div>
- <!-- 快捷入口 -->
- <div class="card p-4">
- <div class="grid grid-cols-3 gap-3">
- <div class="flex flex-col items-center py-3 cursor-pointer" onclick="goToConstructionPage('construction_taskPage')">
- <div class="w-12 h-12 bg-blue-50 rounded-full flex items-center justify-center mb-2">
- <i class="fas fa-tasks text-blue-500"></i>
- </div>
- <span class="text-sm text-gray-600">我的任务</span>
- </div>
- <div class="flex flex-col items-center py-3 cursor-pointer" onclick="goToConstructionPage('construction_dailyTaskPage')">
- <div class="w-12 h-12 bg-blue-50 rounded-full flex items-center justify-center mb-2">
- <i class="fas fa-truck text-blue-500"></i>
- </div>
- <span class="text-sm text-gray-600">车辆检查</span>
- </div>
- <div class="flex flex-col items-center py-3 cursor-pointer" onclick="goToConstructionPage('construction_helpCenterPage')">
- <div class="w-12 h-12 bg-blue-50 rounded-full flex items-center justify-center mb-2">
- <i class="fas fa-question-circle text-blue-500"></i>
- </div>
- <span class="text-sm text-gray-600">帮助中心</span>
- </div>
- </div>
- </div>
- <!-- 通知公告 -->
- <div class="card p-4">
- <div class="flex items-center justify-between mb-3">
- <h3 class="font-semibold text-gray-800 flex items-center">
- <i class="fas fa-bullhorn text-blue-500 mr-2"></i>
- 通知公告
- </h3>
- <span class="text-xs text-blue-500 cursor-pointer" onclick="goToConstructionPage('construction_noticeListPage')">查看全部 <i class="fas fa-chevron-right"></i></span>
- </div>
- <div class="space-y-3">
- <div class="flex items-start py-2 border-b border-gray-50 cursor-pointer" onclick="goToConstructionPage('construction_noticeDetailPage')">
- <div class="flex-1">
- <p class="text-sm text-gray-800 font-medium">关于规范施工现场安全管理的通知</p>
- <p class="text-xs text-gray-400 mt-1">2026-04-20</p>
- </div>
- <span class="px-2 py-0.5 bg-red-50 text-red-500 text-xs rounded">重要</span>
- </div>
- <div class="flex items-start py-2 border-b border-gray-50 cursor-pointer" onclick="goToConstructionPage('construction_noticeDetailPage')">
- <div class="flex-1">
- <p class="text-sm text-gray-800 font-medium">下周安全培训会议安排</p>
- <p class="text-xs text-gray-400 mt-1">2026-04-18</p>
- </div>
- </div>
- <div class="flex items-start py-2 cursor-pointer" onclick="goToConstructionPage('construction_noticeDetailPage')">
- <div class="flex-1">
- <p class="text-sm text-gray-800 font-medium">设备维护保养规范更新</p>
- <p class="text-xs text-gray-400 mt-1">2026-04-15</p>
- </div>
- </div>
- </div>
- </div>
- <!-- 当前任务预览 -->
- <div class="card p-4">
- <div class="flex items-center justify-between mb-4">
- <h3 class="font-semibold text-gray-800 flex items-center">
- <i class="fas fa-list-alt text-blue-500 mr-2"></i>
- 当前任务
- </h3>
- <span class="text-xs text-blue-500 cursor-pointer" onclick="goToConstructionPage('construction_taskPage')">查看全部 <i class="fas fa-chevron-right"></i></span>
- </div>
- <div class="space-y-3">
- <div class="p-3 bg-gray-50 rounded-lg cursor-pointer" onclick="goToConstructionPage('construction_taskDetailPage')">
- <div class="flex justify-between items-center mb-2">
- <span class="font-medium text-gray-800">积丹白鹭 - 油污管疏通</span>
- <span class="tag tag-orange text-xs">进行中</span>
- </div>
- <p class="text-sm text-gray-500"><i class="fas fa-map-marker-alt w-4"></i>积丹白鹭小区</p>
- </div>
- <div class="p-3 bg-gray-50 rounded-lg cursor-pointer" onclick="goToConstructionPage('construction_taskDetailPage')">
- <div class="flex justify-between items-center mb-2">
- <span class="font-medium text-gray-800">俊发城 - 化粪池清掏</span>
- <span class="tag tag-blue text-xs">待确认</span>
- </div>
- <p class="text-sm text-gray-500"><i class="fas fa-map-marker-alt w-4"></i>俊发城住宅区</p>
- </div>
- </div>
- </div>
- </div>
- <!-- 底部导航 -->
- <div class="bottom-nav">
- <div class="flex justify-around py-2">
- <button class="nav-item active flex flex-col items-center py-1 px-4" onclick="goToConstructionPage('construction_homePage')">
- <div class="nav-icon w-10 h-10 rounded-full flex items-center justify-center mb-1 transition-all">
- <i class="fas fa-home text-lg"></i>
- </div>
- <span class="text-xs">首页</span>
- </button>
- <button class="nav-item flex flex-col items-center py-1 px-4" onclick="goToConstructionPage('construction_taskPage')">
- <div class="nav-icon w-10 h-10 rounded-full flex items-center justify-center mb-1 transition-all bg-gray-100">
- <i class="fas fa-tasks text-gray-400 text-lg"></i>
- </div>
- <span class="text-xs text-gray-400">任务</span>
- </button>
- <button class="nav-item flex flex-col items-center py-1 px-4" onclick="goToConstructionPage('construction_myPage')">
- <div class="nav-icon w-10 h-10 rounded-full flex items-center justify-center mb-1 transition-all bg-gray-100">
- <i class="fas fa-user text-gray-400 text-lg"></i>
- </div>
- <span class="text-xs text-gray-400">我的</span>
- </button>
- </div>
- </div>
- </div>
- <!-- ========== 每日任务页 ========== -->
- <div id="construction_dailyTaskPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToConstructionPage('construction_homePage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">每日任务</h1>
- </div>
- <span class="text-sm text-green-500">2024-01-21</span>
- </div>
- </div>
- <!-- 检查项目列表 -->
- <div class="px-4 py-4 space-y-4">
- <p class="text-sm text-gray-500 mb-2">请完成以下每日检查项目</p>
- <!-- 车辆检查 -->
- <div class="check-item">
- <div class="check-header">
- <div class="flex items-center">
- <div class="w-10 h-10 bg-blue-100 rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-truck text-blue-500"></i>
- </div>
- <div>
- <span class="check-title">车辆检查</span>
- <p class="text-xs text-gray-400">检查车辆外观、设备状态</p>
- </div>
- </div>
- <span class="check-status" id="vehicleCheckStatus">未完成</span>
- </div>
- <div class="upload-area" onclick="showToast('拍照上传功能开发中')">
- <i class="fas fa-camera"></i>
- <p>点击拍照上传</p>
- </div>
- </div>
- <!-- 设备检查 -->
- <div class="check-item">
- <div class="check-header">
- <div class="flex items-center">
- <div class="w-10 h-10 bg-orange-100 rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-tools text-orange-500"></i>
- </div>
- <div>
- <span class="check-title">设备检查</span>
- <p class="text-xs text-gray-400">检查施工设备是否齐全</p>
- </div>
- </div>
- <span class="check-status" id="equipmentCheckStatus">未完成</span>
- </div>
- <div class="upload-area" onclick="showToast('拍照上传功能开发中')">
- <i class="fas fa-camera"></i>
- <p>点击拍照上传</p>
- </div>
- </div>
- <!-- 三大系统检查 -->
- <div class="check-item">
- <div class="check-header">
- <div class="flex items-center">
- <div class="w-10 h-10 bg-green-100 rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-cogs text-green-500"></i>
- </div>
- <div>
- <span class="check-title">三大系统检查</span>
- <p class="text-xs text-gray-400">检查核心系统运行状态</p>
- </div>
- </div>
- <span class="check-status" id="systemCheckStatus">未完成</span>
- </div>
- <div class="space-y-3">
- <div class="upload-area" onclick="showToast('拍照上传功能开发中')">
- <i class="fas fa-camera"></i>
- <p>点击拍照上传</p>
- </div>
- <div class="upload-area" onclick="showToast('视频上传功能开发中')">
- <i class="fas fa-video"></i>
- <p>点击录制视频上传</p>
- </div>
- </div>
- </div>
- <!-- 备注输入 -->
- <div class="mt-4">
- <label class="text-sm text-gray-600 mb-2 block">备注</label>
- <textarea class="w-full border rounded-lg p-3 text-sm" rows="3" id="dailyTaskRemark" placeholder="请输入备注信息(选填)"></textarea>
- </div>
- <!-- 提交按钮 -->
- <button class="w-full py-3 bg-green-500 text-white rounded-xl font-medium mt-4" onclick="submitDailyTask()">
- 提交检查结果
- </button>
- </div>
- </div>
- <!-- ========== 任务页 ========== -->
- <div id="construction_taskPage" class="page">
- <!-- 顶部区域 -->
- <div class="bg-white px-4 pt-8 pb-4 shadow-sm sticky top-0 z-10">
- <div class="flex items-center justify-between">
- <h1 class="text-xl font-bold text-gray-800">我的任务</h1>
- <span class="text-sm text-blue-500">共 <span id="constructionTaskCount">5</span> 个任务</span>
- </div>
- <!-- 筛选标签 -->
- <div class="filter-tabs mt-3">
- <button class="filter-tab active" data-status="all" onclick="filterConstructionTasks('all', this)">全部</button>
- <button class="filter-tab" data-status="待确认" onclick="filterConstructionTasks('待确认', this)">待确认</button>
- <button class="filter-tab" data-status="待出车" onclick="filterConstructionTasks('待出车', this)">待出车</button>
- <button class="filter-tab" data-status="已出车" onclick="filterConstructionTasks('已出车', this)">已出车</button>
- <button class="filter-tab" data-status="施工中" onclick="filterConstructionTasks('施工中', this)">施工中</button>
- <button class="filter-tab" data-status="已到达" onclick="filterConstructionTasks('待验收', this)">待验收</button>
- </div>
- </div>
- <!-- 任务列表 -->
- <div class="px-4 py-4 space-y-3" id="constructionTaskList">
- <!-- 任务卡片1 - 待确认 -->
- <div class="task-card" data-status="待确认" data-step="待确认" onclick="goToConstructionPage('construction_taskDetailPage'); setDetailStatus('待确认')">
- <div class="flex justify-between items-center mb-3">
- <div>
- <span class="font-semibold text-gray-800">俊发城住宅区</span>
- <span class="ml-2 text-xs bg-purple-100 text-purple-600 px-2 py-0.5 rounded">包年</span>
- </div>
- <span class="tag tag-blue">待确认</span>
- </div>
- <div class="text-sm text-gray-600 mb-2">
- <i class="fas fa-tools w-5 text-gray-400"></i>
- <span>化粪池清掏</span>
- </div>
- <div class="text-sm text-gray-500 mb-2">
- <i class="fas fa-clock w-5 text-gray-400"></i>
- <span>服务时间:明天 14:00</span>
- </div>
- <div class="text-sm text-gray-500 mb-3">
- <i class="fas fa-map-marker-alt w-5 text-gray-400"></i>
- <span>俊发城3号楼</span>
- </div>
- <div class="bg-blue-50 rounded-lg p-3">
- <div class="flex justify-between items-center mb-2">
- <span class="text-xs text-gray-500">当前步骤</span>
- <span class="text-xs text-blue-600 font-medium">待确认</span>
- </div>
- <div class="flow-progress">
- <div class="flow-step active">
- <div class="step-icon"><i class="fas fa-spinner text-xs"></i></div>
- <span class="step-label">确认</span>
- </div>
- <div class="flow-step">
- <div class="step-icon"><i class="fas fa-times text-xs"></i></div>
- <span class="step-label">出车</span>
- </div>
- <div class="flow-step">
- <div class="step-icon"><i class="fas fa-times text-xs"></i></div>
- <span class="step-label">到达</span>
- </div>
- <div class="flow-step">
- <div class="step-icon"><i class="fas fa-times text-xs"></i></div>
- <span class="step-label">施工</span>
- </div>
- <div class="flow-step">
- <div class="step-icon"><i class="fas fa-times text-xs"></i></div>
- <span class="step-label">完成</span>
- </div>
- <div class="flow-step">
- <div class="step-icon"><i class="fas fa-times text-xs"></i></div>
- <span class="step-label">清洗</span>
- </div>
- <div class="flow-step">
- <div class="step-icon"><i class="fas fa-times text-xs"></i></div>
- <span class="step-label">验收</span>
- </div>
- </div>
- </div>
- </div>
- <!-- 任务卡片2 - 待出车 -->
- <div class="task-card" data-status="待出车" data-step="待出车" onclick="goToConstructionPage('construction_taskDetailPage'); setDetailStatus('待出车')">
- <div class="flex justify-between items-center mb-3">
- <div>
- <span class="font-semibold text-gray-800">星光商业广场</span>
- <span class="ml-2 text-xs bg-orange-100 text-orange-600 px-2 py-0.5 rounded">加急</span>
- </div>
- <span class="tag tag-orange">待出车</span>
- </div>
- <div class="text-sm text-gray-600 mb-2">
- <i class="fas fa-tools w-5 text-gray-400"></i>
- <span>管道高压清洗</span>
- </div>
- <div class="text-sm text-gray-500 mb-2">
- <i class="fas fa-clock w-5 text-gray-400"></i>
- <span>服务时间:今天 15:00</span>
- </div>
- <div class="text-sm text-gray-500 mb-3">
- <i class="fas fa-map-marker-alt w-5 text-gray-400"></i>
- <span>星光商业广场地下管网</span>
- </div>
- <div class="bg-orange-50 rounded-lg p-3">
- <div class="flex justify-between items-center mb-2">
- <span class="text-xs text-gray-500">当前步骤</span>
- <span class="text-xs text-orange-600 font-medium">待出车</span>
- </div>
- <div class="flow-progress">
- <div class="flow-step completed">
- <div class="step-icon"><i class="fas fa-check text-xs"></i></div>
- <span class="step-label">确认</span>
- </div>
- <div class="flow-step active">
- <div class="step-icon"><i class="fas fa-spinner text-xs"></i></div>
- <span class="step-label">出车</span>
- </div>
- <div class="flow-step">
- <div class="step-icon"><i class="fas fa-times text-xs"></i></div>
- <span class="step-label">到达</span>
- </div>
- <div class="flow-step">
- <div class="step-icon"><i class="fas fa-times text-xs"></i></div>
- <span class="step-label">施工</span>
- </div>
- <div class="flow-step">
- <div class="step-icon"><i class="fas fa-times text-xs"></i></div>
- <span class="step-label">完成</span>
- </div>
- <div class="flow-step">
- <div class="step-icon"><i class="fas fa-times text-xs"></i></div>
- <span class="step-label">清洗</span>
- </div>
- <div class="flow-step">
- <div class="step-icon"><i class="fas fa-times text-xs"></i></div>
- <span class="step-label">验收</span>
- </div>
- </div>
- </div>
- </div>
- <!-- 任务卡片3 - 已出车 -->
- <div class="task-card" data-status="已出车" data-step="已出车" onclick="goToConstructionPage('construction_taskDetailPage'); setDetailStatus('已出车')">
- <div class="flex justify-between items-center mb-3">
- <div>
- <span class="font-semibold text-gray-800">逸安新城A区</span>
- <span class="ml-2 text-xs bg-red-100 text-red-600 px-2 py-0.5 rounded">应急</span>
- </div>
- <span class="tag tag-orange">已出车</span>
- </div>
- <div class="text-sm text-gray-600 mb-2">
- <i class="fas fa-tools w-5 text-gray-400"></i>
- <span>应急疏通</span>
- </div>
- <div class="text-sm text-gray-500 mb-2">
- <i class="fas fa-clock w-5 text-gray-400"></i>
- <span>服务时间:今天 08:00</span>
- </div>
- <div class="text-sm text-gray-500 mb-3">
- <i class="fas fa-map-marker-alt w-5 text-gray-400"></i>
- <span>逸安新城A区地下车库</span>
- </div>
- <div class="bg-orange-50 rounded-lg p-3">
- <div class="flex justify-between items-center mb-2">
- <span class="text-xs text-gray-500">当前步骤</span>
- <span class="text-xs text-orange-600 font-medium">已出车</span>
- </div>
- <div class="flow-progress">
- <div class="flow-step completed">
- <div class="step-icon"><i class="fas fa-check text-xs"></i></div>
- <span class="step-label">确认</span>
- </div>
- <div class="flow-step completed">
- <div class="step-icon"><i class="fas fa-check text-xs"></i></div>
- <span class="step-label">出车</span>
- </div>
- <div class="flow-step active">
- <div class="step-icon"><i class="fas fa-spinner text-xs"></i></div>
- <span class="step-label">到达</span>
- </div>
- <div class="flow-step">
- <div class="step-icon"><i class="fas fa-times text-xs"></i></div>
- <span class="step-label">施工</span>
- </div>
- <div class="flow-step">
- <div class="step-icon"><i class="fas fa-times text-xs"></i></div>
- <span class="step-label">完成</span>
- </div>
- <div class="flow-step">
- <div class="step-icon"><i class="fas fa-times text-xs"></i></div>
- <span class="step-label">清洗</span>
- </div>
- <div class="flow-step">
- <div class="step-icon"><i class="fas fa-times text-xs"></i></div>
- <span class="step-label">验收</span>
- </div>
- </div>
- </div>
- </div>
- <!-- 任务卡片4 - 施工中 -->
- <div class="task-card" data-status="施工中" data-step="施工中" onclick="goToConstructionPage('construction_taskDetailPage'); setDetailStatus('施工中')">
- <div class="flex justify-between items-center mb-3">
- <div>
- <span class="font-semibold text-gray-800">积丹白鹭小区</span>
- <span class="ml-2 text-xs bg-purple-100 text-purple-600 px-2 py-0.5 rounded">包年</span>
- </div>
- <span class="tag tag-green">施工中</span>
- </div>
- <div class="text-sm text-gray-600 mb-2">
- <i class="fas fa-tools w-5 text-gray-400"></i>
- <span>油污管疏通</span>
- </div>
- <div class="text-sm text-gray-500 mb-2">
- <i class="fas fa-clock w-5 text-gray-400"></i>
- <span>服务时间:09:00-12:00</span>
- </div>
- <div class="text-sm text-gray-500 mb-3">
- <i class="fas fa-map-marker-alt w-5 text-gray-400"></i>
- <span>地下停车场B1层</span>
- </div>
- <div class="bg-green-50 rounded-lg p-3">
- <div class="flex justify-between items-center mb-2">
- <span class="text-xs text-gray-500">当前步骤</span>
- <span class="text-xs text-green-600 font-medium">施工中</span>
- </div>
- <div class="flow-progress">
- <div class="flow-step completed">
- <div class="step-icon"><i class="fas fa-check text-xs"></i></div>
- <span class="step-label">确认</span>
- </div>
- <div class="flow-step completed">
- <div class="step-icon"><i class="fas fa-check text-xs"></i></div>
- <span class="step-label">出车</span>
- </div>
- <div class="flow-step completed">
- <div class="step-icon"><i class="fas fa-check text-xs"></i></div>
- <span class="step-label">到达</span>
- </div>
- <div class="flow-step active">
- <div class="step-icon"><i class="fas fa-spinner text-xs"></i></div>
- <span class="step-label">施工</span>
- </div>
- <div class="flow-step">
- <div class="step-icon"><i class="fas fa-times text-xs"></i></div>
- <span class="step-label">完成</span>
- </div>
- <div class="flow-step">
- <div class="step-icon"><i class="fas fa-times text-xs"></i></div>
- <span class="step-label">清洗</span>
- </div>
- <div class="flow-step">
- <div class="step-icon"><i class="fas fa-times text-xs"></i></div>
- <span class="step-label">验收</span>
- </div>
- </div>
- </div>
- </div>
- <!-- 任务卡片5 - 待验收 -->
- <div class="task-card" data-status="已到达" data-step="待验收" onclick="goToConstructionPage('construction_taskDetailPage'); setDetailStatus('待验收')">
- <div class="flex justify-between items-center mb-3">
- <div>
- <span class="font-semibold text-gray-800">云锦华庭小区</span>
- <span class="ml-2 text-xs bg-orange-100 text-orange-600 px-2 py-0.5 rounded">应急</span>
- </div>
- <span class="tag tag-purple">待验收</span>
- </div>
- <div class="text-sm text-gray-600 mb-2">
- <i class="fas fa-tools w-5 text-gray-400"></i>
- <span>排水管道维修</span>
- </div>
- <div class="text-sm text-gray-500 mb-2">
- <i class="fas fa-clock w-5 text-gray-400"></i>
- <span>服务时间:昨天 10:00</span>
- </div>
- <div class="text-sm text-gray-500 mb-3">
- <i class="fas fa-map-marker-alt w-5 text-gray-400"></i>
- <span>云锦华庭3栋地下室</span>
- </div>
- <div class="bg-purple-50 rounded-lg p-3">
- <div class="flex justify-between items-center mb-2">
- <span class="text-xs text-gray-500">当前步骤</span>
- <span class="text-xs text-purple-600 font-medium">待验收</span>
- </div>
- <div class="flow-progress">
- <div class="flow-step completed">
- <div class="step-icon"><i class="fas fa-check text-xs"></i></div>
- <span class="step-label">确认</span>
- </div>
- <div class="flow-step completed">
- <div class="step-icon"><i class="fas fa-check text-xs"></i></div>
- <span class="step-label">出车</span>
- </div>
- <div class="flow-step completed">
- <div class="step-icon"><i class="fas fa-check text-xs"></i></div>
- <span class="step-label">到达</span>
- </div>
- <div class="flow-step completed">
- <div class="step-icon"><i class="fas fa-check text-xs"></i></div>
- <span class="step-label">施工</span>
- </div>
- <div class="flow-step completed">
- <div class="step-icon"><i class="fas fa-check text-xs"></i></div>
- <span class="step-label">完成</span>
- </div>
- <div class="flow-step completed">
- <div class="step-icon"><i class="fas fa-check text-xs"></i></div>
- <span class="step-label">清洗</span>
- </div>
- <div class="flow-step active">
- <div class="step-icon"><i class="fas fa-spinner text-xs"></i></div>
- <span class="step-label">验收</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- 底部导航 -->
- <div class="bottom-nav">
- <div class="flex justify-around py-2">
- <button class="nav-item flex flex-col items-center py-1 px-4" onclick="goToConstructionPage('construction_homePage')">
- <div class="nav-icon w-10 h-10 rounded-full flex items-center justify-center mb-1 transition-all bg-gray-100">
- <i class="fas fa-home text-gray-400 text-lg"></i>
- </div>
- <span class="text-xs text-gray-400">首页</span>
- </button>
- <button class="nav-item active flex flex-col items-center py-1 px-4" onclick="goToConstructionPage('construction_taskPage')">
- <div class="nav-icon w-10 h-10 rounded-full flex items-center justify-center mb-1 transition-all">
- <i class="fas fa-tasks text-lg"></i>
- </div>
- <span class="text-xs">任务</span>
- </button>
- <button class="nav-item flex flex-col items-center py-1 px-4" onclick="goToConstructionPage('construction_myPage')">
- <div class="nav-icon w-10 h-10 rounded-full flex items-center justify-center mb-1 transition-all bg-gray-100">
- <i class="fas fa-user text-gray-400 text-lg"></i>
- </div>
- <span class="text-xs text-gray-400">我的</span>
- </button>
- </div>
- </div>
- </div>
- <div id="construction_taskDetailPage" class="page hide-nav">
- <!-- 顶部导航 -->
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center justify-between">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToConstructionPage('construction_taskPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">任务详情</h1>
- </div>
- <button class="text-gray-500"><i class="fas fa-ellipsis-h"></i></button>
- </div>
- </div>
- <!-- 任务内容 -->
- <div class="px-4 py-4 space-y-4">
- <!-- 1. 施工流程进度(最显眼) -->
- <div class="construction-flow-bar" id="detailFlowBar">
- <div class="construction-flow-line">
- <div class="construction-flow-line-fill" id="detailFlowLineFill" style="width: 0%"></div>
- </div>
- <div class="construction-flow-step" id="step-confirm">
- <div class="step-dot pending" id="step-confirm-dot"><i class="fas fa-times"></i></div>
- <span class="step-name">确认</span>
- </div>
- <div class="construction-flow-step" id="step-depart">
- <div class="step-dot pending" id="step-depart-dot"><i class="fas fa-times"></i></div>
- <span class="step-name">出车</span>
- </div>
- <div class="construction-flow-step" id="step-arrive">
- <div class="step-dot pending" id="step-arrive-dot"><i class="fas fa-times"></i></div>
- <span class="step-name">到达</span>
- </div>
- <div class="construction-flow-step" id="step-work">
- <div class="step-dot pending" id="step-work-dot"><i class="fas fa-times"></i></div>
- <span class="step-name">勘验</span>
- </div>
- <div class="construction-flow-step" id="step-work2">
- <div class="step-dot pending" id="step-work2-dot"><i class="fas fa-times"></i></div>
- <span class="step-name">施工</span>
- </div>
- <div class="construction-flow-step" id="step-complete">
- <div class="step-dot pending" id="step-complete-dot"><i class="fas fa-times"></i></div>
- <span class="step-name">完成</span>
- </div>
- <div class="construction-flow-step" id="step-clean">
- <div class="step-dot pending" id="step-clean-dot"><i class="fas fa-times"></i></div>
- <span class="step-name">清洗</span>
- </div>
- <div class="construction-flow-step" id="step-inspect">
- <div class="step-dot pending" id="step-inspect-dot"><i class="fas fa-times"></i></div>
- <span class="step-name">验收</span>
- </div>
- </div>
- <!-- 2. 确认/反馈/拒绝按钮区(待确认状态显示) -->
- <div id="detailActionArea">
- <!-- 待确认状态:三个按钮 -->
- <div id="action-pending-confirm" class="action-content">
- <div class="bg-blue-50 rounded-xl p-4 mb-4">
- <div class="text-center mb-4">
- <i class="fas fa-clipboard-check text-blue-500 text-4xl mb-3"></i>
- <h3 class="text-lg font-semibold text-gray-800">待确认任务</h3>
- <p class="text-gray-500 text-sm mt-1">请查看任务详情,确认是否接受</p>
- </div>
- <div class="bg-white rounded-lg p-3 mb-4">
- <div class="flex justify-between text-sm">
- <span class="text-gray-400">任务类型</span>
- <span class="text-gray-800">油污管疏通</span>
- </div>
- <div class="flex justify-between text-sm mt-2">
- <span class="text-gray-400">服务时间</span>
- <span class="text-gray-800">09:00-12:00</span>
- </div>
- </div>
- </div>
- <div class="space-y-3">
- <button class="w-full py-2.5 bg-green-500 text-white rounded-lg font-medium text-sm flex items-center justify-center gap-2" onclick="confirmTask()">
- <i class="fas fa-check-circle"></i>
- 确认任务
- </button>
- <button class="w-full py-2.5 bg-orange-50 border border-orange-200 text-orange-600 rounded-lg font-medium text-sm flex items-center justify-center gap-2" onclick="openFeedbackModal()">
- <i class="fas fa-comment-dots"></i>
- 反馈问题
- </button>
- <button class="w-full py-2.5 bg-red-50 border border-red-200 text-red-500 rounded-lg font-medium text-sm flex items-center justify-center gap-2" onclick="openRejectModal()">
- <i class="fas fa-times-circle"></i>
- 拒绝任务
- </button>
- </div>
- </div>
- <!-- 待出车状态:出发按钮 -->
- <div id="action-pending-depart" class="action-content hidden">
- <div class="bg-orange-50 rounded-xl p-4 mb-4">
- <div class="text-center mb-4">
- <i class="fas fa-car text-orange-500 text-4xl mb-3"></i>
- <h3 class="text-lg font-semibold text-gray-800">准备出发</h3>
- <p class="text-gray-500 text-sm mt-1">请确认设备准备完毕后出发</p>
- </div>
- <div class="bg-white rounded-lg p-3">
- <div class="flex justify-between text-sm">
- <span class="text-gray-400">目的地</span>
- <span class="text-gray-800">积丹白鹭小区</span>
- </div>
- <div class="flex justify-between text-sm mt-2">
- <span class="text-gray-400">预计时长</span>
- <span class="text-gray-800">约30分钟</span>
- </div>
- </div>
- </div>
- <button class="w-full py-3 bg-gradient-to-r from-orange-500 to-orange-600 text-white rounded-xl font-semibold text-base flex items-center justify-center gap-2" onclick="startDeparture()">
- <i class="fas fa-paper-plane"></i>
- 出发
- </button>
- </div>
- </div>
- <!-- 3. 任务信息区块(可收起/展开) -->
- <div class="bg-white rounded-xl shadow-sm mb-4" id="taskInfoSection">
- <div class="detail-section-title cursor-pointer" onclick="toggleTaskInfo()">
- <i class="fas fa-clipboard-list text-green-500"></i>
- <span id="taskInfoTitle">积丹白鹭小区</span>
- <span class="status-tag status-scheduling ml-2" id="taskInfoStatus">待确认</span>
- <i class="fas fa-chevron-down toggle-icon ml-auto" id="taskInfoToggle"></i>
- </div>
- <div class="section-content" id="taskInfoContent">
- <!-- 项目信息 -->
- <div class="p-4 border-b border-gray-100">
- <h4 class="text-sm font-medium text-gray-500 mb-3 flex items-center">
- <i class="fas fa-building text-green-500 mr-2"></i>项目信息
- </h4>
- <div class="space-y-2 text-sm">
- <div class="flex justify-between">
- <span class="text-gray-400">项目名称</span>
- <span class="text-gray-800" id="detailProjectName">积丹白鹭小区</span>
- </div>
- <div class="flex justify-between">
- <span class="text-gray-400">合作类型</span>
- <span class="tag tag-blue">包年</span>
- </div>
- <div class="flex justify-between">
- <span class="text-gray-400">项目地址</span>
- <span class="text-gray-800">江干区秋涛北路73号</span>
- </div>
- <div class="flex justify-between">
- <span class="text-gray-400">项目联系人</span>
- <span class="text-gray-800">陈物业 138****8888</span>
- </div>
- </div>
- </div>
- <!-- 施工信息 -->
- <div class="p-4 border-b border-gray-100">
- <h4 class="text-sm font-medium text-gray-500 mb-3 flex items-center">
- <i class="fas fa-tools text-blue-500 mr-2"></i>施工信息
- </h4>
- <div class="space-y-2 text-sm">
- <div class="flex justify-between">
- <span class="text-gray-400">施工类型</span>
- <span class="text-gray-800" id="detailWorkType">油污管疏通</span>
- </div>
- <div class="flex justify-between">
- <span class="text-gray-400">设施类型</span>
- <span class="text-gray-800">排污管道</span>
- </div>
- <div class="flex justify-between">
- <span class="text-gray-400">服务方式</span>
- <span class="text-gray-800">带水作业</span>
- </div>
- <div class="flex justify-between">
- <span class="text-gray-400">服务时间</span>
- <span class="text-gray-800 text-xs" id="detailServiceTime">2024-01-21 09:00-12:00</span>
- </div>
- <div class="flex justify-between">
- <span class="text-gray-400">建议出车</span>
- <span class="text-gray-800" id="detailVehicle">疏通车</span>
- </div>
- <div class="flex justify-between">
- <span class="text-gray-400">施工地址</span>
- <span class="text-gray-800" id="detailFaultLocation">地下停车场B1层</span>
- </div>
- <div class="flex justify-between items-center">
- <span class="text-gray-400">地理定位</span>
- <button class="text-blue-500 text-sm flex items-center gap-1" onclick="showToast('打开地图导航')">
- <i class="fas fa-map-marker-alt"></i>点击导航
- </button>
- </div>
- </div>
- </div>
- <!-- 故障信息 -->
- <div class="p-4 border-b border-gray-100">
- <h4 class="text-sm font-medium text-gray-500 mb-3 flex items-center">
- <i class="fas fa-exclamation-triangle text-orange-500 mr-2"></i>故障信息
- </h4>
- <div class="space-y-2 text-sm">
- <div class="flex justify-between">
- <span class="text-gray-400">故障描述</span>
- <span class="text-gray-800">管道堵塞,污水溢出</span>
- </div>
- <div>
- <div class="text-gray-400 mb-2">故障图片/视频</div>
- <div class="grid grid-cols-3 gap-2">
- <div class="aspect-square bg-gray-100 rounded-lg flex items-center justify-center">
- <i class="fas fa-image text-gray-300"></i>
- </div>
- <div class="aspect-square bg-gray-100 rounded-lg flex items-center justify-center">
- <i class="fas fa-image text-gray-300"></i>
- </div>
- <div class="aspect-square bg-gray-100 rounded-lg flex items-center justify-center">
- <i class="fas fa-video text-gray-300"></i>
- </div>
- </div>
- </div>
- <div class="flex justify-between">
- <span class="text-gray-400">设施类型详情</span>
- <span class="text-gray-800">DN200铸铁管</span>
- </div>
- </div>
- </div>
- <!-- 施工要求 -->
- <div class="p-4 border-b border-gray-100">
- <h4 class="text-sm font-medium text-gray-500 mb-3 flex items-center">
- <i class="fas fa-clipboard-check text-blue-500 mr-2"></i>施工要求
- </h4>
- <div class="space-y-2 text-sm">
- <div class="flex justify-between">
- <span class="text-gray-400">水源情况</span>
- <span class="text-gray-800">现场有消防栓</span>
- </div>
- <div class="flex justify-between">
- <span class="text-gray-400">化粪池情况</span>
- <span class="text-gray-800">无</span>
- </div>
- <div class="flex justify-between">
- <span class="text-gray-400">施工协助</span>
- <span class="text-gray-800">无需协助</span>
- </div>
- <div class="flex justify-between">
- <span class="text-gray-400">预估工程量</span>
- <span class="text-gray-800">约30米</span>
- </div>
- <div class="flex justify-between">
- <span class="text-gray-400">预估时长</span>
- <span class="text-gray-800">约3小时</span>
- </div>
- <div class="flex justify-between">
- <span class="text-gray-400">验收要求</span>
- <span class="text-gray-800">管道畅通,无积水</span>
- </div>
- <div class="flex justify-between">
- <span class="text-gray-400">验收方式</span>
- <span class="text-gray-800">签署验收计量单</span>
- </div>
- </div>
- </div>
- <!-- 甲方确认人 -->
- <div class="p-4">
- <h4 class="text-sm font-medium text-gray-500 mb-3 flex items-center">
- <i class="fas fa-user-check text-green-500 mr-2"></i>甲方确认人
- </h4>
- <div class="flex justify-between items-center">
- <div>
- <span class="text-gray-800 text-sm">陈物业</span>
- <span class="text-gray-400 text-sm ml-2">138****8888</span>
- </div>
- <button class="w-8 h-8 bg-green-50 rounded-full flex items-center justify-center" onclick="showToast('拨打 138****8888')">
- <i class="fas fa-phone-alt text-green-500 text-sm"></i>
- </button>
- </div>
- </div>
- </div>
- </div>
- <!-- 4. 出车准备区(SOP新增) -->
- <div class="bg-white rounded-xl p-4 mb-4" id="constructionPrepSection">
- <h3 class="text-base font-semibold text-gray-800 mb-4">
- <i class="fas fa-truck-loading text-orange-500 mr-2"></i>出车准备(SOP)
- </h3>
- <div class="mb-4">
- <div class="text-sm font-medium text-gray-600 mb-2"><i class="fas fa-clipboard-check text-orange-500 mr-1"></i>车辆点检</div>
- <div class="bg-gray-50 rounded-lg p-3">
- <div class="checklist-item">
- <div class="checklist-checkbox" onclick="toggleChecklist(this)"></div>
- <span class="text-sm">机油检查</span>
- </div>
- <div class="checklist-item">
- <div class="checklist-checkbox" onclick="toggleChecklist(this)"></div>
- <span class="text-sm">轮胎检查</span>
- </div>
- <div class="checklist-item">
- <div class="checklist-checkbox" onclick="toggleChecklist(this)"></div>
- <span class="text-sm">灯光/水管/工具</span>
- </div>
- </div>
- </div>
- <div class="inline-selector">
- <div class="form-group">
- <label class="form-label">出发时间</label>
- <input type="time" id="departureTime" class="form-input" value="08:30">
- </div>
- <div class="form-group">
- <label class="form-label">预计到达</label>
- <input type="time" id="estimatedArrival" class="form-input" value="09:00">
- </div>
- </div>
- </div>
- <!-- 5. 现场踏勘区(SOP新增) -->
- <div class="bg-white rounded-xl p-4 mb-4" id="constructionSurveySection">
- <h3 class="text-base font-semibold text-gray-800 mb-4">
- <i class="fas fa-search text-purple-500 mr-2"></i>现场踏勘(SOP)
- </h3>
- <div class="inline-selector">
- <div class="form-group">
- <label class="form-label">到达时间</label>
- <input type="time" id="arrivalTime" class="form-input" value="08:55">
- </div>
- <div class="form-group">
- <label class="form-label">对接人情况</label>
- <select id="contactStatus" class="form-select">
- <option value="到位">已到位</option>
- <option value="未到位">未到位</option>
- </select>
- </div>
- </div>
- <div class="form-group">
- <label class="form-label">踏勘与工单一致性</label>
- <div class="tag-selector">
- <div class="tag-option selected" onclick="toggleTag(this)">一致</div>
- <div class="tag-option" onclick="toggleTag(this)">不一致</div>
- </div>
- </div>
- <div class="form-group">
- <label class="form-label">客户同意情况</label>
- <div class="flex items-center gap-4">
- <span class="text-sm text-gray-500">客户已同意施工</span>
- <div id="customerAgreeToggle" class="toggle-switch active" onclick="toggleSwitch(this)"></div>
- </div>
- </div>
- </div>
- <!-- 6. 施工流程记录 -->
- <div class="bg-white rounded-xl p-4 mb-4">
- <h3 class="text-base font-semibold text-gray-800 mb-4">
- <i class="fas fa-clipboard-list text-blue-500 mr-2"></i>施工流程记录
- </h3>
- <!-- 步骤1:出车 -->
- <div class="step-upload-card mb-3 p-3 bg-gray-50 rounded-lg border border-gray-200">
- <div class="flex items-center justify-between mb-3">
- <div class="flex items-center gap-2">
- <span class="step-number w-6 h-6 bg-orange-500 text-white rounded-full flex items-center justify-center text-xs font-bold">1</span>
- <span class="step-title font-medium text-gray-800">出车</span>
- </div>
- <span class="step-status text-xs px-2 py-1 rounded bg-gray-200 text-gray-600" id="step-status-1">待上传</span>
- </div>
- <div class="upload-area-mini bg-white rounded-lg p-3 border-2 border-dashed border-gray-300 cursor-pointer" onclick="uploadDeparturePhoto()">
- <div class="flex items-center gap-3">
- <i class="fas fa-cloud-upload-alt text-gray-400 text-xl"></i>
- <div>
- <span class="text-sm text-gray-600">拍照上传</span>
- <p class="text-xs text-gray-400">出车前车辆及设备照片</p>
- </div>
- </div>
- </div>
- <div id="preview-1" class="hidden mt-3">
- <div class="flex items-center gap-2 bg-green-50 rounded-lg p-2">
- <i class="fas fa-check-circle text-green-500"></i>
- <span class="text-green-600 text-xs">已上传</span>
- </div>
- </div>
- </div>
- <!-- 步骤2:到达现场 -->
- <div class="step-upload-card mb-3 p-3 bg-gray-50 rounded-lg border border-gray-200">
- <div class="flex items-center justify-between mb-3">
- <div class="flex items-center gap-2">
- <span class="step-number w-6 h-6 bg-orange-400 text-white rounded-full flex items-center justify-center text-xs font-bold">2</span>
- <span class="step-title font-medium text-gray-800">到达现场</span>
- </div>
- <span class="step-status text-xs px-2 py-1 rounded bg-gray-200 text-gray-600" id="step-status-2">待上传</span>
- </div>
- <div class="upload-area-mini bg-white rounded-lg p-3 border-2 border-dashed border-gray-300 cursor-pointer" onclick="uploadArrivePhoto()">
- <div class="flex items-center gap-3">
- <i class="fas fa-parking text-gray-400 text-xl"></i>
- <div>
- <span class="text-sm text-gray-600">上传停车警示牌</span>
- <p class="text-xs text-gray-400">到达现场后停车警示牌照片</p>
- </div>
- </div>
- </div>
- <div id="preview-2" class="hidden mt-3">
- <div class="flex items-center gap-2 bg-green-50 rounded-lg p-2">
- <i class="fas fa-check-circle text-green-500"></i>
- <span class="text-green-600 text-xs">已上传</span>
- </div>
- </div>
- </div>
- <!-- 步骤3:现场勘验 -->
- <div class="step-upload-card mb-3 p-3 bg-gray-50 rounded-lg border border-gray-200">
- <div class="flex items-center justify-between mb-3">
- <div class="flex items-center gap-2">
- <span class="step-number w-6 h-6 bg-blue-500 text-white rounded-full flex items-center justify-center text-xs font-bold">3</span>
- <span class="step-title font-medium text-gray-800">现场勘验</span>
- </div>
- <span class="step-status text-xs px-2 py-1 rounded bg-gray-200 text-gray-600" id="step-status-3">待上传</span>
- </div>
- <div class="upload-area-mini bg-white rounded-lg p-3 border-2 border-dashed border-gray-300 cursor-pointer" onclick="uploadInspectionMedia()">
- <div class="flex items-center gap-3">
- <i class="fas fa-camera text-gray-400 text-xl"></i>
- <div>
- <span class="text-sm text-gray-600">拍照/录像</span>
- <p class="text-xs text-gray-400">现场勘验照片或视频</p>
- </div>
- </div>
- </div>
- <div id="preview-3" class="hidden mt-3">
- <div class="flex items-center gap-2 bg-green-50 rounded-lg p-2">
- <i class="fas fa-check-circle text-green-500"></i>
- <span class="text-green-600 text-xs">已上传</span>
- </div>
- </div>
- </div>
- <!-- 步骤4:施工 -->
- <div class="step-upload-card mb-3 p-3 bg-gray-50 rounded-lg border border-gray-200">
- <div class="flex items-center justify-between mb-3">
- <div class="flex items-center gap-2">
- <span class="step-number w-6 h-6 bg-green-600 text-white rounded-full flex items-center justify-center text-xs font-bold">4</span>
- <span class="step-title font-medium text-gray-800">施工</span>
- </div>
- <span class="step-status text-xs px-2 py-1 rounded bg-gray-200 text-gray-600" id="step-status-4">待上传</span>
- </div>
- <!-- 堵塞物输入 -->
- <div class="mb-3">
- <label class="text-xs text-gray-500 mb-1 block">堵塞物</label>
- <input type="text" class="w-full py-2 px-3 border border-gray-200 rounded-lg text-sm bg-white" placeholder="如:头发、纸巾、油污等">
- </div>
- <div class="upload-area-mini bg-white rounded-lg p-3 border-2 border-dashed border-gray-300 cursor-pointer" onclick="uploadConstructionMedia()">
- <div class="flex items-center gap-3">
- <i class="fas fa-hard-hat text-gray-400 text-xl"></i>
- <div>
- <span class="text-sm text-gray-600">拍照/录像</span>
- <p class="text-xs text-gray-400">施工过程照片或视频</p>
- </div>
- </div>
- </div>
- <div id="preview-4" class="hidden mt-3">
- <div class="flex items-center gap-2 bg-green-50 rounded-lg p-2">
- <i class="fas fa-check-circle text-green-500"></i>
- <span class="text-green-600 text-xs">已上传</span>
- </div>
- </div>
- </div>
- <!-- 步骤5:完成 -->
- <div class="step-upload-card mb-3 p-3 bg-gray-50 rounded-lg border border-gray-200">
- <div class="flex items-center justify-between mb-3">
- <div class="flex items-center gap-2">
- <span class="step-number w-6 h-6 bg-cyan-500 text-white rounded-full flex items-center justify-center text-xs font-bold">5</span>
- <span class="step-title font-medium text-gray-800">完成</span>
- </div>
- <span class="step-status text-xs px-2 py-1 rounded bg-gray-200 text-gray-600" id="step-status-5">待上传</span>
- </div>
- <!-- 设施反馈输入 -->
- <div class="mb-3">
- <label class="text-xs text-gray-500 mb-1 block">设施反馈</label>
- <textarea class="w-full py-2 px-3 border border-gray-200 rounded-lg text-sm bg-white" rows="2" placeholder="设施状态、建议等"></textarea>
- </div>
- <div class="upload-area-mini bg-white rounded-lg p-3 border-2 border-dashed border-gray-300 cursor-pointer" onclick="uploadCompleteMedia()">
- <div class="flex items-center gap-3">
- <i class="fas fa-check-circle text-gray-400 text-xl"></i>
- <div>
- <span class="text-sm text-gray-600">拍照上传</span>
- <p class="text-xs text-gray-400">施工完成照片</p>
- </div>
- </div>
- </div>
- <div id="preview-5" class="hidden mt-3">
- <div class="flex items-center gap-2 bg-green-50 rounded-lg p-2">
- <i class="fas fa-check-circle text-green-500"></i>
- <span class="text-green-600 text-xs">已上传</span>
- </div>
- </div>
- </div>
- <!-- 步骤6:清洗 -->
- <div class="step-upload-card mb-3 p-3 bg-gray-50 rounded-lg border border-gray-200">
- <div class="flex items-center justify-between mb-3">
- <div class="flex items-center gap-2">
- <span class="step-number w-6 h-6 bg-blue-400 text-white rounded-full flex items-center justify-center text-xs font-bold">6</span>
- <span class="step-title font-medium text-gray-800">清洗</span>
- </div>
- <span class="step-status text-xs px-2 py-1 rounded bg-gray-200 text-gray-600" id="step-status-6">待上传</span>
- </div>
- <div class="upload-area-mini bg-white rounded-lg p-3 border-2 border-dashed border-gray-300 cursor-pointer" onclick="uploadCleaningMedia()">
- <div class="flex items-center gap-3">
- <i class="fas fa-broom text-gray-400 text-xl"></i>
- <div>
- <span class="text-sm text-gray-600">拍照上传</span>
- <p class="text-xs text-gray-400">现场清洗照片</p>
- </div>
- </div>
- </div>
- <div id="preview-6" class="hidden mt-3">
- <div class="flex items-center gap-2 bg-green-50 rounded-lg p-2">
- <i class="fas fa-check-circle text-green-500"></i>
- <span class="text-green-600 text-xs">已上传</span>
- </div>
- </div>
- </div>
- <!-- 步骤7:验收 -->
- <div class="step-upload-card p-3 bg-gray-50 rounded-lg border border-gray-200">
- <div class="flex items-center justify-between mb-3">
- <div class="flex items-center gap-2">
- <span class="step-number w-6 h-6 bg-purple-500 text-white rounded-full flex items-center justify-center text-xs font-bold">7</span>
- <span class="step-title font-medium text-gray-800">验收</span>
- </div>
- <span class="step-status text-xs px-2 py-1 rounded bg-gray-200 text-gray-600" id="step-status-7">待上传</span>
- </div>
- <div class="upload-area-mini bg-white rounded-lg p-3 border-2 border-dashed border-gray-300 cursor-pointer" onclick="uploadInspectionSign()">
- <div class="flex items-center gap-3">
- <i class="fas fa-file-signature text-gray-400 text-xl"></i>
- <div>
- <span class="text-sm text-gray-600">拍照上传</span>
- <p class="text-xs text-gray-400">验收签字或客户确认照片</p>
- </div>
- </div>
- </div>
- <div id="preview-7" class="hidden mt-3">
- <div class="flex items-center gap-2 bg-green-50 rounded-lg p-2">
- <i class="fas fa-check-circle text-green-500"></i>
- <span class="text-green-600 text-xs">已上传</span>
- </div>
- </div>
- </div>
- </div>
- <!-- 5. 任务日志区块 -->
- <div class="bg-white rounded-xl p-4 shadow-sm mb-4">
- <h3 class="text-base font-semibold text-gray-800 mb-4">
- <i class="fas fa-history text-green-500 mr-2"></i>任务日志
- </h3>
- <div class="space-y-3" id="construction_taskLogList">
- <div class="flex items-start text-sm">
- <span class="text-gray-400 w-20 flex-shrink-0">04-21 09:30</span>
- <div class="flex-1">
- <span class="text-gray-800">销售 李明</span>
- <span class="text-gray-500">发布了任务</span>
- </div>
- </div>
- <div class="flex items-start text-sm">
- <span class="text-gray-400 w-20 flex-shrink-0">04-21 10:15</span>
- <div class="flex-1">
- <span class="text-gray-800">调度 张调度</span>
- <span class="text-gray-500">已安排班组:工程一班</span>
- </div>
- </div>
- <div class="flex items-start text-sm">
- <span class="text-gray-400 w-20 flex-shrink-0">04-21 10:30</span>
- <div class="flex-1">
- <span class="text-gray-800">工人 张师傅</span>
- <span class="text-gray-500">确认任务</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div><div id="construction_myPage" class="page">
- <!-- 顶部用户信息区域 -->
- <div class="bg-gradient-to-br from-blue-900 to-blue-800 text-white pt-10 pb-6 px-5">
- <div class="flex items-center gap-4">
- <div class="w-14 h-14 bg-white/20 rounded-full flex items-center justify-center text-2xl">
- <i class="fas fa-user"></i>
- </div>
- <div>
- <h2 class="text-lg font-bold">张师傅</h2>
- <p class="text-blue-200 text-xs">工程一班 · 工号 WRK001</p>
- </div>
- </div>
- </div>
- <!-- 功能列表 -->
- <div class="px-4 -mt-3 space-y-4 pb-4">
- <!-- 基本信息卡片 -->
- <div class="bg-white rounded-xl p-4 shadow-sm">
- <div class="flex justify-between items-center py-2 border-b border-gray-100 cursor-pointer" onclick="showToast('查看所属班组')">
- <span class="text-gray-500 text-sm"><i class="fas fa-users w-5 text-blue-400"></i>班组</span>
- <span class="text-sm">工程一班</span>
- </div>
- <div class="flex justify-between items-center py-2 border-b border-gray-100">
- <span class="text-gray-500 text-sm"><i class="fas fa-id-badge w-5 text-blue-400"></i>职位</span>
- <span class="text-sm">施工员</span>
- </div>
- <div class="flex justify-between items-center py-2">
- <span class="text-gray-500 text-sm"><i class="fas fa-phone w-5 text-blue-400"></i>电话</span>
- <span class="text-sm">139****6666</span>
- </div>
- </div>
- <!-- 功能入口卡片 -->
- <div class="bg-white rounded-xl p-4 shadow-sm">
- <div class="flex justify-between items-center py-3 border-b border-gray-100 cursor-pointer" onclick="goToConstructionPage('construction_basicInfoPage')">
- <span class="text-sm text-gray-700"><i class="fas fa-user-circle text-gray-400 w-6"></i>基本信息</span>
- <i class="fas fa-chevron-right text-gray-300 text-xs"></i>
- </div>
- <div class="flex justify-between items-center py-3 border-b border-gray-100 cursor-pointer" onclick="goToConstructionPage('construction_changePasswordPage')">
- <span class="text-sm text-gray-700"><i class="fas fa-lock text-gray-400 w-6"></i>修改密码</span>
- <i class="fas fa-chevron-right text-gray-300 text-xs"></i>
- </div>
- <div class="flex justify-between items-center py-3 border-b border-gray-100 cursor-pointer" onclick="goToConstructionPage('construction_notificationPage')">
- <span class="text-sm text-gray-700"><i class="fas fa-bell text-gray-400 w-6"></i>消息通知</span>
- <div class="flex items-center">
- <span class="w-2 h-2 bg-red-500 rounded-full mr-2"></span>
- <i class="fas fa-chevron-right text-gray-300 text-xs"></i>
- </div>
- </div>
- <div class="flex justify-between items-center py-3 cursor-pointer" onclick="goToConstructionPage('construction_helpCenterPage')">
- <span class="text-sm text-gray-700"><i class="fas fa-question-circle text-gray-400 w-6"></i>帮助中心</span>
- <i class="fas fa-chevron-right text-gray-300 text-xs"></i>
- </div>
- </div>
- <!-- 退出登录按钮 -->
- <button class="w-full py-3 mt-4 bg-red-500 text-white rounded-xl font-medium cursor-pointer active:bg-red-600 transition-colors" onclick="backToLogin()">
- 退出登录
- </button>
- </div>
- <!-- 底部导航 -->
- <div class="bottom-nav">
- <div class="flex justify-around py-2">
- <button class="nav-item flex flex-col items-center py-1 px-4" onclick="goToConstructionPage('construction_homePage')">
- <div class="nav-icon w-10 h-10 rounded-full flex items-center justify-center mb-1 transition-all bg-gray-100">
- <i class="fas fa-home text-gray-400 text-lg"></i>
- </div>
- <span class="text-xs text-gray-400">首页</span>
- </button>
- <button class="nav-item flex flex-col items-center py-1 px-4" onclick="goToConstructionPage('construction_taskPage')">
- <div class="nav-icon w-10 h-10 rounded-full flex items-center justify-center mb-1 transition-all bg-gray-100">
- <i class="fas fa-tasks text-gray-400 text-lg"></i>
- </div>
- <span class="text-xs text-gray-400">任务</span>
- </button>
- <button class="nav-item active flex flex-col items-center py-1 px-4" onclick="goToConstructionPage('construction_myPage')">
- <div class="nav-icon w-10 h-10 rounded-full flex items-center justify-center mb-1 transition-all">
- <i class="fas fa-user text-lg"></i>
- </div>
- <span class="text-xs">我的</span>
- </button>
- </div>
- </div>
- </div>
- <!-- ========== 基本信息页 ========== -->
- <div id="construction_basicInfoPage" class="page hide-nav">
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToConstructionPage('construction_myPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">个人信息</h1>
- </div>
- </div>
- <div class="px-4 py-4">
- <div class="card p-4">
- <div class="form-group">
- <label class="form-label">姓名</label>
- <input type="text" class="form-input" value="张师傅">
- </div>
- <div class="form-group">
- <label class="form-label">工号</label>
- <input type="text" class="form-input" value="WRK001" disabled>
- </div>
- <div class="form-group">
- <label class="form-label">班组</label>
- <input type="text" class="form-input" value="工程一班">
- </div>
- <div class="form-group">
- <label class="form-label">联系电话</label>
- <input type="tel" class="form-input" value="139****6666">
- </div>
- <button class="w-full py-3 bg-green-500 text-white rounded-xl font-medium mt-4" onclick="showToast('保存成功')">
- 保存修改
- </button>
- </div>
- </div>
- </div>
- <!-- ========== 修改密码页 ========== -->
- <div id="construction_changePasswordPage" class="page hide-nav">
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToConstructionPage('construction_myPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">修改密码</h1>
- </div>
- </div>
- <div class="px-4 py-4">
- <div class="card p-4">
- <div class="form-group">
- <label class="form-label">当前密码</label>
- <input type="password" class="form-input" placeholder="请输入当前密码">
- </div>
- <div class="form-group">
- <label class="form-label">新密码</label>
- <input type="password" class="form-input" placeholder="请输入新密码">
- </div>
- <div class="form-group">
- <label class="form-label">确认新密码</label>
- <input type="password" class="form-input" placeholder="请再次输入新密码">
- </div>
- <button class="w-full py-3 bg-green-500 text-white rounded-xl font-medium mt-4" onclick="showToast('密码修改成功')">
- 确认修改
- </button>
- </div>
- </div>
- </div>
- <!-- ========== 帮助中心页 ========== -->
- <div id="construction_helpCenterPage" class="page hide-nav">
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToConstructionPage('construction_myPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">帮助中心</h1>
- </div>
- </div>
- <div class="px-4 py-4">
- <div class="bg-white rounded-xl p-4 mb-4 shadow-sm">
- <h3 class="text-base font-semibold text-gray-800 mb-4"><i class="fas fa-question-circle text-blue-500 mr-2"></i>常见问题</h3>
- <div class="space-y-3">
- <div class="border-b border-gray-100 pb-3">
- <div class="flex justify-between items-center cursor-pointer" onclick="toggleFaq(this)">
- <span class="text-sm text-gray-700">如何确认任务?</span>
- <i class="fas fa-chevron-down text-gray-400 text-xs"></i>
- </div>
- <div class="hidden mt-2 text-gray-500 text-sm">
- 在任务列表中点击待确认的任务,进入详情页后点击确认按钮即可。
- </div>
- </div>
- <div class="border-b border-gray-100 pb-3">
- <div class="flex justify-between items-center cursor-pointer" onclick="toggleFaq(this)">
- <span class="text-sm text-gray-700">如何完成每日检查?</span>
- <i class="fas fa-chevron-down text-gray-400 text-xs"></i>
- </div>
- <div class="hidden mt-2 text-gray-500 text-sm">
- 进入每日任务页面,按照要求拍照上传相关检查照片后提交即可。
- </div>
- </div>
- <div class="border-b border-gray-100 pb-3">
- <div class="flex justify-between items-center cursor-pointer" onclick="toggleFaq(this)">
- <span class="text-sm text-gray-700">施工流程有哪些步骤?</span>
- <i class="fas fa-chevron-down text-gray-400 text-xs"></i>
- </div>
- <div class="hidden mt-2 text-gray-500 text-sm">
- 施工流程包含8个步骤:确认→出车→到达→施工中→施工完成→清洗→验收→完成。
- </div>
- </div>
- <div>
- <div class="flex justify-between items-center cursor-pointer" onclick="toggleFaq(this)">
- <span class="text-sm text-gray-700">如何联系调度?</span>
- <i class="fas fa-chevron-down text-gray-400 text-xs"></i>
- </div>
- <div class="hidden mt-2 text-gray-500 text-sm">
- 可以拨打调度中心热线:400-888-8888,或在系统中留言。
- </div>
- </div>
- </div>
- </div>
- <div class="bg-white rounded-xl p-4 shadow-sm">
- <h3 class="text-base font-semibold text-gray-800 mb-4"><i class="fas fa-headset text-blue-500 mr-2"></i>联系客服</h3>
- <div class="flex items-center justify-between py-3 border-b border-gray-100">
- <div class="flex items-center">
- <i class="fas fa-phone text-blue-500 mr-3"></i>
- <span class="text-sm text-gray-700">客服热线</span>
- </div>
- <span class="text-blue-500 text-sm">400-888-8888</span>
- </div>
- <div class="flex items-center justify-between py-3">
- <div class="flex items-center">
- <i class="fas fa-clock text-blue-500 mr-3"></i>
- <span class="text-sm text-gray-700">服务时间</span>
- </div>
- <span class="text-gray-600 text-sm">9:00-18:00</span>
- </div>
- </div>
- </div>
- </div>
- <!-- ========== 通知公告列表页 ========== -->
- <div id="construction_noticeListPage" class="page hide-nav">
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToConstructionPage('construction_homePage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">通知公告</h1>
- </div>
- </div>
- <div class="px-4 py-4">
- <div class="space-y-3">
- <div class="bg-white rounded-xl p-4 shadow-sm cursor-pointer" onclick="goToConstructionPage('construction_noticeDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <h3 class="text-sm font-semibold text-gray-800">关于规范施工现场安全管理的通知</h3>
- <span class="px-2 py-0.5 bg-red-50 text-red-500 text-xs rounded">重要</span>
- </div>
- <p class="text-xs text-gray-500 mb-2">为进一步规范施工现场安全管理,现就相关事项通知如下...</p>
- <div class="flex items-center text-xs text-gray-400">
- <i class="fas fa-clock mr-1"></i>2026-04-20
- </div>
- </div>
- <div class="bg-white rounded-xl p-4 shadow-sm cursor-pointer" onclick="goToConstructionPage('construction_noticeDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <h3 class="text-sm font-semibold text-gray-800">下周安全培训会议安排</h3>
- </div>
- <p class="text-xs text-gray-500 mb-2">各位同事,下周二将举行安全培训会议,请准时参加...</p>
- <div class="flex items-center text-xs text-gray-400">
- <i class="fas fa-clock mr-1"></i>2026-04-18
- </div>
- </div>
- <div class="bg-white rounded-xl p-4 shadow-sm cursor-pointer" onclick="goToConstructionPage('construction_noticeDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <h3 class="text-sm font-semibold text-gray-800">设备维护保养规范更新</h3>
- </div>
- <p class="text-xs text-gray-500 mb-2">最新设备维护保养规范已更新,请各位同事查阅学习...</p>
- <div class="flex items-center text-xs text-gray-400">
- <i class="fas fa-clock mr-1"></i>2026-04-15
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- ========== 通知公告详情页 ========== -->
- <div id="construction_noticeDetailPage" class="page hide-nav">
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToConstructionPage('construction_noticeListPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">公告详情</h1>
- </div>
- </div>
- <div class="px-4 py-4">
- <div class="bg-white rounded-xl p-4 shadow-sm">
- <div class="flex justify-between items-start mb-3">
- <h2 class="text-base font-bold text-gray-800">关于规范施工现场安全管理的通知</h2>
- <span class="px-2 py-0.5 bg-red-50 text-red-500 text-xs rounded">重要</span>
- </div>
- <div class="text-xs text-gray-400 mb-4">
- <i class="fas fa-clock mr-1"></i>2026-04-20
- <span class="mx-2">|</span>
- <i class="fas fa-user mr-1"></i>调度中心
- </div>
- <div class="text-sm text-gray-600 leading-relaxed">
- <p class="mb-3">各位施工同事:</p>
- <p class="mb-3">为进一步规范施工现场安全管理,确保施工人员人身安全和施工质量,现就相关事项通知如下:</p>
- <p class="mb-2">一、进入施工现场必须佩戴安全帽、安全背心等防护用品。</p>
- <p class="mb-2">二、施工前必须进行安全检查,确保设备正常运转。</p>
- <p class="mb-2">三、施工现场必须设置警示标志,做好安全防护措施。</p>
- <p class="mb-2">四、发现安全隐患及时上报,不得隐瞒。</p>
- <p class="mb-3">请各位同事严格遵守以上规定,确保施工安全。</p>
- <p>调度中心</p>
- <p>2026年4月20日</p>
- </div>
- </div>
- </div>
- </div>
- <!-- ========== 消息通知页 ========== -->
- <div id="construction_notificationPage" class="page hide-nav">
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToConstructionPage('construction_myPage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">消息通知</h1>
- </div>
- </div>
- <!-- 消息通知筛选tab -->
- <div class="filter-tabs">
- <span class="filter-tab active" onclick="filterConstructionNotifications('all', this)">全部</span>
- <span class="filter-tab" onclick="filterConstructionNotifications('task', this)">任务</span>
- <span class="filter-tab" onclick="filterConstructionNotifications('system', this)">系统</span>
- </div>
- <div class="px-4 py-4">
- <div class="space-y-3" id="constructionNotificationList">
- <div class="bg-white rounded-xl p-4 shadow-sm cursor-pointer construction-notification-item" data-type="task">
- <div class="flex justify-between items-start mb-2">
- <h3 class="text-sm font-semibold text-gray-800">新任务分配</h3>
- <span class="text-xs text-gray-400">10:30</span>
- </div>
- <p class="text-xs text-gray-500 mb-2">您有一个新任务:积丹白鹭油污管疏通,请及时确认。</p>
- <div class="flex items-center">
- <span class="px-2 py-0.5 bg-blue-50 text-blue-500 text-xs rounded">待处理</span>
- </div>
- </div>
- <div class="bg-white rounded-xl p-4 shadow-sm cursor-pointer construction-notification-item" data-type="system">
- <div class="flex justify-between items-start mb-2">
- <h3 class="text-sm font-semibold text-gray-800">安全培训提醒</h3>
- <span class="text-xs text-gray-400">昨天</span>
- </div>
- <p class="text-xs text-gray-500 mb-2">下周二安全培训会议即将开始,请准时参加。</p>
- <div class="flex items-center">
- <span class="px-2 py-0.5 bg-green-50 text-green-500 text-xs rounded">已读</span>
- </div>
- </div>
- <div class="bg-white rounded-xl p-4 shadow-sm cursor-pointer construction-notification-item" data-type="task">
- <div class="flex justify-between items-start mb-2">
- <h3 class="text-sm font-semibold text-gray-800">任务状态更新</h3>
- <span class="text-xs text-gray-400">昨天</span>
- </div>
- <p class="text-xs text-gray-500 mb-2">您的任务"俊发城化粪池清掏"已被调度确认,请等待安排。</p>
- <div class="flex items-center">
- <span class="px-2 py-0.5 bg-gray-50 text-gray-500 text-xs rounded">已完成</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- ========== 历史任务页面 ========== -->
- <div id="construction_historyTaskPage" class="page hide-nav">
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToConstructionPage('construction_homePage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">历史任务</h1>
- </div>
- </div>
- <div class="px-4 py-4">
- <div class="space-y-3">
- <div class="bg-white rounded-xl p-4 shadow-sm cursor-pointer" onclick="goToConstructionPage('construction_taskDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <h3 class="text-sm font-semibold text-gray-800">万科城 - 化粪池清掏</h3>
- <span class="tag tag-green text-xs">已完成</span>
- </div>
- <p class="text-xs text-gray-500 mb-2"><i class="fas fa-map-marker-alt w-4"></i>万科城A区</p>
- <div class="flex items-center text-xs text-gray-400">
- <span>完成时间:2026-04-23</span>
- </div>
- </div>
- <div class="bg-white rounded-xl p-4 shadow-sm cursor-pointer" onclick="goToConstructionPage('construction_taskDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <h3 class="text-sm font-semibold text-gray-800">碧桂园 - 油污管疏通</h3>
- <span class="tag tag-green text-xs">已完成</span>
- </div>
- <p class="text-xs text-gray-500 mb-2"><i class="fas fa-map-marker-alt w-4"></i>碧桂园二期</p>
- <div class="flex items-center text-xs text-gray-400">
- <span>完成时间:2026-04-22</span>
- </div>
- </div>
- <div class="bg-white rounded-xl p-4 shadow-sm cursor-pointer" onclick="goToConstructionPage('construction_taskDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <h3 class="text-sm font-semibold text-gray-800">恒大城 - 排水管清洗</h3>
- <span class="tag tag-green text-xs">已完成</span>
- </div>
- <p class="text-xs text-gray-500 mb-2"><i class="fas fa-map-marker-alt w-4"></i>恒大城3栋</p>
- <div class="flex items-center text-xs text-gray-400">
- <span>完成时间:2026-04-21</span>
- </div>
- </div>
- <div class="bg-white rounded-xl p-4 shadow-sm cursor-pointer" onclick="goToConstructionPage('construction_taskDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <h3 class="text-sm font-semibold text-gray-800">中海锦城 - 管道维修</h3>
- <span class="tag tag-green text-xs">已完成</span>
- </div>
- <p class="text-xs text-gray-500 mb-2"><i class="fas fa-map-marker-alt w-4"></i>中海锦城B区</p>
- <div class="flex items-center text-xs text-gray-400">
- <span>完成时间:2026-04-20</span>
- </div>
- </div>
- <div class="bg-white rounded-xl p-4 shadow-sm cursor-pointer" onclick="goToConstructionPage('construction_taskDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <h3 class="text-sm font-semibold text-gray-800">保利香槟 - 化粪池清掏</h3>
- <span class="tag tag-green text-xs">已完成</span>
- </div>
- <p class="text-xs text-gray-500 mb-2"><i class="fas fa-map-marker-alt w-4"></i>保利香槟国际</p>
- <div class="flex items-center text-xs text-gray-400">
- <span>完成时间:2026-04-19</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- ========== 明日任务页面 ========== -->
- <div id="construction_tomorrowTaskPage" class="page hide-nav">
- <div class="bg-white px-4 pt-8 pb-3 shadow-sm sticky top-0 z-10">
- <div class="flex items-center">
- <button class="w-10 h-10 flex items-center justify-center mr-2" onclick="goToConstructionPage('construction_homePage')">
- <i class="fas fa-arrow-left text-gray-600 text-lg"></i>
- </button>
- <h1 class="text-lg font-bold text-gray-800">明日任务</h1>
- </div>
- </div>
- <div class="px-4 py-4">
- <div class="space-y-3">
- <div class="bg-white rounded-xl p-4 shadow-sm cursor-pointer" onclick="goToConstructionPage('construction_taskDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <h3 class="text-sm font-semibold text-gray-800">绿城花园 - 管道疏通</h3>
- <span class="tag tag-blue text-xs">待执行</span>
- </div>
- <p class="text-xs text-gray-500 mb-2"><i class="fas fa-map-marker-alt w-4"></i>绿城花园小区</p>
- <div class="flex items-center text-xs text-gray-400">
- <span>计划时间:2026-04-25 09:00</span>
- </div>
- </div>
- <div class="bg-white rounded-xl p-4 shadow-sm cursor-pointer" onclick="goToConstructionPage('construction_taskDetailPage')">
- <div class="flex justify-between items-start mb-2">
- <h3 class="text-sm font-semibold text-gray-800">金地名峰 - 化粪池清掏</h3>
- <span class="tag tag-blue text-xs">待执行</span>
- </div>
- <p class="text-xs text-gray-500 mb-2"><i class="fas fa-map-marker-alt w-4"></i>金地名峰1栋</p>
- <div class="flex items-center text-xs text-gray-400">
- <span>计划时间:2026-04-25 14:00</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- 反馈问题弹窗 -->
- <div class="modal-overlay hidden" id="constructionFeedbackModal">
- <div class="modal-content">
- <div class="modal-header">
- <span class="modal-title">反馈问题</span>
- <button class="modal-close" onclick="closeConstructionFeedbackModal()">
- <i class="fas fa-times"></i>
- </button>
- </div>
- <div class="modal-body">
- <textarea class="w-full border rounded-lg p-3 text-sm" rows="4" id="constructionFeedbackText" placeholder="请描述遇到的问题..."></textarea>
- </div>
- <div class="modal-footer">
- <button class="btn btn-outline" onclick="closeConstructionFeedbackModal()">取消</button>
- <button class="btn btn-primary" style="background: linear-gradient(135deg, #10b981 0%, #059669 100%);" onclick="submitConstructionFeedback()">提交反馈</button>
- </div>
- </div>
- </div>
- <!-- 拒绝原因弹窗 -->
- <div class="modal-overlay hidden" id="constructionRejectModal">
- <div class="modal-content">
- <div class="modal-header">
- <span class="modal-title">拒绝原因</span>
- <button class="modal-close" onclick="closeConstructionRejectModal()">
- <i class="fas fa-times"></i>
- </button>
- </div>
- <div class="modal-body">
- <textarea class="w-full border rounded-lg p-3 text-sm" rows="4" id="constructionRejectText" placeholder="请输入拒绝原因..."></textarea>
- </div>
- <div class="modal-footer">
- <button class="btn btn-outline" onclick="closeConstructionRejectModal()">取消</button>
- <button class="btn btn-danger" onclick="submitConstructionReject()">确认拒绝</button>
- </div>
- </div>
- </div>
- <!-- Toast提示 -->
- <div id="toast" class="hidden"></div>
- </div><!-- constructionApp结束 -->
- <script>
- // ==================== 销售端JavaScript ====================
- // 项目数据结构(含子服务项)
- const projects = {
- '积丹白鹭': {
- name: '积丹白鹭',
- contacts: [{name: '张经理', phone: '138****1234'}],
- servicePoints: [
- {name: '1号化粪池', location: '南门地下车库入口旁', serviceType: '清掏'},
- {name: '2号隔油池', location: '商业区B1层餐饮后厨区', serviceType: '清掏'},
- {name: '3号油污管道', location: '住宅区东侧绿化带', serviceType: '疏通'}
- ]
- },
- '富源同坐': {
- name: '富源同坐',
- contacts: [{name: '李主管', phone: '139****5678'}],
- servicePoints: [
- {name: '主化粪池', location: '小区中心花园北侧', serviceType: '清掏'},
- {name: '东侧管道', location: '东门入口排水沟', serviceType: '疏通'},
- {name: '商业区主管', location: '商业街地下主管', serviceType: '排查'}
- ]
- },
- '俊发城': {
- name: '俊发城',
- contacts: [{name: '王物业', phone: '136****8765'}],
- servicePoints: [
- {name: '1号化粪池', location: '1号楼南侧绿化带', serviceType: '清掏'},
- {name: '2号化粪池', location: '3号楼西侧', serviceType: '清掏'},
- {name: '地下主管', location: '地下停车场主排污管', serviceType: '疏通'},
- {name: '5号楼管道', location: '5号楼单元入口', serviceType: '维修'}
- ]
- },
- '逸安新城A区': {
- name: '逸安新城A区',
- contacts: [{name: '赵经理', phone: '137****4321'}],
- servicePoints: [
- {name: 'A1号隔油池', location: '餐饮街后巷', serviceType: '清掏'},
- {name: 'A2号油污管', location: '美食广场B区', serviceType: '疏通'}
- ]
- },
- '逸安新城B区': {
- name: '逸安新城B区',
- contacts: [{name: '陈师傅', phone: '135****9876'}],
- servicePoints: [
- {name: 'B1号化粪池', location: '小区中庭花园', serviceType: '清掏'},
- {name: 'B2号化粪池', location: '4栋北侧', serviceType: '清掏'},
- {name: 'B区主管', location: '小区主排污口', serviceType: '疏通'},
- {name: 'B区支管', location: '儿童游乐区旁', serviceType: '排查'},
- {name: 'B区PVC管', location: '6栋单元主管', serviceType: '维修'}
- ]
- }
- };
- // 任务数据(模拟)
- const taskData = {
- 'task001': {
- id: 'TASK-20240120-001',
- status: '调度中',
- statusClass: 'status-scheduling',
- urgent: '普通',
- urgentClass: 'urgent-normal',
- projectName: '积丹白鹭',
- coopType: '包年',
- facilityType: '油污管',
- address: '昆明市五华区积丹白鹭小区',
- serviceType: '疏通',
- publishTime: '2024-01-20 14:30',
- serviceTime: '2024-01-21 09:00',
- faultLocation: '积丹白鹭小区地下停车场B1层',
- geoLocation: '积丹白鹭小区地下停车场B1层',
- faultDesc: '管道堵塞,污水溢出,需要紧急疏通处理',
- vehicle: '疏通车',
- serviceMode: '应急',
- facility: '油污管',
- waterSource: '有消防水',
- septicTank: '正常',
- constructionHelp: '地库限高2.2米,需注意',
- estimatedQuantity: '2个堵点',
- estimatedHours: '2小时',
- acceptRequirement: '正常走水',
- previousConstruction: '否',
- acceptType: '签署验收计量单',
- contacts: [{name: '陈物业', phone: '138****8888'}],
- partyAContacts: [{name: '陈物业', phone: '138****8888'}],
- team: '班组A',
- remark: '',
- progressStep: 2,
- records: [
- {time: '2024-01-20 14:35', operator: '调度中心', role: 'dispatch', action: '调度中心已接收,正在分配班组'},
- {time: '2024-01-20 14:30', operator: '张销售', role: 'sales', action: '任务已发布'}
- ]
- },
- 'task002': {
- id: 'TASK-20240120-002',
- status: '施工中',
- statusClass: 'status-constructing',
- urgent: '紧急',
- urgentClass: 'urgent-high',
- projectName: '富源同坐',
- coopType: '季度',
- facilityType: '化粪池',
- address: '昆明市西山区富源同坐商业广场',
- serviceType: '清淤',
- publishTime: '2024-01-20 10:15',
- serviceTime: '2024-01-20 11:00',
- faultLocation: '富源同坐商业广场南门',
- geoLocation: '富源同坐商业广场南门',
- faultDesc: '化粪池满溢,影响正常使用',
- vehicle: '吸污车',
- serviceMode: '应急',
- facility: '化粪池',
- waterSource: '无消防水',
- septicTank: '异常',
- constructionHelp: '需在营业前完成',
- estimatedQuantity: '1个池体',
- estimatedHours: '3小时',
- acceptRequirement: '池体清理干净',
- previousConstruction: '是',
- acceptType: '累计自动计费',
- contacts: [{name: '王主管', phone: '139****6666'}],
- partyAContacts: [{name: '王主管', phone: '139****6666'}],
- team: '班组B',
- remark: '需在营业前完成',
- progressStep: 3,
- records: [
- {time: '2024-01-20 11:00', operator: '班组B', role: 'worker', action: '施工人员已到达现场,开始施工'},
- {time: '2024-01-20 10:45', operator: '调度中心', role: 'dispatch', action: '已分配班组:班组B'},
- {time: '2024-01-20 10:30', operator: '调度中心', role: 'dispatch', action: '调度中心已接收任务'},
- {time: '2024-01-20 10:15', operator: '张销售', role: 'sales', action: '任务已发布(紧急)'}
- ]
- },
- 'task003': {
- id: 'TASK-20240119-003',
- status: '已完成',
- statusClass: 'status-completed',
- urgent: '普通',
- urgentClass: 'urgent-normal',
- projectName: '俊发城',
- coopType: '月付',
- facilityType: 'PVC',
- address: '昆明市盘龙区俊发城住宅区',
- serviceType: '维修',
- publishTime: '2024-01-19 09:00',
- serviceTime: '2024-01-19 10:00',
- faultLocation: '俊发城住宅区3号楼',
- geoLocation: '俊发城住宅区3号楼',
- faultDesc: 'PVC管道破裂漏水',
- vehicle: '疏通车',
- serviceMode: '月计划',
- facility: 'PVC',
- waterSource: '有消防水',
- septicTank: '正常',
- constructionHelp: '',
- estimatedQuantity: '1处',
- estimatedHours: '1小时',
- acceptRequirement: '管道修复完成',
- previousConstruction: '否',
- acceptType: '签署验收计量单',
- contacts: [{name: '张经理', phone: '158****2222'}],
- partyAContacts: [{name: '张经理', phone: '158****2222'}],
- team: '班组C',
- remark: '',
- progressStep: 4,
- records: [
- {time: '2024-01-19 16:45', operator: '班组C', role: 'worker', action: '施工完成,任务已结束'},
- {time: '2024-01-19 10:00', operator: '班组C', role: 'worker', action: '施工人员已到达现场,开始施工'},
- {time: '2024-01-19 09:30', operator: '调度中心', role: 'dispatch', action: '已分配班组:班组C'},
- {time: '2024-01-19 09:15', operator: '调度中心', role: 'dispatch', action: '调度中心已接收任务'},
- {time: '2024-01-19 09:00', operator: '张销售', role: 'sales', action: '任务已发布'}
- ]
- },
- 'task004': {
- id: 'TASK-20240120-004',
- status: '应急',
- statusClass: 'status-emergency',
- urgent: '紧急',
- urgentClass: 'urgent-high',
- projectName: '逸安新城A区',
- coopType: '包年',
- facilityType: '油污管',
- address: '昆明市官渡区逸安新城A区',
- serviceType: '疏通',
- publishTime: '2024-01-20 08:30',
- serviceTime: '2024-01-20 09:00',
- faultLocation: '逸安新城A区地下车库入口',
- geoLocation: '逸安新城A区地下车库入口',
- faultDesc: '管道严重堵塞,污水倒灌',
- vehicle: '高压清洗车',
- serviceMode: '应急',
- facility: '油污管',
- waterSource: '有消防水',
- septicTank: '正常',
- constructionHelp: '高峰期车流量大,请尽快处理',
- estimatedQuantity: '3个堵点',
- estimatedHours: '4小时',
- acceptRequirement: '管道畅通',
- previousConstruction: '是',
- acceptType: '签署验收计量单',
- contacts: [{name: '李总', phone: '136****5555'}],
- partyAContacts: [{name: '李总', phone: '136****5555'}],
- team: '应急班组',
- remark: '高峰期车流量大,请尽快处理',
- progressStep: 3,
- records: [
- {time: '2024-01-20 09:05', operator: '应急班组', role: 'worker', action: '应急班组已到达现场,开始施工'},
- {time: '2024-01-20 08:50', operator: '调度中心', role: 'dispatch', action: '已启动应急响应,分配应急班组'},
- {time: '2024-01-20 08:35', operator: '调度中心', role: 'dispatch', action: '收到应急任务请求'},
- {time: '2024-01-20 08:30', operator: '张销售', role: 'sales', action: '任务已发布(应急)'}
- ]
- },
- 'task005': {
- id: 'TASK-20240121-005',
- status: '调度中',
- statusClass: 'status-scheduling',
- urgent: '普通',
- urgentClass: 'urgent-normal',
- projectName: '逸安新城B区',
- coopType: '单次',
- facilityType: '隔油池',
- address: '昆明市官渡区逸安新城B区',
- serviceType: '清掏',
- publishTime: '2024-01-21 09:00',
- serviceTime: '2024-01-22 14:00',
- faultLocation: '逸安新城B区餐饮一条街',
- geoLocation: '逸安新城B区餐饮一条街',
- faultDesc: '隔油池油脂堆积,需要清理维护',
- vehicle: '吸污车',
- serviceMode: '月计划',
- facility: '隔油池',
- waterSource: '有消防水',
- septicTank: '正常',
- constructionHelp: '',
- estimatedQuantity: '1个池体',
- estimatedHours: '2小时',
- acceptRequirement: '池体清洁',
- previousConstruction: '否',
- acceptType: '累计自动计费',
- contacts: [{name: '赵师傅', phone: '158****3333'}],
- partyAContacts: [{name: '赵师傅', phone: '158****3333'}],
- team: '待分配',
- remark: '',
- progressStep: 1,
- records: [
- {time: '2024-01-21 09:00', operator: '张销售', role: 'sales', action: '任务已发布'}
- ]
- }
- };
- // 当前任务的联系人列表(用于详情页)
- let currentTaskContacts = [];
- let currentPartyAContacts = [];
- // 跳转到任务详情
- function goToTaskDetail(taskId) {
- const task = taskData[taskId];
- if (!task) return;
- // 重置联系人列表
- currentTaskContacts = [...task.contacts];
- currentPartyAContacts = task.partyAContacts ? [...task.partyAContacts] : [...task.contacts];
- // 填充详情页数据 - 项目信息
- document.getElementById('detailStatusTag').className = 'status-tag ' + task.statusClass;
- document.getElementById('detailStatusTag').textContent = task.status;
- document.getElementById('detailProjectName').textContent = task.projectName;
- document.getElementById('detailCoopType').innerHTML = '<span class="tag tag-blue">' + (task.coopType || '包年') + '</span>';
- document.getElementById('detailFacilityType').textContent = task.facilityType || '油污管';
- document.getElementById('detailAddress').textContent = task.address || task.projectName;
- // 填充详情页数据 - 施工信息
- document.getElementById('detailServiceTime').textContent = task.serviceTime;
- document.getElementById('detailFaultLocation').textContent = task.faultLocation;
- document.getElementById('detailGeoLocation').innerHTML = '<i class="fas fa-map-marker-alt mr-1"></i>' + (task.geoLocation || task.faultLocation);
- document.getElementById('detailFaultDesc').textContent = task.faultDesc;
- document.getElementById('detailServiceType').textContent = task.serviceType;
- document.getElementById('detailFacility').textContent = task.facility || '油污管';
- document.getElementById('detailServiceMode').textContent = task.serviceMode || '应急';
- document.getElementById('detailVehicle').textContent = task.vehicle;
- document.getElementById('detailWaterSource').textContent = task.waterSource || '有消防水';
- document.getElementById('detailSepticTank').textContent = task.septicTank || '正常';
- document.getElementById('detailConstructionHelp').textContent = task.constructionHelp || '-';
- document.getElementById('detailEstimatedQuantity').textContent = task.estimatedQuantity || '-';
- document.getElementById('detailEstimatedHours').textContent = task.estimatedHours || '-';
- document.getElementById('detailAcceptRequirement').textContent = task.acceptRequirement || '-';
- document.getElementById('detailPreviousConstruction').textContent = task.previousConstruction || '否';
- document.getElementById('detailAcceptType').textContent = task.acceptType;
- document.getElementById('detailRemark').textContent = task.remark || '-';
- // 更新进度条
- updateDetailProgressBar(task.progressStep);
- // 渲染联系人列表(项目联系人)
- renderProjectContactsList();
- // 渲染甲方当事人列表
- renderPartyAContactsList();
- // 渲染处理记录(带角色颜色)
- renderTimelineRecords(task.records);
- // 根据状态显示不同操作按钮
- updateDetailActions(task.status);
- goToPage('taskDetailPage');
- }
- // 更新详情页进度条
- function updateDetailProgressBar(step) {
- const fill = document.getElementById('detailProgressFill');
- const steps = [
- document.getElementById('detailStep1'),
- document.getElementById('detailStep2'),
- document.getElementById('detailStep3'),
- document.getElementById('detailStep4')
- ];
- // 计算进度条填充宽度
- const widths = ['8%', '33%', '58%', '92%'];
- if (fill) fill.style.width = widths[step - 1] || '8%';
- // 更新步骤点状态
- steps.forEach((stepEl, index) => {
- if (!stepEl) return;
- if (index < step) {
- stepEl.classList.add('completed');
- stepEl.classList.remove('active');
- } else if (index === step - 1) {
- stepEl.classList.add('active');
- stepEl.classList.remove('completed');
- } else {
- stepEl.classList.remove('completed', 'active');
- }
- });
- }
- // 渲染项目联系人列表
- function renderProjectContactsList() {
- const container = document.getElementById('detailProjectContacts');
- let html = '';
- currentTaskContacts.forEach((contact) => {
- html += `
- <div class="contact-list-item" style="margin-bottom: 8px;">
- <div class="w-10 h-10 bg-blue-100 rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-user text-blue-500"></i>
- </div>
- <div class="contact-info">
- <span class="contact-name">${contact.name}</span>
- <span class="contact-phone">${contact.phone}</span>
- </div>
- <button class="w-8 h-8 bg-green-100 rounded-full flex items-center justify-center">
- <i class="fas fa-phone text-green-500 text-xs"></i>
- </button>
- </div>
- `;
- });
- container.innerHTML = html;
- }
- // 渲染甲方当事人列表
- function renderPartyAContactsList() {
- const container = document.getElementById('detailPartyAContacts');
- let html = '';
- currentPartyAContacts.forEach((contact) => {
- html += `
- <div class="contact-list-item" style="margin-bottom: 8px;">
- <div class="w-10 h-10 bg-orange-100 rounded-full flex items-center justify-center mr-3">
- <i class="fas fa-user text-orange-500"></i>
- </div>
- <div class="contact-info">
- <span class="contact-name">${contact.name}</span>
- <span class="contact-phone">${contact.phone}</span>
- </div>
- <button class="w-8 h-8 bg-green-100 rounded-full flex items-center justify-center">
- <i class="fas fa-phone text-green-500 text-xs"></i>
- </button>
- </div>
- `;
- });
- container.innerHTML = html;
- }
- // 获取角色图标和颜色类
- function getRoleInfo(operator) {
- if (operator.includes('销售') || operator.includes('张')) {
- return { icon: 'fa-user-tie', colorClass: 'sales', label: '销售' };
- } else if (operator.includes('调度') || operator.includes('中心')) {
- return { icon: 'fa-headset', colorClass: 'dispatch', label: '调度' };
- } else if (operator.includes('班组') || operator.includes('施工') || operator.includes('应急')) {
- return { icon: 'fa-hard-hat', colorClass: 'worker', label: '施工' };
- }
- return { icon: 'fa-user', colorClass: 'sales', label: '未知' };
- }
- // 渲染时间线记录(带角色颜色)
- function renderTimelineRecords(records) {
- const container = document.getElementById('timelineRecords');
- // 按时间倒序排列
- const sortedRecords = [...records].sort((a, b) => b.time.localeCompare(a.time));
- let html = '';
- sortedRecords.forEach((record, index) => {
- const isLatest = index === 0;
- const roleInfo = getRoleInfo(record.operator);
- const currentClass = isLatest ? ' current' : '';
- html += `
- <div class="timeline-record${currentClass}">
- <div class="timeline-avatar ${roleInfo.colorClass}">
- <i class="fas ${roleInfo.icon}"></i>
- </div>
- <div class="timeline-content">
- <div class="timeline-time">${record.time}</div>
- <div class="timeline-action">${record.action}</div>
- <div class="timeline-operator">操作人:${record.operator}</div>
- </div>
- </div>
- `;
- });
- container.innerHTML = html;
- }
- // 更新详情页操作按钮
- function updateDetailActions(status) {
- const actionsDiv = document.getElementById('detailActions');
- if (status === '已完成') {
- actionsDiv.innerHTML = `
- <button class="flex-1 py-3 bg-blue-500 text-white rounded-xl font-medium" onclick="showToast('查看验收单')">
- <i class="fas fa-file-alt mr-1"></i>查看验收单
- </button>
- <button class="flex-1 py-3 bg-white border border-gray-200 text-gray-600 rounded-xl font-medium" onclick="showToast('再次预约')">
- 再次预约
- </button>
- `;
- } else if (status === '施工中') {
- actionsDiv.innerHTML = `
- <button class="flex-1 py-3 bg-white border border-gray-200 text-gray-600 rounded-xl font-medium" onclick="showToast('联系班组')">
- <i class="fas fa-phone mr-1"></i>联系班组
- </button>
- <button class="flex-1 py-3 bg-orange-500 text-white rounded-xl font-medium" onclick="showCancelModal()">
- 申请取消
- </button>
- `;
- } else if (status === '待取消') {
- actionsDiv.innerHTML = `
- <button class="flex-1 py-3 bg-gray-200 text-gray-500 rounded-xl font-medium" disabled>
- 待取消
- </button>
- <button class="flex-1 py-3 bg-blue-500 text-white rounded-xl font-medium" onclick="showToast('催单成功')">
- <i class="fas fa-bell mr-1"></i>催单
- </button>
- `;
- } else {
- actionsDiv.innerHTML = `
- <button class="flex-1 py-3 bg-white border border-gray-200 text-gray-600 rounded-xl font-medium" onclick="showCancelModal()">
- 取消任务
- </button>
- <button class="flex-1 py-3 bg-blue-500 text-white rounded-xl font-medium" onclick="showToast('催单成功')">
- <i class="fas fa-bell mr-1"></i>催单
- </button>
- `;
- }
- }
- // 折叠区块切换
- function toggleSection(sectionId) {
- const section = document.getElementById(sectionId);
- section.classList.toggle('collapsed');
- }
- // 任务筛选功能
- function filterTasks(status) {
- document.querySelectorAll('.filter-tab').forEach(tab => {
- tab.classList.remove('active');
- if (tab.dataset.status === status) {
- tab.classList.add('active');
- }
- });
- const tasks = document.querySelectorAll('.task-card');
- let visibleCount = 0;
- tasks.forEach(card => {
- if (status === 'all' || card.dataset.status === status) {
- card.style.display = 'block';
- visibleCount++;
- } else {
- card.style.display = 'none';
- }
- });
- const emptyState = document.getElementById('taskEmptyState');
- if (visibleCount === 0) {
- emptyState.style.display = 'block';
- } else {
- emptyState.style.display = 'none';
- }
- }
- // 发布任务相关变量
- let selectedProject = null;
- let publishContacts = []; // 项目联系人列表
- let partyAContacts = []; // 甲方当事人列表
- // 项目库扩展信息(用于自动带出)
- const projectExtraInfo = {
- '积丹白鹭': { coopType: '包年', facilityType: '住宅', address: '昆明市五华区积丹白鹭小区' },
- '富源同坐': { coopType: '季度', facilityType: '商业', address: '昆明市西山区富源同坐商业广场' },
- '俊发城': { coopType: '月付', facilityType: '住宅', address: '昆明市盘龙区俊发城小区' },
- '逸安新城A区': { coopType: '包年', facilityType: '住宅', address: '昆明市官渡区逸安新城A区' },
- '逸安新城B区': { coopType: '单次', facilityType: '市政', address: '昆明市官渡区逸安新城B区' }
- };
- // 项目选择变更事件
- function onProjectSelectChange() {
- const projectName = document.getElementById('projectSelect').value;
- const hint = document.getElementById('projectSelectHint');
- const hintText = document.getElementById('projectHintText');
- const autoInfo = document.getElementById('projectAutoInfo');
- const newForm = document.getElementById('newProjectForm');
- // 清空联系人列表
- publishContacts = [];
- partyAContacts = [];
- if (projectName === '') {
- // 未选择
- hint.style.display = 'flex';
- hintText.textContent = '请从项目库选择或新增项目';
- autoInfo.style.display = 'none';
- newForm.style.display = 'none';
- document.getElementById('projectSelectHint').className = 'bg-blue-50 rounded-lg px-3 py-2 mb-4 flex items-center';
- document.querySelector('#projectSelectHint i').className = 'fas fa-info-circle text-blue-500 mr-2 text-sm';
- selectedProject = null;
- } else if (projectName === 'new') {
- // 新增项目
- hint.style.display = 'flex';
- hintText.textContent = '新增项目';
- autoInfo.style.display = 'none';
- newForm.style.display = 'block';
- document.getElementById('projectSelectHint').className = 'bg-orange-50 rounded-lg px-3 py-2 mb-4 flex items-center';
- document.querySelector('#projectSelectHint i').className = 'fas fa-edit text-orange-500 mr-2 text-sm';
- selectedProject = null;
- // 清空新增表单
- document.getElementById('newProjectName').value = '';
- document.getElementById('newCoopType').value = '';
- document.getElementById('newFacilityType').value = '';
- document.getElementById('newProjectAddress').value = '';
- } else {
- // 选择了已有项目
- hint.style.display = 'flex';
- hintText.textContent = '已选择:' + projectName + '项目';
- autoInfo.style.display = 'block';
- newForm.style.display = 'none';
- document.getElementById('projectSelectHint').className = 'bg-green-50 rounded-lg px-3 py-2 mb-4 flex items-center';
- document.querySelector('#projectSelectHint i').className = 'fas fa-check-circle text-green-500 mr-2 text-sm';
- // 显示自动带出的信息
- document.getElementById('selectedProjectName').textContent = projectName;
- const extraInfo = projectExtraInfo[projectName] || { coopType: '-', facilityType: '-', address: '-' };
- document.getElementById('autoCoopType').textContent = extraInfo.coopType;
- document.getElementById('autoFacilityType').textContent = extraInfo.facilityType;
- document.getElementById('autoProjectAddress').textContent = extraInfo.address;
- // 设置选中项目
- selectedProject = projects[projectName] || null;
- // 自动填充联系人(从项目联系人中获取)
- if (selectedProject && selectedProject.contacts && selectedProject.contacts.length > 0) {
- publishContacts = [...selectedProject.contacts];
- partyAContacts = [...selectedProject.contacts];
- }
- // 自动填充故障位置
- if (selectedProject && selectedProject.servicePoints && selectedProject.servicePoints.length > 0) {
- document.getElementById('faultLocation').value = selectedProject.servicePoints[0].location;
- document.getElementById('faultLocation').classList.add('auto-filled');
- document.getElementById('faultLocationLabel').style.display = 'block';
- }
- }
- // 渲染联系人列表
- renderProjectContacts();
- renderPartyAContacts();
- }
- // 重置项目选择
- function resetProjectSelection() {
- document.getElementById('projectSelect').value = '';
- onProjectSelectChange();
- // 清空故障位置
- document.getElementById('faultLocation').value = '';
- document.getElementById('faultLocation').classList.remove('auto-filled');
- document.getElementById('faultLocationLabel').style.display = 'none';
- }
- // 渲染项目联系人列表
- function renderProjectContacts() {
- const container = document.getElementById('contactListContainer');
- if (publishContacts.length === 0) {
- container.innerHTML = '<div class="text-gray-400 text-sm text-center py-2">暂无联系人,请添加</div>';
- return;
- }
- let html = '';
- publishContacts.forEach((contact, index) => {
- html += `
- <div class="contact-list-item" data-index="${index}">
- <div class="contact-info" style="flex-direction: column; align-items: flex-start;">
- <div class="flex gap-2 w-full">
- <input type="text" class="form-input" value="${contact.name}"
- placeholder="姓名" style="flex: 1; padding: 8px 10px; font-size: 13px;"
- onchange="updateProjectContact(${index}, 'name', this.value)">
- <input type="tel" class="form-input" value="${contact.phone}"
- placeholder="电话" style="flex: 1; padding: 8px 10px; font-size: 13px;"
- onchange="updateProjectContact(${index}, 'phone', this.value)">
- </div>
- </div>
- <div class="delete-btn" onclick="removeProjectContact(${index})">
- <i class="fas fa-times"></i>
- </div>
- </div>
- `;
- });
- container.innerHTML = html;
- }
- // 添加项目联系人
- function addContactItem() {
- publishContacts.push({name: '', phone: ''});
- renderProjectContacts();
- }
- // 删除项目联系人
- function removeProjectContact(index) {
- publishContacts.splice(index, 1);
- renderProjectContacts();
- }
- // 更新项目联系人信息
- function updateProjectContact(index, field, value) {
- if (publishContacts[index]) {
- publishContacts[index][field] = value;
- }
- }
- // 渲染甲方当事人列表
- function renderPartyAContacts() {
- const container = document.getElementById('partyAContactList');
- if (partyAContacts.length === 0) {
- container.innerHTML = '<div class="text-gray-400 text-sm text-center py-2">暂无甲方当事人,请添加</div>';
- return;
- }
- let html = '';
- partyAContacts.forEach((contact, index) => {
- html += `
- <div class="contact-list-item" data-index="${index}">
- <div class="contact-info" style="flex-direction: column; align-items: flex-start;">
- <div class="flex gap-2 w-full">
- <input type="text" class="form-input" value="${contact.name}"
- placeholder="姓名" style="flex: 1; padding: 8px 10px; font-size: 13px;"
- onchange="updatePartyAContact(${index}, 'name', this.value)">
- <input type="tel" class="form-input" value="${contact.phone}"
- placeholder="电话" style="flex: 1; padding: 8px 10px; font-size: 13px;"
- onchange="updatePartyAContact(${index}, 'phone', this.value)">
- </div>
- </div>
- <div class="delete-btn" onclick="removePartyAContact(${index})">
- <i class="fas fa-times"></i>
- </div>
- </div>
- `;
- });
- container.innerHTML = html;
- }
- // 添加甲方当事人
- function addPartyAContact() {
- partyAContacts.push({name: '', phone: ''});
- renderPartyAContacts();
- }
- // 删除甲方当事人
- function removePartyAContact(index) {
- partyAContacts.splice(index, 1);
- renderPartyAContacts();
- }
- // 更新甲方当事人信息
- function updatePartyAContact(index, field, value) {
- if (partyAContacts[index]) {
- partyAContacts[index][field] = value;
- }
- }
- // 提交任务
- function submitTask() {
- const projectSelect = document.getElementById('projectSelect').value;
- const serviceDate = document.getElementById('serviceDate').value;
- const serviceTime = document.getElementById('serviceTime').value;
- const faultLocation = document.getElementById('faultLocation').value;
- const faultDesc = document.getElementById('faultDesc').value;
- const serviceType = document.getElementById('serviceType').value;
- const facilityType = document.getElementById('serviceFacilityType').value;
- const serviceMode = document.getElementById('serviceMode').value;
- const vehicleType = document.getElementById('vehicleType').value;
- const acceptType = document.getElementById('acceptType').value;
- // 验证必填项 - 项目选择
- if (!projectSelect) {
- showToast('请选择项目');
- return;
- }
- // 如果选择新增项目,验证新增表单
- if (projectSelect === 'new') {
- const newProjectName = document.getElementById('newProjectName').value;
- const newCoopType = document.getElementById('newCoopType').value;
- const newFacilityType = document.getElementById('newFacilityType').value;
- const newProjectAddress = document.getElementById('newProjectAddress').value;
- if (!newProjectName) {
- showToast('请输入项目名称');
- return;
- }
- if (!newCoopType) {
- showToast('请选择合作类型');
- return;
- }
- if (!newFacilityType) {
- showToast('请选择设施类型');
- return;
- }
- if (!newProjectAddress) {
- showToast('请输入项目地址');
- return;
- }
- }
- // 验证必填项 - 服务信息
- if (!serviceDate || !serviceTime) {
- showToast('请选择服务时间');
- return;
- }
- if (!faultLocation) {
- showToast('请填写故障位置');
- return;
- }
- if (!faultDesc) {
- showToast('请填写故障描述');
- return;
- }
- if (!serviceType) {
- showToast('请选择施工类型');
- return;
- }
- if (!facilityType) {
- showToast('请选择施工设施');
- return;
- }
- if (!serviceMode) {
- showToast('请选择服务方式');
- return;
- }
- if (!vehicleType) {
- showToast('请选择建议出车');
- return;
- }
- if (!acceptType) {
- showToast('请选择验收方式');
- return;
- }
- // 检查甲方当事人
- const validPartyA = partyAContacts.filter(c => c.name && c.phone);
- if (validPartyA.length === 0) {
- showToast('请至少添加一个甲方当事人');
- return;
- }
- showToast('发布成功');
- setTimeout(() => {
- resetPublishForm();
- goToPage('taskPage');
- }, 1500);
- }
- // 重置发布表单
- function resetPublishForm() {
- document.getElementById('projectSelect').value = '';
- selectedProject = null;
- publishContacts = [];
- partyAContacts = [];
- // 重置提示区域
- document.getElementById('projectSelectHint').style.display = 'flex';
- document.getElementById('projectSelectHint').className = 'bg-blue-50 rounded-lg px-3 py-2 mb-4 flex items-center';
- document.querySelector('#projectSelectHint i').className = 'fas fa-info-circle text-blue-500 mr-2 text-sm';
- document.getElementById('projectHintText').textContent = '请从项目库选择或新增项目';
- document.getElementById('projectAutoInfo').style.display = 'none';
- document.getElementById('newProjectForm').style.display = 'none';
- // 清空新增表单
- document.getElementById('newProjectName').value = '';
- document.getElementById('newCoopType').value = '';
- document.getElementById('newFacilityType').value = '';
- document.getElementById('newProjectAddress').value = '';
- // 清空服务信息表单
- document.getElementById('serviceDate').value = '';
- document.getElementById('serviceTime').value = '';
- document.getElementById('faultLocation').value = '';
- document.getElementById('faultLocation').classList.remove('auto-filled');
- document.getElementById('faultLocationLabel').style.display = 'none';
- document.getElementById('faultDesc').value = '';
- document.getElementById('serviceType').value = '';
- document.getElementById('serviceFacilityType').value = '';
- document.getElementById('serviceMode').value = '';
- document.getElementById('vehicleType').value = '';
- document.getElementById('acceptType').value = '';
- document.getElementById('remark').value = '';
- // 清空联系人列表
- renderProjectContacts();
- renderPartyAContacts();
- }
- // 兼容旧函数(保留以防其他地方调用)
- function goToStep(step) {
- // 新版单页面不需要步骤切换
- }
- function onProjectChange() {
- onProjectSelectChange();
- }
- function onServicePointChange() {
- // 新版不需要服务点选择
- }
- function resetSelection() {
- resetProjectSelection();
- }
- function initPublishContacts() {
- renderProjectContacts();
- }
- function fillFormWithServicePoint() {
- // 新版自动填充在onProjectSelectChange中处理
- }
- // Toast提示
- function showToast(message) {
- const toast = document.getElementById('toast');
- toast.textContent = message;
- toast.classList.remove('hidden');
- setTimeout(() => {
- toast.classList.add('hidden');
- }, 2000);
- }
- // 页面跳转
- function goToPage(pageId) {
- document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
- document.getElementById(pageId).classList.add('active');
- window.scrollTo(0, 0);
- }
- // ========== 销售端消息通知相关 ==========
- function markAllMessagesRead() {
- showToast('全部消息已标记为已读');
- // 重置所有未读标记
- document.querySelectorAll('.notice-item').forEach(item => {
- const dot = item.querySelector('.bg-red-500');
- if (dot) {
- dot.classList.remove('bg-red-500');
- dot.classList.add('bg-gray-200');
- }
- });
- }
- // 销售端消息通知页tab切换
- function filterSalesNotifications(type, element) {
- // 更新按钮样式
- document.querySelectorAll('.sales-notification-tab').forEach(btn => {
- btn.classList.remove('bg-blue-500', 'text-white');
- btn.classList.add('bg-gray-100', 'text-gray-600');
- });
- element.classList.remove('bg-gray-100', 'text-gray-600');
- element.classList.add('bg-blue-500', 'text-white');
- // 筛选通知列表
- const items = document.querySelectorAll('#salesNotificationList .notification-item');
- items.forEach(item => {
- if (type === 'all' || item.dataset.type === type) {
- item.style.display = 'block';
- } else {
- item.style.display = 'none';
- }
- });
- }
- function filterMessages(type) {
- // 更新按钮样式
- event.target.parentElement.querySelectorAll('button').forEach(btn => {
- btn.classList.remove('bg-blue-500', 'text-white');
- btn.classList.add('bg-gray-100', 'text-gray-600');
- });
- event.target.classList.remove('bg-gray-100', 'text-gray-600');
- event.target.classList.add('bg-blue-500', 'text-white');
- showToast('已筛选:' + (type === 'all' ? '全部消息' : type === 'task' ? '任务消息' : '系统消息'));
- }
- function toggleFaq(element) {
- const answer = element.nextElementSibling;
- const icon = element.querySelector('i');
- if (answer.classList.contains('hidden')) {
- answer.classList.remove('hidden');
- icon.classList.remove('fa-chevron-down');
- icon.classList.add('fa-chevron-up');
- } else {
- answer.classList.add('hidden');
- icon.classList.remove('fa-chevron-up');
- icon.classList.add('fa-chevron-down');
- }
- }
- function submitChangePassword() {
- const currentPwd = document.getElementById('currentPassword').value;
- const newPwd = document.getElementById('newPassword').value;
- const confirmPwd = document.getElementById('confirmNewPassword').value;
- if (!currentPwd) {
- showToast('请输入当前密码');
- return;
- }
- if (!newPwd) {
- showToast('请输入新密码');
- return;
- }
- if (newPwd.length < 6 || newPwd.length > 20) {
- showToast('新密码长度需为6-20位');
- return;
- }
- if (!/^(?=.*[a-zA-Z])(?=.*[0-9])/.test(newPwd)) {
- showToast('新密码必须包含字母和数字');
- return;
- }
- if (newPwd !== confirmPwd) {
- showToast('两次输入的密码不一致');
- return;
- }
- if (currentPwd === newPwd) {
- showToast('新密码不能与当前密码相同');
- return;
- }
- showToast('密码修改成功');
- setTimeout(() => {
- goToPage('profilePage');
- }, 1000);
- }
- // 项目筛选功能
- function filterProjects(type) {
- // 更新标签选中状态
- document.querySelectorAll('.filter-tab').forEach(tab => {
- tab.classList.remove('active');
- if (tab.dataset.type === type) {
- tab.classList.add('active');
- }
- });
- // 筛选项目卡片
- const projects = document.querySelectorAll('.project-card');
- let visibleCount = 0;
- projects.forEach(card => {
- if (type === 'all' || card.dataset.type === type) {
- card.classList.remove('hidden');
- visibleCount++;
- } else {
- card.classList.add('hidden');
- }
- });
- // 显示/隐藏空状态
- const emptyState = document.getElementById('emptyState');
- if (visibleCount === 0) {
- emptyState.style.display = 'block';
- } else {
- emptyState.style.display = 'none';
- }
- }
- // 添加联系人
- function addContact() {
- const container = document.getElementById('contactsContainer');
- const newContact = document.createElement('div');
- newContact.className = 'contact-card';
- newContact.innerHTML = `
- <div class="flex gap-2 mb-2">
- <input type="text" class="form-input contact-name" placeholder="联系人姓名" style="flex:1">
- <input type="tel" class="form-input contact-phone" placeholder="联系电话" style="flex:1">
- </div>
- <div class="text-right">
- <span class="text-red-400 text-xs cursor-pointer" onclick="this.parentElement.parentElement.remove()">删除</span>
- </div>
- `;
- container.appendChild(newContact);
- }
- // 添加服务点
- function addPoint() {
- const container = document.getElementById('pointsContainer');
- const pointCount = container.querySelectorAll('.point-item').length + 1;
- const newPoint = document.createElement('div');
- newPoint.className = 'point-item';
- newPoint.innerHTML = `
- <div class="flex items-center justify-between mb-2">
- <span class="text-gray-600 text-xs font-medium">服务点 ${pointCount}</span>
- <i class="fas fa-trash-alt text-red-400 ml-2 cursor-pointer" onclick="this.parentElement.parentElement.remove()"></i>
- </div>
- <input type="text" class="form-input point-name mb-2" placeholder="服务点名称(如:1号化粪池)">
- <input type="text" class="form-input point-location mb-2" placeholder="位置(如:南门地下车库)">
- <input type="text" class="form-input point-service" placeholder="对应服务项(如:清掏)">
- `;
- container.appendChild(newPoint);
- }
- // 提交项目
- function submitProject() {
- const projectName = document.getElementById('projectName').value;
- const cooperationType = document.getElementById('cooperationType').value;
- if (!projectName) {
- showToast('请输入项目名称');
- return;
- }
- if (!cooperationType) {
- showToast('请选择合作类型');
- return;
- }
- showToast('提交成功!');
- setTimeout(() => {
- goToPage('projectListPage');
- }, 2000);
- }
- // 初始化筛选状态
- filterProjects('all');
- // ========== 模态框相关函数 ==========
- // 显示取消任务模态框
- function showCancelModal() {
- document.getElementById('cancelModal').classList.remove('hidden');
- document.getElementById('cancelReason').value = '';
- }
- // 隐藏取消任务模态框
- function hideCancelModal() {
- document.getElementById('cancelModal').classList.add('hidden');
- }
- // 点击模态框背景关闭
- document.addEventListener('click', function(e) {
- if (e.target.classList.contains('modal-overlay')) {
- e.target.classList.add('hidden');
- }
- });
- // 确认取消任务
- function confirmCancel() {
- const reason = document.getElementById('cancelReason').value.trim();
- if (!reason) {
- showToast('请输入取消原因');
- return;
- }
- // 添加取消记录
- const now = new Date();
- const timeStr = now.getFullYear() + '-' +
- String(now.getMonth() + 1).padStart(2, '0') + '-' +
- String(now.getDate()).padStart(2, '0') + ' ' +
- String(now.getHours()).padStart(2, '0') + ':' +
- String(now.getMinutes()).padStart(2, '0');
- // 更新状态标签
- document.getElementById('detailStatusTag').className = 'status-tag';
- document.getElementById('detailStatusTag').style.background = '#fef3c7';
- document.getElementById('detailStatusTag').style.color = '#d97706';
- document.getElementById('detailStatusTag').textContent = '待取消';
- // 更新处理记录 - 使用新的时间线样式
- const timelineRecords = document.getElementById('timelineRecords');
- const roleInfo = getRoleInfo('张销售');
- const newRecordHtml = `
- <div class="timeline-record current">
- <div class="timeline-avatar ${roleInfo.colorClass}">
- <i class="fas ${roleInfo.icon}"></i>
- </div>
- <div class="timeline-content">
- <div class="timeline-time">${timeStr}</div>
- <div class="timeline-action">提交取消申请,取消原因:${reason}</div>
- <div class="timeline-operator">操作人:张销售</div>
- </div>
- </div>
- `;
- // 移除最新记录的高亮
- const currentRecords = timelineRecords.querySelectorAll('.timeline-record');
- currentRecords.forEach(rec => rec.classList.remove('current'));
- // 添加新记录到最前面
- timelineRecords.insertAdjacentHTML('afterbegin', newRecordHtml);
- // 更新底部按钮
- updateDetailActions('待取消');
- // 隐藏模态框
- hideCancelModal();
- // 显示提示
- showToast('已提交取消申请,等待调度中心确认');
- }
- // 显示添加联系人模态框
- function showAddContactModal() {
- document.getElementById('addContactModal').classList.remove('hidden');
- document.getElementById('newContactName').value = '';
- document.getElementById('newContactPhone').value = '';
- }
- // 隐藏添加联系人模态框
- function hideAddContactModal() {
- document.getElementById('addContactModal').classList.add('hidden');
- }
- // 确认添加联系人
- function confirmAddContact() {
- const name = document.getElementById('newContactName').value.trim();
- const phone = document.getElementById('newContactPhone').value.trim();
- if (!name) {
- showToast('请输入联系人姓名');
- return;
- }
- if (!phone) {
- showToast('请输入联系电话');
- return;
- }
- // 添加到联系人列表
- currentTaskContacts.push({name: name, phone: phone});
- currentPartyAContacts.push({name: name, phone: phone});
- renderProjectContactsList();
- renderPartyAContactsList();
- // 添加处理记录 - 使用新的时间线样式
- const now = new Date();
- const timeStr = now.getFullYear() + '-' +
- String(now.getMonth() + 1).padStart(2, '0') + '-' +
- String(now.getDate()).padStart(2, '0') + ' ' +
- String(now.getHours()).padStart(2, '0') + ':' +
- String(now.getMinutes()).padStart(2, '0');
- const timelineRecords = document.getElementById('timelineRecords');
- const roleInfo = getRoleInfo('张销售');
- const newRecordHtml = `
- <div class="timeline-record current">
- <div class="timeline-avatar ${roleInfo.colorClass}">
- <i class="fas ${roleInfo.icon}"></i>
- </div>
- <div class="timeline-content">
- <div class="timeline-time">${timeStr}</div>
- <div class="timeline-action">新增联系人:${name} (${phone})</div>
- <div class="timeline-operator">操作人:张销售</div>
- </div>
- </div>
- `;
- // 移除最新记录的高亮
- const currentRecords = timelineRecords.querySelectorAll('.timeline-record');
- currentRecords.forEach(rec => rec.classList.remove('current'));
- // 添加新记录到最前面
- timelineRecords.insertAdjacentHTML('afterbegin', newRecordHtml);
- // 隐藏模态框
- hideAddContactModal();
- // 显示提示
- showToast('联系人添加成功');
- }
- // 显示补充信息模态框
- function showSupplementModal() {
- showToast('补充信息功能开发中');
- }
- // ==================== 调度端JavaScript ====================
- let currentRole = 'dispatch';
- let currentYear = 2026;
- let currentMonth = 3;
- let selectedDate = 21;
- let selectedScheduleType = 'monthly';
- let currentTaskFilter = 'all';
- const teamsData = {
- 'zhang': { name: '张师傅组', members: ['张三', '李四'] },
- 'wang': { name: '王师傅组', members: ['王五', '赵六'] },
- 'liu': { name: '刘师傅组', members: ['刘七', '陈八'] }
- };
- const vehiclesData = {
- 'v1': { name: '疏通车01', plate: '贵A81356' },
- 'v2': { name: '疏通车02', plate: '贵A82345' },
- 'v3': { name: '吸污车03', plate: '贵A83456' },
- 'v4': { name: '吸污车04', plate: '贵A84567' },
- 'v5': { name: '高压清洗车05', plate: '贵A85678' }
- };
- const schedulesData = {
- '2026-04-21': [
- { id: 1, teamKey: 'zhang', vehicleKey: 'v1', type: 'monthly', remark: '' },
- { id: 2, teamKey: 'wang', vehicleKey: 'v3', type: 'emergency', remark: '应急响应' }
- ],
- '2026-04-22': [
- { id: 3, teamKey: 'wang', vehicleKey: 'v2', type: 'monthly', remark: '' }
- ],
- '2026-04-15': [
- { id: 4, teamKey: 'liu', vehicleKey: 'v5', type: 'monthly', remark: '定期清洗' }
- ],
- '2026-04-18': [
- { id: 5, teamKey: 'zhang', vehicleKey: 'v4', type: 'emergency', remark: '紧急疏通' }
- ]
- };
- // 任务数据
- const tasksData = {
- 'T001': { title: '积丹白鹭小区疏通', address: '积丹白鹭小区A栋', type: '油污管疏通', time: '今天 09:30', applicant: '李明', status: 'pending' },
- 'T002': { title: '俊发城应急疏通', address: '俊发城住宅区', type: '化粪池清理', time: '今天 10:15', applicant: '王芳', status: 'pending' },
- 'T003': { title: '逸安新城日常维护', address: '逸安新城A区', type: '日常维护', time: '今天 08:00', applicant: '系统', status: 'processing', team: '张师傅组', vehicle: '疏通车01' },
- 'T004': { title: '富源同坐管道检修', address: '富源同坐商业广场', type: '管道检修', time: '昨天 16:30', applicant: '赵经理', status: 'completed', team: '王师傅组', vehicle: '吸污车03' },
- 'T005': { title: '云岩大厦排污', address: '云岩大厦', type: '排污处理', time: '昨天 14:20', applicant: '陈主管', status: 'rejected', rejectReason: '设备临时故障' },
- 'T006': { title: '新都国际管道维修', address: '新都国际小区', type: '管道维修', time: '今天 11:00', applicant: '周经理', status: 'confirmed' }
- };
- let currentDetailTaskId = null;
- function goToDispatchPage(pageId) {
- document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
- document.getElementById(pageId).classList.add('active');
- // 更新导航高亮
- document.querySelectorAll('.nav-item').forEach(item => {
- if (item.dataset.page === pageId) {
- item.classList.add('active');
- } else {
- item.classList.remove('active');
- }
- });
- // 渲染对应页面内容
- if (pageId === 'dispatch_schedulePage') {
- renderScheduleCalendar();
- renderScheduleList();
- } else if (pageId === 'dispatch_taskPage') {
- filterTasks(currentTaskFilter);
- } else if (pageId === 'dispatch_notificationPage') {
- renderDispatchNotificationList();
- }
- }
- // ========== 调度端消息通知相关 ==========
- function markAllRead() {
- showToast('全部消息已标记为已读');
- // 重置所有未读标记
- document.querySelectorAll('.notice-item').forEach(item => {
- const dot = item.querySelector('.bg-red-500');
- if (dot) {
- dot.classList.remove('bg-red-500');
- dot.classList.add('bg-gray-200');
- }
- });
- }
- function filterNotification(type) {
- // 更新按钮样式
- event.target.parentElement.querySelectorAll('button').forEach(btn => {
- btn.classList.remove('bg-blue-500', 'text-white');
- btn.classList.add('bg-gray-100', 'text-gray-600');
- });
- event.target.classList.remove('bg-gray-100', 'text-gray-600');
- event.target.classList.add('bg-blue-500', 'text-white');
- showToast('已筛选:' + (type === 'all' ? '全部' : type === 'task' ? '任务分配' : type === 'audit' ? '审核结果' : '系统消息'));
- }
- function toggleDispatchFaq(element) {
- const answer = element.nextElementSibling;
- const icon = element.querySelector('i');
- if (answer.classList.contains('hidden')) {
- answer.classList.remove('hidden');
- icon.classList.remove('fa-chevron-down');
- icon.classList.add('fa-chevron-up');
- } else {
- answer.classList.add('hidden');
- icon.classList.remove('fa-chevron-up');
- icon.classList.add('fa-chevron-down');
- }
- }
- function submitDispatchChangePassword() {
- const currentPwd = document.getElementById('dispatchCurrentPassword').value;
- const newPwd = document.getElementById('dispatchNewPassword').value;
- const confirmPwd = document.getElementById('dispatchConfirmNewPassword').value;
- if (!currentPwd) {
- showToast('请输入当前密码');
- return;
- }
- if (!newPwd) {
- showToast('请输入新密码');
- return;
- }
- if (newPwd.length < 6 || newPwd.length > 20) {
- showToast('新密码长度需为6-20位');
- return;
- }
- if (!/^(?=.*[a-zA-Z])(?=.*[0-9])/.test(newPwd)) {
- showToast('新密码必须包含字母和数字');
- return;
- }
- if (newPwd !== confirmPwd) {
- showToast('两次输入的密码不一致');
- return;
- }
- if (currentPwd === newPwd) {
- showToast('新密码不能与当前密码相同');
- return;
- }
- showToast('密码修改成功');
- setTimeout(() => {
- goToDispatchPage('dispatch_myPage');
- }, 1000);
- }
- function logout() {
- goToDispatchPage('loginPage');
- showToast('已退出登录');
- }
- // ========== 排班页面相关 ==========
- function renderScheduleCalendar() {
- const calendarTitle = document.getElementById('calendarTitle2');
- if (calendarTitle) {
- calendarTitle.textContent = `${currentYear}年${currentMonth + 1}月`;
- }
- const calendarDays = document.getElementById('calendarDays2');
- if (!calendarDays) return;
- calendarDays.innerHTML = '';
- const firstDay = new Date(currentYear, currentMonth, 1);
- const lastDay = new Date(currentYear, currentMonth + 1, 0);
- const startWeekday = firstDay.getDay() || 7;
- for (let i = 1; i < startWeekday; i++) {
- const emptyDay = document.createElement('div');
- emptyDay.className = 'calendar-day other-month';
- emptyDay.textContent = new Date(currentYear, currentMonth, 1 - startWeekday + i).getDate();
- calendarDays.appendChild(emptyDay);
- }
- const today = new Date();
- for (let day = 1; day <= lastDay.getDate(); day++) {
- const dayElement = document.createElement('div');
- dayElement.className = 'calendar-day';
- const dateStr = `${currentYear}-${String(currentMonth + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
- const isToday = today.getFullYear() === currentYear && today.getMonth() === currentMonth && today.getDate() === day;
- const isSelected = selectedDate === day;
- if (isToday) {
- dayElement.classList.add('today');
- }
- if (isSelected) {
- dayElement.classList.add('selected');
- }
- const dayNumberHtml = isToday ? `<span class="day-number">${day}</span>` : `<span>${day}</span>`;
- dayElement.innerHTML = `
- ${dayNumberHtml}
- ${getDayDotsHtml(dateStr)}
- `;
- dayElement.addEventListener('click', () => selectDate(day, dateStr));
- calendarDays.appendChild(dayElement);
- }
- }
- function getDayDotsHtml(dateStr) {
- const schedules = schedulesData[dateStr];
- if (!schedules || schedules.length === 0) return '';
- let dotsHtml = '<div class="day-dots">';
- schedules.forEach(s => {
- const dotClass = s.type === 'monthly' ? 'monthly' : 'emergency';
- dotsHtml += `<div class="day-dot ${dotClass}"></div>`;
- });
- dotsHtml += '</div>';
- return dotsHtml;
- }
- function selectDate(day, dateStr) {
- selectedDate = day;
- renderScheduleCalendar();
- renderScheduleList();
- openDateDetailModal(dateStr, day);
- }
- function changeMonth(delta) {
- currentMonth += delta;
- if (currentMonth > 11) {
- currentMonth = 0;
- currentYear++;
- } else if (currentMonth < 0) {
- currentMonth = 11;
- currentYear--;
- }
- renderScheduleCalendar();
- }
- function renderScheduleList() {
- const listTitle = document.getElementById('scheduleListTitle');
- if (listTitle) {
- listTitle.textContent = `${currentMonth + 1}月${selectedDate}日 排班`;
- }
- const scheduleList = document.getElementById('scheduleList');
- if (!scheduleList) return;
- const dateStr = `${currentYear}-${String(currentMonth + 1).padStart(2, '0')}-${String(selectedDate).padStart(2, '0')}`;
- const schedules = schedulesData[dateStr] || [];
- if (schedules.length === 0) {
- scheduleList.innerHTML = `
- <div class="empty-state">
- <i class="fas fa-calendar-times"></i>
- <p>暂无排班安排</p>
- </div>
- `;
- return;
- }
- scheduleList.innerHTML = schedules.map(s => {
- const team = teamsData[s.teamKey];
- const vehicle = vehiclesData[s.vehicleKey];
- const iconClass = s.type === 'monthly' ? 'monthly' : 'emergency';
- const tagClass = s.type === 'monthly' ? 'tag-blue' : 'tag-orange';
- const tagText = s.type === 'monthly' ? '月计划' : '应急';
- return `
- <div class="schedule-card">
- <div class="schedule-icon ${iconClass}">
- <i class="fas ${s.type === 'monthly' ? 'fa-calendar-check' : 'fa-bolt'}"></i>
- </div>
- <div class="schedule-info">
- <div class="schedule-team">${team.name}</div>
- <div class="schedule-vehicle">
- <i class="fas fa-truck"></i>
- ${vehicle.name}(${vehicle.plate})
- </div>
- <div class="schedule-time">
- <span class="tag ${tagClass}">${tagText}</span>
- ${s.remark ? `<span style="margin-left: 8px; color: #999;">${s.remark}</span>` : ''}
- </div>
- </div>
- </div>
- `;
- }).join('');
- }
- function openAddScheduleModal() {
- document.getElementById('addScheduleModal').classList.add('active');
- document.getElementById('teamSelect').value = '';
- document.getElementById('vehicleSelect').value = '';
- document.getElementById('scheduleRemark').value = '';
- selectType('monthly');
- }
- function closeAddScheduleModal() {
- document.getElementById('addScheduleModal').classList.remove('active');
- }
- function selectType(type) {
- selectedScheduleType = type;
- document.querySelectorAll('.type-option').forEach(opt => {
- opt.classList.remove('selected');
- });
- document.querySelector(`.type-option.${type}`).classList.add('selected');
- }
- function confirmAddSchedule() {
- const teamKey = document.getElementById('teamSelect').value;
- const vehicleKey = document.getElementById('vehicleSelect').value;
- const remark = document.getElementById('scheduleRemark').value;
- if (!teamKey) {
- showToast('请选择班组');
- return;
- }
- if (!vehicleKey) {
- showToast('请选择车辆');
- return;
- }
- const dateStr = `${currentYear}-${String(currentMonth + 1).padStart(2, '0')}-${String(selectedDate).padStart(2, '0')}`;
- if (!schedulesData[dateStr]) {
- schedulesData[dateStr] = [];
- }
- const newId = Date.now();
- schedulesData[dateStr].push({
- id: newId,
- teamKey: teamKey,
- vehicleKey: vehicleKey,
- type: selectedScheduleType,
- remark: remark
- });
- closeAddScheduleModal();
- renderScheduleCalendar();
- renderScheduleList();
- showToast('排班添加成功');
- }
- function openDateDetailModal(dateStr, day) {
- document.getElementById('dateDetailTitle').textContent = `${currentMonth + 1}月${day}日 排班详情`;
- const detailList = document.getElementById('dateDetailList');
- const schedules = schedulesData[dateStr] || [];
- if (schedules.length === 0) {
- detailList.innerHTML = `
- <div class="empty-state">
- <i class="fas fa-calendar-times"></i>
- <p>暂无排班安排</p>
- <button class="btn btn-primary mt-4" onclick="addScheduleForDate()">
- <i class="fas fa-plus mr-1"></i>新增排班
- </button>
- </div>
- `;
- } else {
- detailList.innerHTML = schedules.map(s => {
- const team = teamsData[s.teamKey];
- const vehicle = vehiclesData[s.vehicleKey];
- const iconClass = s.type === 'monthly' ? 'monthly' : 'emergency';
- const tagClass = s.type === 'monthly' ? 'tag-blue' : 'tag-orange';
- const tagText = s.type === 'monthly' ? '月计划' : '应急';
- return `
- <div class="schedule-card">
- <div class="schedule-icon ${iconClass}">
- <i class="fas ${s.type === 'monthly' ? 'fa-calendar-check' : 'fa-bolt'}"></i>
- </div>
- <div class="schedule-info">
- <div class="schedule-team">${team.name}</div>
- <div class="schedule-vehicle">
- <i class="fas fa-truck"></i>
- ${vehicle.name}(${vehicle.plate})
- </div>
- <div style="margin-top: 4px;">
- <span class="tag ${tagClass}">${tagText}</span>
- </div>
- ${s.remark ? `<div style="font-size: 12px; color: #999; margin-top: 4px;">备注: ${s.remark}</div>` : ''}
- </div>
- <button style="color: #ef4444; padding: 8px;" onclick="deleteSchedule('${dateStr}', ${s.id})">
- <i class="fas fa-trash-alt"></i>
- </button>
- </div>
- `;
- }).join('');
- }
- document.getElementById('dateDetailModal').classList.add('active');
- }
- function closeDateDetailModal() {
- document.getElementById('dateDetailModal').classList.remove('active');
- }
- function addScheduleForDate() {
- closeDateDetailModal();
- setTimeout(() => {
- openAddScheduleModal();
- }, 300);
- }
- function deleteSchedule(dateStr, id) {
- if (schedulesData[dateStr]) {
- schedulesData[dateStr] = schedulesData[dateStr].filter(s => s.id !== id);
- if (schedulesData[dateStr].length === 0) {
- delete schedulesData[dateStr];
- }
- }
- openDateDetailModal(dateStr, selectedDate);
- renderScheduleCalendar();
- renderScheduleList();
- showToast('排班已删除');
- }
- // ========== 任务页面相关 ==========
- function filterTasks(status) {
- currentTaskFilter = status;
- // 更新筛选按钮样式
- document.querySelectorAll('.task-filter').forEach(btn => {
- btn.classList.remove('bg-blue-500', 'text-white');
- btn.classList.add('bg-gray-100', 'text-gray-600');
- });
- // 找到对应的按钮并高亮
- document.querySelectorAll('.task-filter').forEach(btn => {
- const btnText = btn.textContent.trim();
- if ((status === 'all' && btnText === '全部') || btnText === getFilterText(status)) {
- btn.classList.remove('bg-gray-100', 'text-gray-600');
- btn.classList.add('bg-blue-500', 'text-white');
- }
- });
- // 筛选任务卡片
- const cards = document.querySelectorAll('#taskListContainer .task-card');
- cards.forEach(card => {
- const cardStatus = card.dataset.status;
- if (status === 'all' || cardStatus === status) {
- card.style.display = 'block';
- } else {
- card.style.display = 'none';
- }
- });
- }
- function getFilterText(status) {
- const map = {
- 'all': '全部',
- 'pending': '待审核',
- 'confirmed': '待排班',
- 'approved': '已通过',
- 'rejected': '已驳回',
- 'processing': '进行中',
- 'completed': '已完成'
- };
- return map[status] || '全部';
- }
- function openTaskDetail(taskId) {
- const task = tasksData[taskId];
- if (!task) return;
- currentDetailTaskId = taskId;
- // 填充任务详情
- document.getElementById('taskDetailTitle').textContent = task.title;
- document.getElementById('taskDetailAddress').textContent = task.address;
- document.getElementById('taskDetailType').textContent = task.type;
- document.getElementById('taskDetailTime').textContent = task.time;
- document.getElementById('taskDetailApplicant').textContent = task.applicant;
- // 重置审核步骤
- document.getElementById('auditStep1').style.display = 'block';
- document.getElementById('auditStep2').style.display = 'none';
- document.getElementById('dispatchTeam').value = '';
- document.getElementById('dispatchVehicle').value = '';
- document.getElementById('auditRemark').value = '';
- // 重置confirmed状态的表单
- document.getElementById('confirmDispatchTeam').value = '';
- document.getElementById('confirmDispatchVehicle').value = '';
- document.getElementById('confirmAuditRemark').value = '';
- // 更新状态标签
- const statusEl = document.getElementById('taskDetailStatus');
- statusEl.className = 'tag';
- switch(task.status) {
- case 'pending':
- statusEl.classList.add('tag-orange');
- statusEl.textContent = '待审核';
- break;
- case 'confirmed':
- statusEl.classList.add('tag-yellow');
- statusEl.textContent = '待排班';
- break;
- case 'processing':
- statusEl.classList.add('tag-blue');
- statusEl.textContent = '进行中';
- break;
- case 'completed':
- statusEl.classList.add('tag-green');
- statusEl.textContent = '已完成';
- break;
- case 'rejected':
- statusEl.classList.add('tag-red');
- statusEl.textContent = '已驳回';
- break;
- }
- // 显示/隐藏审核区域
- const auditSection = document.getElementById('taskAuditSection');
- const confirmSection = document.getElementById('taskConfirmSection');
- const rejectSection = document.getElementById('taskRejectSection');
- const dispatchSection = document.getElementById('taskDispatchSection');
- auditSection.style.display = task.status === 'pending' ? 'block' : 'none';
- confirmSection.style.display = task.status === 'confirmed' ? 'block' : 'none';
- rejectSection.style.display = task.status === 'rejected' ? 'block' : 'none';
- dispatchSection.style.display = ['processing', 'completed'].includes(task.status) ? 'block' : 'none';
- if (task.status === 'rejected') {
- document.getElementById('rejectReason').textContent = task.rejectReason || '无';
- }
- if (task.team) {
- document.getElementById('dispatchedTeam').textContent = task.team;
- document.getElementById('dispatchedVehicle').textContent = task.vehicle;
- }
- goToDispatchPage('dispatch_taskDetailPage');
- }
- function approveTask(taskId) {
- tasksData[taskId].status = 'confirmed';
- showToast('任务已确认,请安排班组');
- filterTasks(currentTaskFilter);
- updatePendingBadge();
- }
- function rejectTask(taskId) {
- tasksData[taskId].status = 'rejected';
- tasksData[taskId].rejectReason = '审核不通过';
- showToast('任务已驳回');
- filterTasks(currentTaskFilter);
- updatePendingBadge();
- }
- // ========== 任务详情页两步审核 ==========
- // 第一步:确认任务
- function confirmTaskStep1() {
- if (!currentDetailTaskId) return;
- tasksData[currentDetailTaskId].status = 'confirmed';
- showToast('任务已确认,请安排班组');
- // 更新页面显示
- const statusEl = document.getElementById('taskDetailStatus');
- statusEl.className = 'tag tag-yellow';
- statusEl.textContent = '待排班';
- // 切换到第二步
- document.getElementById('auditStep1').style.display = 'none';
- document.getElementById('auditStep2').style.display = 'block';
- updatePendingBadge();
- }
- // 取消确认,返回第一步
- function cancelConfirmStep() {
- if (!currentDetailTaskId) return;
- tasksData[currentDetailTaskId].status = 'pending';
- // 更新页面显示
- const statusEl = document.getElementById('taskDetailStatus');
- statusEl.className = 'tag tag-orange';
- statusEl.textContent = '待审核';
- // 切换回第一步
- document.getElementById('auditStep1').style.display = 'block';
- document.getElementById('auditStep2').style.display = 'none';
- updatePendingBadge();
- }
- // 第二步:安排班组(从审核卡片第二步)
- function arrangeTeamStep2() {
- const team = document.getElementById('dispatchTeam').value;
- const vehicle = document.getElementById('dispatchVehicle').value;
- if (!team) {
- showToast('请选择班组');
- return;
- }
- if (!vehicle) {
- showToast('请选择车辆');
- return;
- }
- if (!currentDetailTaskId) return;
- tasksData[currentDetailTaskId].status = 'processing';
- tasksData[currentDetailTaskId].team = teamsData[team].name;
- tasksData[currentDetailTaskId].vehicle = vehiclesData[vehicle].name + '(' + vehiclesData[vehicle].plate + ')';
- showToast('任务已开始执行');
- updatePendingBadge();
- // 返回任务列表
- setTimeout(() => {
- goToDispatchPage('dispatch_taskPage');
- filterTasks(currentTaskFilter);
- }, 1000);
- }
- // confirmed状态:安排班组
- function arrangeTeamForConfirmed() {
- const team = document.getElementById('confirmDispatchTeam').value;
- const vehicle = document.getElementById('confirmDispatchVehicle').value;
- if (!team) {
- showToast('请选择班组');
- return;
- }
- if (!vehicle) {
- showToast('请选择车辆');
- return;
- }
- if (!currentDetailTaskId) return;
- tasksData[currentDetailTaskId].status = 'processing';
- tasksData[currentDetailTaskId].team = teamsData[team].name;
- tasksData[currentDetailTaskId].vehicle = vehiclesData[vehicle].name + '(' + vehiclesData[vehicle].plate + ')';
- showToast('任务已开始执行');
- updatePendingBadge();
- // 返回任务列表
- setTimeout(() => {
- goToDispatchPage('dispatch_taskPage');
- filterTasks(currentTaskFilter);
- }, 1000);
- }
- function rejectTaskFromDetail() {
- const reason = document.getElementById('auditRemark').value || '审核不通过';
- if (!currentDetailTaskId) return;
- tasksData[currentDetailTaskId].status = 'rejected';
- tasksData[currentDetailTaskId].rejectReason = reason;
- showToast('任务已驳回');
- updatePendingBadge();
- setTimeout(() => {
- goToDispatchPage('dispatch_taskPage');
- filterTasks(currentTaskFilter);
- }, 1000);
- }
- function updatePendingBadge() {
- let pendingCount = 0;
- for (let id in tasksData) {
- if (tasksData[id].status === 'pending') {
- pendingCount++;
- }
- }
- const badge = document.getElementById('pendingBadge');
- if (badge) {
- badge.textContent = pendingCount;
- badge.style.display = pendingCount > 0 ? 'flex' : 'none';
- }
- }
- // 初始化
- document.addEventListener('DOMContentLoaded', function() {
- updatePendingBadge();
- });
- // ========== 发布任务页相关 ==========
- // 项目数据结构(含子服务项)- 调度中心版
- const dispatchProjects = {
- '积丹白鹭': {
- name: '积丹白鹭',
- contacts: [{name: '张经理', phone: '138****1234'}],
- servicePoints: [
- {name: '1号化粪池', location: '南门地下车库入口旁', serviceType: '清掏'},
- {name: '2号隔油池', location: '商业区B1层餐饮后厨区', serviceType: '清掏'},
- {name: '3号油污管道', location: '住宅区东侧绿化带', serviceType: '疏通'}
- ]
- },
- '富源同坐': {
- name: '富源同坐',
- contacts: [{name: '李主管', phone: '139****5678'}],
- servicePoints: [
- {name: '主化粪池', location: '小区中心花园北侧', serviceType: '清掏'},
- {name: '东侧管道', location: '东门入口排水沟', serviceType: '疏通'},
- {name: '商业区主管', location: '商业街地下主管', serviceType: '排查'}
- ]
- },
- '俊发城': {
- name: '俊发城',
- contacts: [{name: '王物业', phone: '136****8765'}],
- servicePoints: [
- {name: '1号化粪池', location: '1号楼南侧绿化带', serviceType: '清掏'},
- {name: '2号化粪池', location: '3号楼西侧', serviceType: '清掏'},
- {name: '地下主管', location: '地下停车场主排污管', serviceType: '疏通'},
- {name: '5号楼管道', location: '5号楼单元入口', serviceType: '维修'}
- ]
- },
- '逸安新城A区': {
- name: '逸安新城A区',
- contacts: [{name: '赵经理', phone: '137****4321'}],
- servicePoints: [
- {name: 'A1号隔油池', location: '餐饮街后巷', serviceType: '清掏'},
- {name: 'A2号油污管', location: '美食广场B区', serviceType: '疏通'}
- ]
- },
- '逸安新城B区': {
- name: '逸安新城B区',
- contacts: [{name: '陈师傅', phone: '135****9876'}],
- servicePoints: [
- {name: 'B1号化粪池', location: '小区中庭花园', serviceType: '清掏'},
- {name: 'B2号化粪池', location: '4栋北侧', serviceType: '清掏'},
- {name: 'B区主管', location: '小区主排污口', serviceType: '疏通'},
- {name: 'B区支管', location: '儿童游乐区旁', serviceType: '排查'},
- {name: 'B区PVC管', location: '6栋单元主管', serviceType: '维修'}
- ]
- }
- };
- // 项目额外信息
- const dispatchProjectExtraInfo = {
- '积丹白鹭': { coopType: '包年', facilityType: '油污管', address: '昆明市五华区积丹白鹭小区' },
- '富源同坐': { coopType: '季度', facilityType: '化粪池', address: '昆明市西山区富源同坐商业广场' },
- '俊发城': { coopType: '月付', facilityType: 'PVC', address: '昆明市盘龙区俊发城住宅区' },
- '逸安新城A区': { coopType: '包年', facilityType: '油污管', address: '昆明市官渡区逸安新城A区' },
- '逸安新城B区': { coopType: '单次', facilityType: '市政', address: '昆明市官渡区逸安新城B区' }
- };
- let dispatchSelectedProject = null;
- let dispatchPublishContacts = []; // 项目联系人列表
- let dispatchPartyAContacts = []; // 甲方当事人列表
- // 项目选择变更事件
- function dispatchOnProjectSelectChange() {
- const projectName = document.getElementById('dispatchProjectSelect').value;
- const hint = document.getElementById('dispatchProjectSelectHint');
- const hintText = document.getElementById('dispatchProjectHintText');
- const autoInfo = document.getElementById('dispatchProjectAutoInfo');
- const newForm = document.getElementById('dispatchNewProjectForm');
- // 清空联系人列表
- dispatchPublishContacts = [];
- dispatchPartyAContacts = [];
- if (projectName === '') {
- // 未选择
- hint.style.display = 'flex';
- hintText.textContent = '请从项目库选择或新增项目';
- autoInfo.style.display = 'none';
- newForm.style.display = 'none';
- document.getElementById('dispatchProjectSelectHint').className = 'bg-blue-50 rounded-lg px-3 py-2 mb-4 flex items-center';
- document.querySelector('#dispatchProjectSelectHint i').className = 'fas fa-info-circle text-blue-500 mr-2 text-sm';
- dispatchSelectedProject = null;
- } else if (projectName === 'new') {
- // 新增项目
- hint.style.display = 'flex';
- hintText.textContent = '新增项目';
- autoInfo.style.display = 'none';
- newForm.style.display = 'block';
- document.getElementById('dispatchProjectSelectHint').className = 'bg-orange-50 rounded-lg px-3 py-2 mb-4 flex items-center';
- document.querySelector('#dispatchProjectSelectHint i').className = 'fas fa-edit text-orange-500 mr-2 text-sm';
- dispatchSelectedProject = null;
- // 清空新增表单
- document.getElementById('dispatchNewProjectName').value = '';
- document.getElementById('dispatchNewCoopType').value = '';
- document.getElementById('dispatchNewFacilityType').value = '';
- document.getElementById('dispatchNewProjectAddress').value = '';
- } else {
- // 选择了已有项目
- hint.style.display = 'flex';
- hintText.textContent = '已选择:' + projectName + '项目';
- autoInfo.style.display = 'block';
- newForm.style.display = 'none';
- document.getElementById('dispatchProjectSelectHint').className = 'bg-green-50 rounded-lg px-3 py-2 mb-4 flex items-center';
- document.querySelector('#dispatchProjectSelectHint i').className = 'fas fa-check-circle text-green-500 mr-2 text-sm';
- // 显示自动带出的信息
- document.getElementById('dispatchSelectedProjectName').textContent = projectName;
- const extraInfo = dispatchProjectExtraInfo[projectName] || { coopType: '-', facilityType: '-', address: '-' };
- document.getElementById('dispatchAutoCoopType').textContent = extraInfo.coopType;
- document.getElementById('dispatchAutoFacilityType').textContent = extraInfo.facilityType;
- document.getElementById('dispatchAutoProjectAddress').textContent = extraInfo.address;
- // 设置选中项目
- dispatchSelectedProject = dispatchProjects[projectName] || null;
- // 自动填充联系人(从项目联系人中获取)
- if (dispatchSelectedProject && dispatchSelectedProject.contacts && dispatchSelectedProject.contacts.length > 0) {
- dispatchPublishContacts = [...dispatchSelectedProject.contacts];
- dispatchPartyAContacts = [...dispatchSelectedProject.contacts];
- }
- // 自动填充故障位置
- if (dispatchSelectedProject && dispatchSelectedProject.servicePoints && dispatchSelectedProject.servicePoints.length > 0) {
- document.getElementById('dispatchFaultLocation').value = dispatchSelectedProject.servicePoints[0].location;
- document.getElementById('dispatchFaultLocation').classList.add('auto-filled');
- document.getElementById('dispatchFaultLocationLabel').style.display = 'block';
- }
- }
- // 渲染联系人列表
- dispatchRenderProjectContacts();
- dispatchRenderPartyAContacts();
- }
- // 重置项目选择
- function dispatchResetProjectSelection() {
- document.getElementById('dispatchProjectSelect').value = '';
- dispatchOnProjectSelectChange();
- // 清空故障位置
- document.getElementById('dispatchFaultLocation').value = '';
- document.getElementById('dispatchFaultLocation').classList.remove('auto-filled');
- document.getElementById('dispatchFaultLocationLabel').style.display = 'none';
- }
- // 渲染项目联系人列表
- function dispatchRenderProjectContacts() {
- const container = document.getElementById('dispatchContactListContainer');
- if (dispatchPublishContacts.length === 0) {
- container.innerHTML = '<div class="text-gray-400 text-sm text-center py-2">暂无联系人,请添加</div>';
- return;
- }
- let html = '';
- dispatchPublishContacts.forEach((contact, index) => {
- html += `
- <div class="contact-list-item" data-index="${index}">
- <div class="contact-info" style="flex-direction: column; align-items: flex-start;">
- <div class="flex gap-2 w-full">
- <input type="text" class="form-input" value="${contact.name}"
- placeholder="姓名" style="flex: 1; padding: 8px 10px; font-size: 13px;"
- onchange="dispatchUpdateProjectContact(${index}, 'name', this.value)">
- <input type="tel" class="form-input" value="${contact.phone}"
- placeholder="电话" style="flex: 1; padding: 8px 10px; font-size: 13px;"
- onchange="dispatchUpdateProjectContact(${index}, 'phone', this.value)">
- </div>
- </div>
- <div class="delete-btn" onclick="dispatchRemoveProjectContact(${index})">
- <i class="fas fa-times"></i>
- </div>
- </div>
- `;
- });
- container.innerHTML = html;
- }
- // 添加项目联系人
- function dispatchAddContactItem() {
- dispatchPublishContacts.push({name: '', phone: ''});
- dispatchRenderProjectContacts();
- }
- // 删除项目联系人
- function dispatchRemoveProjectContact(index) {
- dispatchPublishContacts.splice(index, 1);
- dispatchRenderProjectContacts();
- }
- // 更新项目联系人信息
- function dispatchUpdateProjectContact(index, field, value) {
- if (dispatchPublishContacts[index]) {
- dispatchPublishContacts[index][field] = value;
- }
- }
- // 渲染甲方当事人列表
- function dispatchRenderPartyAContacts() {
- const container = document.getElementById('dispatchPartyAContactList');
- if (dispatchPartyAContacts.length === 0) {
- container.innerHTML = '<div class="text-gray-400 text-sm text-center py-2">暂无甲方当事人,请添加</div>';
- return;
- }
- let html = '';
- dispatchPartyAContacts.forEach((contact, index) => {
- html += `
- <div class="contact-list-item" data-index="${index}">
- <div class="contact-info" style="flex-direction: column; align-items: flex-start;">
- <div class="flex gap-2 w-full">
- <input type="text" class="form-input" value="${contact.name}"
- placeholder="姓名" style="flex: 1; padding: 8px 10px; font-size: 13px;"
- onchange="dispatchUpdatePartyAContact(${index}, 'name', this.value)">
- <input type="tel" class="form-input" value="${contact.phone}"
- placeholder="电话" style="flex: 1; padding: 8px 10px; font-size: 13px;"
- onchange="dispatchUpdatePartyAContact(${index}, 'phone', this.value)">
- </div>
- </div>
- <div class="delete-btn" onclick="dispatchRemovePartyAContact(${index})">
- <i class="fas fa-times"></i>
- </div>
- </div>
- `;
- });
- container.innerHTML = html;
- }
- // 添加甲方当事人
- function dispatchAddPartyAContact() {
- dispatchPartyAContacts.push({name: '', phone: ''});
- dispatchRenderPartyAContacts();
- }
- // 删除甲方当事人
- function dispatchRemovePartyAContact(index) {
- dispatchPartyAContacts.splice(index, 1);
- dispatchRenderPartyAContacts();
- }
- // 更新甲方当事人信息
- function dispatchUpdatePartyAContact(index, field, value) {
- if (dispatchPartyAContacts[index]) {
- dispatchPartyAContacts[index][field] = value;
- }
- }
- // 提交任务
- function dispatchSubmitTask() {
- const projectSelect = document.getElementById('dispatchProjectSelect').value;
- const serviceDate = document.getElementById('dispatchServiceDate').value;
- const serviceTime = document.getElementById('dispatchServiceTime').value;
- const faultLocation = document.getElementById('dispatchFaultLocation').value;
- const faultDesc = document.getElementById('dispatchFaultDesc').value;
- const serviceType = document.getElementById('dispatchServiceType').value;
- const facilityType = document.getElementById('dispatchServiceFacilityType').value;
- const serviceMode = document.getElementById('dispatchServiceMode').value;
- const vehicleType = document.getElementById('dispatchVehicleType').value;
- const acceptType = document.getElementById('dispatchAcceptType').value;
- // 验证必填项 - 项目选择
- if (!projectSelect) {
- showToast('请选择项目');
- return;
- }
- // 如果选择新增项目,验证新增表单
- if (projectSelect === 'new') {
- const newProjectName = document.getElementById('dispatchNewProjectName').value;
- const newCoopType = document.getElementById('dispatchNewCoopType').value;
- const newFacilityType = document.getElementById('dispatchNewFacilityType').value;
- const newProjectAddress = document.getElementById('dispatchNewProjectAddress').value;
- if (!newProjectName) {
- showToast('请输入项目名称');
- return;
- }
- if (!newCoopType) {
- showToast('请选择合作类型');
- return;
- }
- if (!newFacilityType) {
- showToast('请选择设施类型');
- return;
- }
- if (!newProjectAddress) {
- showToast('请输入项目地址');
- return;
- }
- }
- // 验证必填项 - 服务信息
- if (!serviceDate || !serviceTime) {
- showToast('请选择服务时间');
- return;
- }
- if (!faultLocation) {
- showToast('请填写故障位置');
- return;
- }
- if (!faultDesc) {
- showToast('请填写故障描述');
- return;
- }
- if (!serviceType) {
- showToast('请选择施工类型');
- return;
- }
- if (!facilityType) {
- showToast('请选择施工设施');
- return;
- }
- if (!serviceMode) {
- showToast('请选择服务方式');
- return;
- }
- if (!vehicleType) {
- showToast('请选择建议出车');
- return;
- }
- if (!acceptType) {
- showToast('请选择验收方式');
- return;
- }
- // 检查甲方当事人
- const validPartyA = dispatchPartyAContacts.filter(c => c.name && c.phone);
- if (validPartyA.length === 0) {
- showToast('请至少添加一个甲方当事人');
- return;
- }
- showToast('发布成功');
- setTimeout(() => {
- dispatchResetPublishForm();
- goToDispatchPage('dispatch_taskPage');
- }, 1500);
- }
- // 重置发布表单
- function dispatchResetPublishForm() {
- document.getElementById('dispatchProjectSelect').value = '';
- dispatchSelectedProject = null;
- dispatchPublishContacts = [];
- dispatchPartyAContacts = [];
- // 重置提示区域
- document.getElementById('dispatchProjectSelectHint').style.display = 'flex';
- document.getElementById('dispatchProjectSelectHint').className = 'bg-blue-50 rounded-lg px-3 py-2 mb-4 flex items-center';
- document.querySelector('#dispatchProjectSelectHint i').className = 'fas fa-info-circle text-blue-500 mr-2 text-sm';
- document.getElementById('dispatchProjectHintText').textContent = '请从项目库选择或新增项目';
- document.getElementById('dispatchProjectAutoInfo').style.display = 'none';
- document.getElementById('dispatchNewProjectForm').style.display = 'none';
- // 清空新增表单
- document.getElementById('dispatchNewProjectName').value = '';
- document.getElementById('dispatchNewCoopType').value = '';
- document.getElementById('dispatchNewFacilityType').value = '';
- document.getElementById('dispatchNewProjectAddress').value = '';
- // 清空服务信息表单
- document.getElementById('dispatchServiceDate').value = '';
- document.getElementById('dispatchServiceTime').value = '';
- document.getElementById('dispatchFaultLocation').value = '';
- document.getElementById('dispatchFaultLocation').classList.remove('auto-filled');
- document.getElementById('dispatchFaultLocationLabel').style.display = 'none';
- document.getElementById('dispatchFaultDesc').value = '';
- document.getElementById('dispatchServiceType').value = '';
- document.getElementById('dispatchServiceFacilityType').value = '';
- document.getElementById('dispatchServiceMode').value = '';
- document.getElementById('dispatchVehicleType').value = '';
- document.getElementById('dispatchAcceptType').value = '';
- document.getElementById('dispatchRemark').value = '';
- // 清空联系人列表
- dispatchRenderProjectContacts();
- dispatchRenderPartyAContacts();
- }
- // ========== 人员列表页相关 ==========
- // 人员数据
- const personnelData = [
- { id: 1, name: '张三', team: '张师傅组', status: 'working', task: '逸安新城日常维护' },
- { id: 2, name: '李四', team: '张师傅组', status: 'working', task: '逸安新城日常维护' },
- { id: 3, name: '王五', team: '王师傅组', status: 'free', task: '' },
- { id: 4, name: '赵六', team: '王师傅组', status: 'working', task: '积丹白鹭小区疏通' },
- { id: 5, name: '刘七', team: '刘师傅组', status: 'free', task: '' },
- { id: 6, name: '陈八', team: '刘师傅组', status: 'working', task: '俊发城应急疏通' },
- { id: 7, name: '周九', team: '应急一组', status: 'free', task: '', emergency: true },
- { id: 8, name: '吴十', team: '应急二组', status: 'free', task: '', emergency: true },
- { id: 9, name: '郑一', team: '张师傅组', status: 'working', task: '富源同坐管道检修' },
- { id: 10, name: '钱二', team: '王师傅组', status: 'free', task: '' },
- { id: 11, name: '孙三', team: '刘师傅组', status: 'working', task: '新都国际管道维修' },
- { id: 12, name: '李四', team: '应急三组', status: 'free', task: '', emergency: true }
- ];
- let currentPersonnelFilter = 'all';
- function filterPersonnel(filter) {
- currentPersonnelFilter = filter;
- // 更新按钮样式
- document.querySelectorAll('#dispatch_personnelPage .bg-blue-500').forEach(btn => {
- btn.classList.remove('bg-blue-500', 'text-white');
- btn.classList.add('bg-gray-100');
- });
- event.target.classList.remove('bg-gray-100');
- event.target.classList.add('bg-blue-500', 'text-white');
- renderPersonnelList();
- }
- function renderPersonnelList() {
- const container = document.getElementById('personnelList');
- if (!container) return;
- let filteredData = personnelData;
- if (currentPersonnelFilter === 'working') {
- filteredData = personnelData.filter(p => p.status === 'working');
- } else if (currentPersonnelFilter === 'free') {
- filteredData = personnelData.filter(p => p.status === 'free');
- }
- if (filteredData.length === 0) {
- container.innerHTML = `
- <div class="empty-state">
- <i class="fas fa-users"></i>
- <p>暂无人员数据</p>
- </div>
- `;
- return;
- }
- container.innerHTML = filteredData.map(p => `
- <div class="card p-4 mb-3">
- <div class="flex items-center gap-3">
- <div class="w-12 h-12 bg-blue-100 rounded-full flex items-center justify-center">
- <i class="fas fa-user text-blue-500"></i>
- </div>
- <div class="flex-1">
- <div class="flex items-center gap-2">
- <span class="font-medium">${p.name}</span>
- ${p.emergency ? '<span class="tag tag-red text-xs">应急</span>' : ''}
- </div>
- <div class="text-sm text-gray-500">${p.team}</div>
- </div>
- <span class="tag ${p.status === 'working' ? 'tag-orange' : 'tag-green'}">
- ${p.status === 'working' ? '施工中' : '空闲'}
- </span>
- </div>
- ${p.task ? `
- <div class="mt-2 pt-2 border-t border-gray-100 text-sm text-gray-500">
- <i class="fas fa-tasks w-4 inline-block"></i> 当前任务:${p.task}
- </div>
- ` : ''}
- </div>
- `).join('');
- }
- // ========== 车辆列表页相关 ==========
- // 车辆数据
- const vehicleListData = [
- { id: 1, name: '疏通车01', plate: '贵A81356', type: '疏通车', status: 'working', task: '逸安新城日常维护' },
- { id: 2, name: '疏通车02', plate: '贵A82345', type: '疏通车', status: 'working', task: '积丹白鹭小区疏通' },
- { id: 3, name: '疏通车03', plate: '贵A83345', type: '疏通车', status: 'free', task: '' },
- { id: 4, name: '吸污车01', plate: '贵A83456', type: '吸污车', status: 'working', task: '俊发城应急疏通' },
- { id: 5, name: '吸污车02', plate: '贵A84456', type: '吸污车', status: 'free', task: '' },
- { id: 6, name: '吸污车03', plate: '贵A85456', type: '吸污车', status: 'working', task: '富源同坐管道检修' },
- { id: 7, name: '高压清洗车01', plate: '贵A86456', type: '高压清洗车', status: 'working', task: '新都国际管道维修' },
- { id: 8, name: '高压清洗车02', plate: '贵A87456', type: '高压清洗车', status: 'free', task: '' },
- { id: 9, name: '疏通车04', plate: '贵A88456', type: '疏通车', status: 'working', task: '云岩大厦排污' },
- { id: 10, name: '吸污车04', plate: '贵A89456', type: '吸污车', status: 'free', task: '' }
- ];
- let currentVehicleFilter = 'all';
- function filterVehicle(filter) {
- currentVehicleFilter = filter;
- // 更新按钮样式
- document.querySelectorAll('#dispatch_vehicleListPage .bg-blue-500').forEach(btn => {
- btn.classList.remove('bg-blue-500', 'text-white');
- btn.classList.add('bg-gray-100');
- });
- event.target.classList.remove('bg-gray-100');
- event.target.classList.add('bg-blue-500', 'text-white');
- renderVehicleList();
- }
- function renderVehicleList() {
- const container = document.getElementById('vehicleList');
- if (!container) return;
- let filteredData = vehicleListData;
- if (currentVehicleFilter === 'working') {
- filteredData = vehicleListData.filter(v => v.status === 'working');
- } else if (currentVehicleFilter === 'free') {
- filteredData = vehicleListData.filter(v => v.status === 'free');
- }
- if (filteredData.length === 0) {
- container.innerHTML = `
- <div class="empty-state">
- <i class="fas fa-truck"></i>
- <p>暂无车辆数据</p>
- </div>
- `;
- return;
- }
- container.innerHTML = filteredData.map(v => `
- <div class="card p-4 mb-3">
- <div class="flex items-center gap-3">
- <div class="w-12 h-12 ${v.type.includes('疏通车') ? 'bg-blue-100' : v.type.includes('吸污车') ? 'bg-purple-100' : 'bg-green-100'} rounded-lg flex items-center justify-center">
- <i class="fas fa-truck ${v.type.includes('疏通车') ? 'text-blue-500' : v.type.includes('吸污车') ? 'text-purple-500' : 'text-green-500'}"></i>
- </div>
- <div class="flex-1">
- <div class="font-medium">${v.name}</div>
- <div class="text-sm text-gray-500">${v.plate} · ${v.type}</div>
- </div>
- <span class="tag ${v.status === 'working' ? 'tag-orange' : 'tag-green'}">
- ${v.status === 'working' ? '施工中' : '空闲'}
- </span>
- </div>
- ${v.task ? `
- <div class="mt-2 pt-2 border-t border-gray-100 text-sm text-gray-500">
- <i class="fas fa-tasks w-4 inline-block"></i> 执行任务:${v.task}
- </div>
- ` : ''}
- </div>
- `).join('');
- }
- // ========== 应急班组页相关 ==========
- const emergencyTeamData = [
- { id: 1, name: '应急一组', leader: '周九', phone: '139****1234', members: ['周九', '李明'], vehicle: '疏通车01', status: 'ready' },
- { id: 2, name: '应急二组', leader: '吴十', phone: '138****5678', members: ['吴十', '王强'], vehicle: '吸污车01', status: 'ready' },
- { id: 3, name: '应急三组', leader: '李四', phone: '137****9012', members: ['李四', '陈东'], vehicle: '高压清洗车01', status: 'ready' }
- ];
- function renderEmergencyTeamList() {
- const container = document.getElementById('emergencyTeamList');
- if (!container) return;
- if (emergencyTeamData.length === 0) {
- container.innerHTML = `
- <div class="empty-state">
- <i class="fas fa-phone-volume"></i>
- <p>暂无应急班组</p>
- </div>
- `;
- return;
- }
- container.innerHTML = emergencyTeamData.map(team => `
- <div class="card p-4 mb-3">
- <div class="flex items-center justify-between mb-3">
- <div class="flex items-center gap-3">
- <div class="w-12 h-12 bg-red-100 rounded-lg flex items-center justify-center">
- <i class="fas fa-bolt text-red-500"></i>
- </div>
- <div>
- <div class="font-medium">${team.name}</div>
- <div class="text-sm text-gray-500">组长:${team.leader}</div>
- </div>
- </div>
- <span class="tag tag-green">待命就绪</span>
- </div>
- <div class="grid grid-cols-2 gap-2 text-sm">
- <div class="bg-gray-50 rounded-lg p-2">
- <div class="text-gray-400 text-xs">成员</div>
- <div class="text-gray-700">${team.members.join('、')}</div>
- </div>
- <div class="bg-gray-50 rounded-lg p-2">
- <div class="text-gray-400 text-xs">应急车辆</div>
- <div class="text-gray-700">${team.vehicle}</div>
- </div>
- </div>
- <div class="mt-2 pt-2 border-t border-gray-100 flex justify-between items-center">
- <span class="text-sm text-gray-500"><i class="fas fa-phone w-4 inline-block"></i> ${team.phone}</span>
- <button class="px-3 py-1 bg-green-500 text-white rounded-lg text-xs">
- <i class="fas fa-phone-alt mr-1"></i>联系组长
- </button>
- </div>
- </div>
- `).join('');
- }
- // ========== 调度端消息通知页相关 ==========
- // 调度端消息通知tab切换
- function filterDispatchNotifications(type, element) {
- document.querySelectorAll('.dispatch-notification-tab').forEach(btn => {
- btn.classList.remove('bg-blue-500', 'text-white');
- btn.classList.add('bg-gray-100', 'text-gray-600');
- });
- element.classList.remove('bg-gray-100', 'text-gray-600');
- element.classList.add('bg-blue-500', 'text-white');
- const items = document.querySelectorAll('#dispatchNotificationList .notification-item');
- items.forEach(item => {
- if (type === 'all' || item.dataset.type === type) {
- item.style.display = 'block';
- } else {
- item.style.display = 'none';
- }
- });
- }
- // ========== 消息通知页相关 ==========
- const notificationData = [
- { id: 1, type: 'task', title: '新任务分配', content: '积丹白鹭小区疏通任务已分配给您,请及时处理', time: '今天 10:30', read: false },
- { id: 2, type: 'audit', title: '审核通过', content: '俊发城应急疏通任务已审核通过,已安排张师傅组执行', time: '今天 09:45', read: false },
- { id: 3, type: 'system', title: '系统通知', content: '明日(4月22日)天气预报有雨,请注意施工安全', time: '今天 08:00', read: true },
- { id: 4, type: 'task', title: '任务变更', content: '新都国际管道维修任务时间调整为明天上午10:00', time: '昨天 17:30', read: true },
- { id: 5, type: 'audit', title: '任务驳回', content: '云岩大厦排污任务因设备临时故障被驳回', time: '昨天 15:20', read: true },
- { id: 6, type: 'system', title: '系统更新', content: '清道夫系统V1.0.1版本已发布,新增可视化大屏功能', time: '昨天 10:00', read: true }
- ];
- let currentNotificationFilter = 'all';
- function filterNotification(filter) {
- currentNotificationFilter = filter;
- // 更新按钮样式
- document.querySelectorAll('#notificationPage button').forEach(btn => {
- if (btn.textContent.includes('全部') || btn.textContent.includes('任务') || btn.textContent.includes('审核') || btn.textContent.includes('系统')) {
- if (btn.classList.contains('bg-blue-500')) {
- btn.classList.remove('bg-blue-500', 'text-white');
- btn.classList.add('bg-gray-100', 'text-gray-600');
- }
- }
- });
- event.target.classList.remove('bg-gray-100', 'text-gray-600');
- event.target.classList.add('bg-blue-500', 'text-white');
- renderNotificationList();
- }
- function renderNotificationList() {
- const container = document.getElementById('notificationList');
- if (!container) return;
- let filteredData = notificationData;
- if (currentNotificationFilter === 'task') {
- filteredData = notificationData.filter(n => n.type === 'task');
- } else if (currentNotificationFilter === 'audit') {
- filteredData = notificationData.filter(n => n.type === 'audit');
- } else if (currentNotificationFilter === 'system') {
- filteredData = notificationData.filter(n => n.type === 'system');
- }
- if (filteredData.length === 0) {
- container.innerHTML = `
- <div class="empty-state">
- <i class="fas fa-bell"></i>
- <p>暂无通知消息</p>
- </div>
- `;
- return;
- }
- container.innerHTML = filteredData.map(n => {
- let iconClass = 'fa-bell text-gray-500';
- let bgClass = 'bg-gray-100';
- if (n.type === 'task') {
- iconClass = 'fa-tasks text-blue-500';
- bgClass = 'bg-blue-100';
- } else if (n.type === 'audit') {
- iconClass = 'fa-check-circle text-green-500';
- bgClass = 'bg-green-100';
- } else if (n.type === 'system') {
- iconClass = 'fa-cog text-purple-500';
- bgClass = 'bg-purple-100';
- }
- return `
- <div class="notification-item card p-4 mb-3 ${n.read ? 'opacity-60' : ''}" data-type="${n.type}">
- <div class="flex items-start gap-3">
- <div class="w-10 h-10 ${bgClass} rounded-lg flex items-center justify-center flex-shrink-0">
- <i class="fas ${iconClass}"></i>
- </div>
- <div class="flex-1">
- <div class="flex items-center justify-between">
- <span class="font-medium text-sm">${n.title}</span>
- ${!n.read ? '<span class="w-2 h-2 bg-blue-500 rounded-full"></span>' : ''}
- </div>
- <p class="text-sm text-gray-500 mt-1">${n.content}</p>
- <span class="text-xs text-gray-400 mt-2 inline-block">${n.time}</span>
- </div>
- </div>
- </div>
- `;
- }).join('');
- }
- // 渲染调度端消息通知列表
- function renderDispatchNotificationList() {
- const container = document.getElementById('dispatchNotificationList');
- if (!container) return;
- if (notificationData.length === 0) {
- container.innerHTML = `
- <div class="empty-state">
- <i class="fas fa-bell"></i>
- <p>暂无通知消息</p>
- </div>
- `;
- return;
- }
- container.innerHTML = notificationData.map(n => {
- let iconClass = 'fa-bell text-gray-500';
- let bgClass = 'bg-gray-100';
- if (n.type === 'task') {
- iconClass = 'fa-tasks text-blue-500';
- bgClass = 'bg-blue-100';
- } else if (n.type === 'audit') {
- iconClass = 'fa-check-circle text-green-500';
- bgClass = 'bg-green-100';
- } else if (n.type === 'system') {
- iconClass = 'fa-cog text-purple-500';
- bgClass = 'bg-purple-100';
- }
- return `
- <div class="notification-item card p-4 mb-3 ${n.read ? 'opacity-60' : ''}" data-type="${n.type}">
- <div class="flex items-start gap-3">
- <div class="w-10 h-10 ${bgClass} rounded-lg flex items-center justify-center flex-shrink-0">
- <i class="fas ${iconClass}"></i>
- </div>
- <div class="flex-1">
- <div class="flex items-center justify-between">
- <span class="font-medium text-sm">${n.title}</span>
- ${!n.read ? '<span class="w-2 h-2 bg-blue-500 rounded-full"></span>' : ''}
- </div>
- <p class="text-sm text-gray-500 mt-1">${n.content}</p>
- <span class="text-xs text-gray-400 mt-2 inline-block">${n.time}</span>
- </div>
- </div>
- </div>
- `;
- }).join('');
- }
- function markAllRead() {
- notificationData.forEach(n => n.read = true);
- renderNotificationList();
- showToast('已全部标记为已读');
- }
- // ========== 可视化大屏页相关 ==========
- function initVisualizationPage() {
- const now = new Date();
- const dateStr = `${now.getFullYear()}年${now.getMonth() + 1}月${now.getDate()}日`;
- document.getElementById('vizDate').textContent = dateStr;
- }
- // ========== 任务列表筛选跳转 ==========
- function goToTaskListFiltered(filter) {
- goToDispatchPage('dispatch_taskPage');
- // 等待页面切换后执行筛选
- setTimeout(() => {
- if (filter === 'today') {
- filterTasks('all');
- } else if (filter === 'confirmed') {
- filterTasks('confirmed');
- } else if (filter === 'processing') {
- filterTasks('processing');
- }
- }, 100);
- }
- // 页面切换时初始化页面数据
- const originalGoToPage = goToPage;
- goToPage = function(pageId) {
- originalGoToPage(pageId);
- // 初始化各页面数据
- if (pageId === 'dispatch_personnelPage') {
- renderPersonnelList();
- } else if (pageId === 'dispatch_vehicleListPage') {
- renderVehicleList();
- } else if (pageId === 'dispatch_emergencyTeamPage') {
- renderEmergencyTeamList();
- } else if (pageId === 'dispatch_notificationPage') {
- renderNotificationList();
- } else if (pageId === 'dispatch_visualizationPage') {
- initVisualizationPage();
- }
- };
- // ==================== 合并登录逻辑 ====================
- // 重写登录按钮事件
- document.getElementById('loginBtn').onclick = function() {
- const account = document.querySelector('input[placeholder="请输入账号"]').value;
- const password = document.querySelector('input[placeholder="请输入密码"]').value;
- if (!account || !password) {
- alert('请输入账号和密码');
- return;
- }
- // 获取当前选中的角色
- let selectedRole = 'sales';
- document.querySelectorAll('.role-tab').forEach(tab => {
- if (tab.classList.contains('active')) {
- selectedRole = tab.dataset.role;
- }
- });
- // 隐藏登录容器
- document.getElementById('loginContainer').style.display = 'none';
- // 根据角色跳转
- if (selectedRole === 'sales') {
- // 显示销售端,隐藏调度端
- document.getElementById('salesApp').style.display = 'block';
- document.getElementById('dispatchApp').style.display = 'none';
- goToPage('salesPage');
- } else if (selectedRole === 'dispatch') {
- // 显示调度端,隐藏销售端
- document.getElementById('salesApp').style.display = 'none';
- document.getElementById('dispatchApp').style.display = 'block';
- goToDispatchPage('dispatch_homePage');
- } else if (selectedRole === 'worker') {
- // 显示施工端,隐藏销售端和调度端
- document.getElementById('salesApp').style.display = 'none';
- document.getElementById('dispatchApp').style.display = 'none';
- document.getElementById('constructionApp').style.display = 'block';
- goToConstructionPage('construction_homePage');
- }
- };
- // 角色切换事件
- document.querySelectorAll('.role-tab').forEach(tab => {
- tab.onclick = function() {
- document.querySelectorAll('.role-tab').forEach(t => {
- t.classList.remove('active');
- t.classList.add('text-white/80');
- });
- this.classList.add('active');
- this.classList.remove('text-white/80');
- };
- });
- // ==================== 统一退出登录 ====================
- function backToLogin() {
- // 隐藏所有容器
- document.getElementById('salesApp').style.display = 'none';
- document.getElementById('dispatchApp').style.display = 'none';
- document.getElementById('constructionApp').style.display = 'none';
- // 显示登录容器
- document.getElementById('loginContainer').style.display = 'block';
- // 重置登录页状态
- document.getElementById('loginPage').classList.add('active');
- }
- // ==================== 施工端函数 ====================
- // 施工端页面跳转
- function goToConstructionPage(pageId) {
- // 隐藏所有施工端页面
- document.querySelectorAll('#constructionApp .page').forEach(page => {
- page.classList.remove('active');
- });
- // 显示目标页面
- const targetPage = document.getElementById(pageId);
- if (targetPage) {
- targetPage.classList.add('active');
- }
- // 更新底部导航状态
- updateConstructionNav(pageId);
- }
- // 更新施工端底部导航状态
- function updateConstructionNav(pageId) {
- const navItems = document.querySelectorAll('#constructionApp .nav-item');
- navItems.forEach(item => {
- item.classList.remove('active');
- const icon = item.querySelector('.nav-icon');
- const text = item.querySelector('span');
- if (pageId === 'construction_homePage' && item.onclick && item.onclick.toString().includes('construction_homePage')) {
- item.classList.add('active');
- } else if (pageId === 'construction_taskPage' && item.onclick && item.onclick.toString().includes('construction_taskPage')) {
- item.classList.add('active');
- } else if (pageId === 'construction_myPage' && item.onclick && item.onclick.toString().includes('construction_myPage')) {
- item.classList.add('active');
- }
- });
- }
- // 筛选施工端任务列表
- function filterConstructionTasks(status, element) {
- // 更新tab激活状态
- document.querySelectorAll('#construction_taskPage .filter-tab').forEach(tab => {
- tab.classList.remove('active');
- });
- element.classList.add('active');
- // 筛选任务卡片
- const cards = document.querySelectorAll('#constructionTaskList .task-card');
- cards.forEach(card => {
- if (status === 'all' || card.dataset.status === status) {
- card.style.display = 'block';
- } else {
- card.style.display = 'none';
- }
- });
- // 更新任务数量
- const visibleCards = document.querySelectorAll('#constructionTaskList .task-card:not([style*="display: none"])');
- document.getElementById('constructionTaskCount').textContent = visibleCards.length;
- }
- // 筛选施工端消息通知
- function filterConstructionNotifications(type, element) {
- // 更新tab激活状态
- element.parentElement.querySelectorAll('.filter-tab').forEach(tab => {
- tab.classList.remove('active');
- });
- element.classList.add('active');
- // 筛选消息项
- const items = document.querySelectorAll('.construction-notification-item');
- items.forEach(item => {
- if (type === 'all' || item.dataset.type === type) {
- item.style.display = 'block';
- } else {
- item.style.display = 'none';
- }
- });
- }
- // ========== 施工端步骤操作函数 V13 ==========
- // 全局当前状态
- let currentTaskStatus = '待确认';
- // 收起/展开任务信息区
- function toggleTaskInfo() {
- const title = document.getElementById('taskInfoTitle');
- const status = document.getElementById('taskInfoStatus');
- const content = document.getElementById('taskInfoContent');
- const toggle = document.getElementById('taskInfoToggle');
- const titleEl = document.querySelector('#taskInfoSection .detail-section-title');
- if (content.classList.contains('hidden')) {
- content.classList.remove('hidden');
- titleEl.classList.remove('collapsed');
- } else {
- content.classList.add('hidden');
- titleEl.classList.add('collapsed');
- }
- }
- // 设置详情页状态
- function setDetailStatus(status) {
- currentTaskStatus = status;
- // 隐藏所有操作区
- const actionContents = document.querySelectorAll('.action-content');
- actionContents.forEach(el => el.classList.add('hidden'));
- // 定义各状态对应的流程步骤
- const statusSteps = {
- '待确认': {
- flowLineWidth: '0%',
- steps: {
- 'step-confirm': 'active',
- 'step-depart': 'pending',
- 'step-arrive': 'pending',
- 'step-work': 'pending',
- 'step-work2': 'pending',
- 'step-complete': 'pending',
- 'step-clean': 'pending',
- 'step-inspect': 'pending'
- },
- actionContent: 'action-pending-confirm'
- },
- '待出车': {
- flowLineWidth: '11.1%',
- steps: {
- 'step-confirm': 'completed',
- 'step-depart': 'active',
- 'step-arrive': 'pending',
- 'step-work': 'pending',
- 'step-work2': 'pending',
- 'step-complete': 'pending',
- 'step-clean': 'pending',
- 'step-inspect': 'pending'
- },
- actionContent: 'action-pending-depart'
- },
- '已出车': {
- flowLineWidth: '22.2%',
- steps: {
- 'step-confirm': 'completed',
- 'step-depart': 'completed',
- 'step-arrive': 'active',
- 'step-work': 'pending',
- 'step-work2': 'pending',
- 'step-complete': 'pending',
- 'step-clean': 'pending',
- 'step-inspect': 'pending'
- },
- actionContent: 'action-departed'
- },
- '已到达': {
- flowLineWidth: '33.3%',
- steps: {
- 'step-confirm': 'completed',
- 'step-depart': 'completed',
- 'step-arrive': 'completed',
- 'step-work': 'active',
- 'step-work2': 'pending',
- 'step-complete': 'pending',
- 'step-clean': 'pending',
- 'step-inspect': 'pending'
- },
- actionContent: 'action-arrived'
- },
- '勘验完成': {
- flowLineWidth: '44.4%',
- steps: {
- 'step-confirm': 'completed',
- 'step-depart': 'completed',
- 'step-arrive': 'completed',
- 'step-work': 'completed',
- 'step-work2': 'active',
- 'step-complete': 'pending',
- 'step-clean': 'pending',
- 'step-inspect': 'pending'
- },
- actionContent: 'action-inspection-done'
- },
- '施工中': {
- flowLineWidth: '55.5%',
- steps: {
- 'step-confirm': 'completed',
- 'step-depart': 'completed',
- 'step-arrive': 'completed',
- 'step-work': 'completed',
- 'step-work2': 'completed',
- 'step-complete': 'active',
- 'step-clean': 'pending',
- 'step-inspect': 'pending'
- },
- actionContent: 'action-constructing'
- },
- '施工完成': {
- flowLineWidth: '66.6%',
- steps: {
- 'step-confirm': 'completed',
- 'step-depart': 'completed',
- 'step-arrive': 'completed',
- 'step-work': 'completed',
- 'step-work2': 'completed',
- 'step-complete': 'completed',
- 'step-clean': 'active',
- 'step-inspect': 'pending'
- },
- actionContent: 'action-work-complete'
- },
- '清洗完成': {
- flowLineWidth: '77.7%',
- steps: {
- 'step-confirm': 'completed',
- 'step-depart': 'completed',
- 'step-arrive': 'completed',
- 'step-work': 'completed',
- 'step-work2': 'completed',
- 'step-complete': 'completed',
- 'step-clean': 'completed',
- 'step-inspect': 'active'
- },
- actionContent: 'action-cleaning-done'
- },
- '已验收': {
- flowLineWidth: '100%',
- steps: {
- 'step-confirm': 'completed',
- 'step-depart': 'completed',
- 'step-arrive': 'completed',
- 'step-work': 'completed',
- 'step-work2': 'completed',
- 'step-complete': 'completed',
- 'step-clean': 'completed',
- 'step-inspect': 'completed'
- },
- actionContent: 'action-completed'
- }
- };
- const config = statusSteps[status] || statusSteps['待确认'];
- // 更新流程进度条
- document.getElementById('detailFlowLineFill').style.width = config.flowLineWidth;
- // 更新每个步骤的状态
- Object.keys(config.steps).forEach(stepId => {
- const stepEl = document.getElementById(stepId);
- const dotEl = document.getElementById(stepId + '-dot');
- const stepStatus = config.steps[stepId];
- if (!stepEl || !dotEl) return;
- stepEl.classList.remove('completed', 'active');
- dotEl.classList.remove('completed', 'active', 'pending');
- if (stepStatus === 'completed') {
- stepEl.classList.add('completed');
- dotEl.classList.add('completed');
- dotEl.innerHTML = '<i class="fas fa-check"></i>';
- } else if (stepStatus === 'active') {
- stepEl.classList.add('active');
- dotEl.classList.add('active');
- dotEl.innerHTML = '<i class="fas fa-spinner"></i>';
- } else {
- dotEl.classList.add('pending');
- dotEl.innerHTML = '<i class="fas fa-times"></i>';
- }
- });
- // 更新任务状态标签
- const statusTag = document.getElementById('taskInfoStatus');
- if (statusTag) {
- statusTag.textContent = status;
- if (status === '已验收') {
- statusTag.className = 'status-tag bg-green-100 text-green-600';
- } else if (status === '待确认' || status === '待出车' || status === '已出车') {
- statusTag.className = 'status-tag bg-orange-100 text-orange-600';
- } else {
- statusTag.className = 'status-tag status-scheduling';
- }
- }
- // 显示对应的操作区
- const actionEl = document.getElementById(config.actionContent);
- if (actionEl) {
- actionEl.classList.remove('hidden');
- }
- }
- // 确认任务
- function confirmTask() {
- showToast('任务已确认,准备出发');
- setDetailStatus('待出车');
- addTaskLog('确认任务');
- }
- // 出发
- function startDeparture() {
- showToast('已出发,开始前往现场');
- setDetailStatus('已出车');
- addTaskLog('已出发');
- }
- // 上传警示牌照片
- function uploadWarningPhoto() {
- showToast('打开相机拍摄警示牌照片');
- setTimeout(() => {
- document.getElementById('warningPhotoPreview').classList.remove('hidden');
- }, 1500);
- }
- // 确认到达
- function confirmArrive() {
- showToast('已到达现场,开始勘验');
- setDetailStatus('已到达');
- addTaskLog('已到达现场');
- }
- // 上传勘验照片/视频
- function uploadInspectionMedia() {
- showToast('打开相机拍摄勘验照片/视频');
- setTimeout(() => {
- document.getElementById('inspectionPreview').classList.remove('hidden');
- }, 1500);
- }
- // 确认勘验完成
- function confirmInspection() {
- const faultLocation = document.getElementById('faultLocationInput').value;
- if (!faultLocation.trim()) {
- showToast('请输入故障点位置描述');
- return;
- }
- showToast('勘验完成,开始施工');
- setDetailStatus('勘验完成');
- addTaskLog('勘验完成,故障点:' + faultLocation);
- }
- // 上传施工照片/视频
- function uploadConstructionMedia() {
- showToast('打开相机拍摄施工照片/视频');
- setTimeout(() => {
- document.getElementById('constructionPreview').classList.remove('hidden');
- }, 1500);
- }
- // 确认开始施工
- function confirmConstructionStart() {
- showToast('开始施工');
- setDetailStatus('施工中');
- addTaskLog('开始施工');
- }
- // 上传完成照片/视频
- function uploadCompleteMedia() {
- showToast('打开相机拍摄完成照片/视频');
- setTimeout(() => {
- document.getElementById('completePreview').classList.remove('hidden');
- }, 1500);
- }
- // 确认施工完成
- function confirmConstructionComplete() {
- showToast('施工完成,开始清洗');
- setDetailStatus('施工完成');
- addTaskLog('施工完成');
- }
- // 上传清洗照片
- function uploadCleaningMedia() {
- showToast('打开相机拍摄清洗照片');
- setTimeout(() => {
- document.getElementById('cleaningPreview').classList.remove('hidden');
- }, 1500);
- }
- // 确认清洗完成
- function confirmCleaningComplete() {
- showToast('清洗完成,等待验收');
- setDetailStatus('清洗完成');
- addTaskLog('清洗完成');
- }
- // 上传验收签字照片
- function uploadInspectionSign() {
- showToast('打开相机拍摄签字照片');
- setTimeout(() => {
- document.getElementById('signPreview').classList.remove('hidden');
- }, 1500);
- }
- // 确认最终验收
- function confirmFinalInspection() {
- showToast('验收完成,任务全部结束');
- setDetailStatus('已验收');
- addTaskLog('客户验收完成');
- // 返回任务列表
- setTimeout(() => {
- goToConstructionPage('construction_taskPage');
- }, 2000);
- }
- // 添加任务日志
- function addTaskLog(action) {
- const logList = document.getElementById('construction_taskLogList');
- if (!logList) return;
- const now = new Date();
- const time = (now.getMonth() + 1).toString().padStart(2, '0') + '-' +
- now.getDate().toString().padStart(2, '0') + ' ' +
- now.getHours().toString().padStart(2, '0') + ':' +
- now.getMinutes().toString().padStart(2, '0');
- const logItem = document.createElement('div');
- logItem.className = 'flex items-start text-sm';
- logItem.innerHTML = '<span class="text-gray-400 w-20 flex-shrink-0">' + time + '</span><div class="flex-1"><span class="text-green-600">工人 张师傅</span><span class="text-gray-500">' + action + '</span></div>';
- logList.insertBefore(logItem, logList.firstChild);
- }
- // 打开反馈弹窗(保留V10设计)
- function openFeedbackModal() {
- document.getElementById('constructionFeedbackModal').classList.remove('hidden');
- }
- // 关闭反馈弹窗
- function closeFeedbackModal() {
- document.getElementById('constructionFeedbackModal').classList.add('hidden');
- document.getElementById('constructionFeedbackText').value = '';
- }
- // 提交反馈
- function submitFeedback() {
- const text = document.getElementById('constructionFeedbackText').value;
- if (!text.trim()) {
- showToast('请输入反馈内容');
- return;
- }
- closeFeedbackModal();
- showToast('反馈已提交');
- addTaskLog('反馈问题:' + text);
- }
- // 打开拒绝弹窗
- function openRejectModal() {
- document.getElementById('constructionRejectModal').classList.remove('hidden');
- }
- // 关闭拒绝弹窗
- function closeRejectModal() {
- document.getElementById('constructionRejectModal').classList.add('hidden');
- document.getElementById('constructionRejectText').value = '';
- }
- // 提交拒绝
- function submitReject() {
- const text = document.getElementById('constructionRejectText').value;
- if (!text.trim()) {
- showToast('请输入拒绝原因');
- return;
- }
- closeRejectModal();
- showToast('任务已拒绝');
- addTaskLog('拒绝任务:' + text);
- setTimeout(() => {
- goToConstructionPage('construction_taskPage');
- }, 1500);
- }
- // 兼容旧函数名
- function openConstructionFeedbackModal() { openFeedbackModal(); }
- function closeConstructionFeedbackModal() { closeFeedbackModal(); }
- function submitConstructionFeedback() { submitFeedback(); }
- function openConstructionRejectModal() { openRejectModal(); }
- function closeConstructionRejectModal() { closeRejectModal(); }
- function submitConstructionReject() { submitReject(); }</script>
- </body>
- </html>
|