| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963 |
- <template>
- <div class="home-container">
- <el-row :gutter="6" class="home-top-row">
- <el-col :span="24" class="box-col">
- <el-card class="box-card">
- <div slot="header" class="clearfix">
- <span>常用功能</span>
- <span style="float: right; padding: 3px 0">
- <i
- class="el-icon-edit"
- @click="handleEdit"
- style="cursor: pointer; margin-right: 16px; font-size: 18px"
- ></i>
- <i
- class="el-icon-setting"
- @click="handleAdd"
- style="cursor: pointer; font-size: 18px"
- ></i>
- </span>
- </div>
- <div class="card-content common-function-card">
- <vuedraggable v-model="commonFunctions" class="common-function">
- <div
- v-for="(item, index) in commonFunctions"
- :key="item.id"
- class="common-function-item"
- @click="handleDel(item, index)"
- :title="isDelFlag ? '点击删除' : ''"
- :class="isDelFlag ? 'div-del' : ''"
- >
- <!-- <div class="common-function-item-content"> -->
- <div class="common-function-item-icon">
- <!-- <i :class="item.icon || 'el-icon-s-opportunity'"></i> -->
- <img :src="getIconPath(item.pic)" alt="" />
- </div>
- <div class="common-function-item-name">{{ item.name }}</div>
- <!-- </div> -->
- </div>
- </vuedraggable>
- </div>
- </el-card>
- </el-col>
- </el-row>
- <el-row :gutter="6" class="mt-20 home-overview-row">
- <el-col :span="18" class="box-col">
- <el-card class="box-card">
- <div slot="header" class="clearfix">
- <span>数据概览</span>
- </div>
- <div class="card-content">
- <el-row :gutter="20" class="overview-container">
- <el-col :span="8">
- <div class="overview">
- <div class="overview-top">
- <div class="overview-top-img"
- ><img src="~@/assets/home/ceshi1.png" alt=""
- /></div>
- <div class="overview-top-content">
- <div class="overview-top-content-name">我的项目</div>
- <div class="overview-top-content-count">{{
- myProjectList['总数量'] || 0
- }}</div>
- </div>
- </div>
- <el-divider></el-divider>
- <div class="overview-bottom">
- <div
- v-for="(value, key) in myProjectList"
- :key="key"
- v-if="key !== '总数量' && value != 0"
- class="overview-bottom-item"
- @click="handleToPro(key)"
- >
- <div class="overview-bottom-item-name">{{ key }}</div>
- <div class="overview-bottom-item-count">{{
- value || 0
- }}</div>
- </div>
- </div>
- </div>
- </el-col>
- <el-col :span="8">
- <div class="overview">
- <div class="overview-top">
- <div class="overview-top-img"
- ><img src="~@/assets/home/ceshi.jpg" alt=""
- /></div>
- <div class="overview-top-content">
- <div class="overview-top-content-name">我的工单</div>
- <div class="overview-top-content-count">{{
- myWorkOrderList['总数量'] || 0
- }}</div>
- </div>
- </div>
- <el-divider></el-divider>
- <div class="overview-bottom">
- <div
- v-for="(value, key) in myWorkOrderList"
- :key="key"
- v-if="key !== '总数量' && value != 0"
- class="overview-bottom-item"
- @click="handleTo(key)"
- >
- <div class="overview-bottom-item-name">{{ key }}</div>
- <div class="overview-bottom-item-count">{{
- value || 0
- }}</div>
- </div>
- </div>
- </div>
- </el-col>
- <el-col :span="8">
- <div class="overview">
- <div class="overview-top">
- <div class="overview-top-img"
- ><img
- style="border-radius: 10px"
- src="~@/assets/home/ceshi2.jpg"
- alt=""
- /></div>
- <div class="overview-top-content">
- <div class="overview-top-content-name">我的任务</div>
- <div class="overview-top-content-count">{{
- myTaskList['总数量'] || 0
- }}</div>
- </div>
- </div>
- <el-divider></el-divider>
- <div class="overview-bottom">
- <div
- v-for="(value, key) in myTaskList"
- :key="key"
- v-if="key !== '总数量' && value != 0"
- class="overview-bottom-item"
- @click="handleTo(key)"
- >
- <div class="overview-bottom-item-name">{{ key }}</div>
- <div class="overview-bottom-item-count">{{
- value || 0
- }}</div>
- </div>
- </div>
- </div>
- </el-col>
- </el-row>
- </div>
- </el-card>
- </el-col>
- <el-col :span="6" class="box-col">
- <el-card class="box-card">
- <div slot="header" class="clearfix">
- <span>统一门户</span>
- </div>
- <div class="card-content portal-content">
- <div class="portal">
- <el-row :gutter="12">
- <el-col
- :span="8"
- v-for="item in portals"
- :key="item.name"
- class="portal-item"
- >
- <div class="portal-item-content" @click="openUrl(item)">
- <div class="portal-item-img"
- ><img :src="item.img" alt=""
- /></div>
- <div class="portal-item-name">{{ item.name }}</div>
- </div>
- </el-col>
- </el-row>
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
- <el-row :gutter="6" class="mt-20 home-bottom-row">
- <el-col :span="12" class="box-col notification-col">
- <el-card class="box-card notification-card">
- <div class="card-content">
- <el-tabs v-model="activeTab" @tab-click="handleTabClick">
- <el-tab-pane label="通知公告" name="notice"></el-tab-pane>
- <!-- <el-tab-pane label="行业动态" name="industry"></el-tab-pane> -->
- <el-tab-pane label="系统通知" name="system"></el-tab-pane>
- </el-tabs>
- <div v-if="notifications.length > 0" class="notification-list">
- <div
- v-for="(item, index) in notifications"
- :key="index"
- class="notification-item"
- @click="handleNotificationsClick(item)"
- >
- <div class="notification-dot"></div>
- <div class="notification-content">
- <div class="notification-header">
- <div class="notification-title">{{ item.title }}</div>
- <div v-if="activeTab == 'notice'" class="notification-text">
- {{ item.content }}
- <!-- <div v-if="item.images && item.images.length > 0" class="notification-images">
- <div v-for="(img, imgIndex) in item.images" :key="imgIndex" class="image-url">{{ img }}</div>
- </div> -->
- </div>
- <div v-else class="notification-text">{{
- item.content
- }}</div>
- </div>
- <div class="notification-info"
- >{{ item.createUser }}
- <span style="margin-left: 20px">{{
- item.department
- }}</span></div
- >
- </div>
- <div class="notification-date">{{ item.createTime }}</div>
- </div>
- <div
- v-if="hasMore"
- class="notification-more"
- @click="loadMoreNotifications"
- >
- 更多......
- </div>
- </div>
- <div v-else class="no-notification">
- <el-empty description="暂无数据"></el-empty>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="12" class="box-col calendar-col">
- <el-card class="box-card calendar-card">
- <div slot="header" class="clearfix">
- <span>工作日历</span>
- </div>
- <div class="card-content calendar-content">
- <div class="work-calendar">
- <div class="calendar-view-title">
- <span>{{ calendarViewTitle }}</span>
- <div class="calendar-title-tools">
- <el-radio-group
- v-model="selectedCalendarType"
- size="mini"
- class="calendar-type-switch"
- @change="handleCalendarTypeChange"
- >
- <el-radio-button
- v-for="item in calendarTypeOptions"
- :key="item.value"
- :label="item.value"
- >
- {{ item.shortLabel }}
- </el-radio-button>
- </el-radio-group>
- </div>
- </div>
- <div class="calendar-week">
- <span v-for="item in weekNames" :key="item">{{ item }}</span>
- </div>
- <div ref="calendarGrid" class="calendar-grid">
- <el-tooltip
- v-for="day in calendarCells"
- :key="day.key"
- :disabled="!day.date"
- placement="auto"
- effect="light"
- popper-class="calendar-day-tooltip"
- :popper-append-to-body="true"
- :popper-options="calendarTooltipPopperOptions"
- :manual="true"
- :value="activeCalendarTooltipKey === day.key"
- :open-delay="120"
- :hide-after="0"
- :enterable="false"
- >
- <div slot="content" class="calendar-tooltip-content">
- <div class="tooltip-head">
- <strong>{{ day.date }}</strong>
- <span v-if="isConflictDay(day)">冲突</span>
- </div>
- <div class="tooltip-row">
- <span>日期类型</span>
- <strong>{{ getDateTypeText(getDayDateType(day)) }}</strong>
- </div>
- <div class="tooltip-row">
- <span>时段</span>
- <strong>{{ getDayRangeText(getDayDetails(day)) }}</strong>
- </div>
- <div class="tooltip-row">
- <span>排班状态</span>
- <strong>{{ hasSchedule(day.date) ? '已排产' : '未排产/空闲' }}</strong>
- </div>
- <div class="tooltip-row">
- <span>临时调整</span>
- <strong>{{ isTempAdjustDay(day) ? '是' : '否' }}</strong>
- </div>
- <div class="tooltip-row">
- <span>冲突说明</span>
- <strong>{{ getDayConflictText(day) || '无' }}</strong>
- </div>
- <div class="tooltip-stats">
- <span>关联计划 {{ getDayPlanCount(day) }}</span>
- <span>明细 {{ getDayDetails(day).length }}</span>
- </div>
- </div>
- <div
- class="calendar-cell"
- :class="getCalendarDayClass(day)"
- @mouseenter="showCalendarTooltip(day)"
- @mouseleave="hideCalendarTooltip(day)"
- @click="day.date && openCalendarDayDrawer(day)"
- >
- <div v-if="day.date" class="day-head">
- <span>{{ day.dayText }}</span>
- <el-tag
- v-if="isHolidayDay(day)"
- size="mini"
- class="holiday-tag"
- >
- 节假日
- </el-tag>
- <el-tag
- v-else-if="isTempAdjustDay(day)"
- size="mini"
- class="temp-adjust-tag"
- >
- 临调
- </el-tag>
- <em v-if="day.isToday">今</em>
- </div>
- <div v-if="day.date" class="day-body">
- <span
- v-for="(item, index) in getDayPeriodList(day)"
- :key="`${day.date}-${index}`"
- class="period-pill"
- >
- {{ item }}
- </span>
- </div>
- <div v-if="day.date" class="day-foot">
- <span v-if="getDayStatusText(day)" class="plan-text">
- {{ getDayStatusText(day) }}
- </span>
- <span v-if="isConflictDay(day)" class="conflict-text">
- 冲突
- </span>
- </div>
- </div>
- </el-tooltip>
- </div>
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
- <el-drawer
- :visible.sync="dayDrawerVisible"
- :title="dayDrawerTitle"
- size="460px"
- append-to-body
- custom-class="calendar-day-drawer"
- >
- <div class="drawer-body" v-if="currentDay.date">
- <div class="drawer-summary">
- <div class="summary-date">
- <span>{{ drawerDateMonth }}</span>
- <strong>{{ drawerDateDay }}</strong>
- </div>
- <div class="summary-info">
- <div class="summary-title">
- {{ getDateTypeText(getDayDateType(currentDay)) }}
- <el-tag
- size="mini"
- :type="currentDay.scheduleStatus ? 'success' : 'info'"
- >
- {{ currentDay.scheduleStatus ? '已排班' : '未排班' }}
- </el-tag>
- </div>
- <p>{{ getDayRangeText(currentDay.details) }}</p>
- <div class="summary-tags">
- <el-tag v-if="currentDay.isRest" size="mini" type="info">
- 休息/节假日
- </el-tag>
- <el-tag v-if="currentDay.isTempAdjust" size="mini">
- 临时调整
- </el-tag>
- <el-tag v-if="currentDay.isConflict" size="mini" type="danger">
- 存在冲突
- </el-tag>
- <el-tag v-if="currentDay.planCount" size="mini" type="warning">
- {{ currentDay.planCount }} 个计划
- </el-tag>
- </div>
- </div>
- </div>
- <div class="drawer-section">
- <div class="drawer-title">
- <span>时段明细</span>
- <em>{{ currentDay.details.length }} 条</em>
- </div>
- <div v-if="currentDay.details.length" class="detail-timeline">
- <div
- v-for="(detail, index) in currentDay.details"
- :key="detail.id || index"
- class="detail-item"
- >
- <div class="detail-time">
- <strong>{{ getDetailTimeText(detail) }}</strong>
- </div>
- <div class="detail-content">
- <div>
- <strong>{{ getDetailTitle(detail) }}</strong>
- <span>{{ getDetailTimeText(detail) }}</span>
- </div>
- <el-tag
- size="mini"
- :type="isCalendarDetailScheduled(detail) ? 'success' : 'info'"
- >
- {{ isCalendarDetailScheduled(detail) ? '已排班' : '未排班' }}
- </el-tag>
- </div>
- </div>
- </div>
- <div v-else class="drawer-empty">暂无时段明细</div>
- </div>
- <div class="drawer-section">
- <div class="drawer-title">
- <span>{{ relatedSectionTitle }}</span>
- <em>{{ getCurrentDayRelatedPlans().length }} 条</em>
- </div>
- <div v-if="getCurrentDayRelatedPlans().length" class="plan-list">
- <el-tooltip
- v-for="(plan, index) in getCurrentDayRelatedPlans()"
- :key="getPlanUniqueKey(plan, index)"
- placement="top"
- effect="light"
- >
- <div slot="content" class="plan-tooltip">
- <template v-if="isTeamQueueDrawer">
- <div>排班名称:{{ getRelatedQueueName(plan) }}</div>
- <div>人员:{{ getRelatedQueueUserName(plan) || '-' }}</div>
- </template>
- <template v-else>
- <div>
- {{ isEquipmentDrawer ? '设备编码' : '计划编号' }}:{{
- getRelatedPlanCode(plan, index)
- }}
- </div>
- <div>
- {{ isEquipmentDrawer ? '设备名称' : '计划名称' }}:{{
- getRelatedPlanName(plan)
- }}
- </div>
- <div v-if="!isEquipmentDrawer">
- 订单编号:{{ plan.orderNo || '-' }}
- </div>
- <div v-if="!isEquipmentDrawer">
- 计划数量:{{ getPlanQuantity(plan) || '-' }}
- </div>
- <div>开始时间:{{ getPlanStartTime(plan) || '-' }}</div>
- <div>结束时间:{{ getPlanEndTime(plan) || '-' }}</div>
- </template>
- </div>
- <div class="plan-item">
- <div v-if="isTeamQueueDrawer" class="plan-main">
- <div class="plan-topline">
- <strong>{{ getRelatedQueueName(plan) }}</strong>
- <span>排班</span>
- </div>
- <div class="plan-name">
- 人员:{{ getRelatedQueueUserName(plan) || '-' }}
- </div>
- </div>
- <div v-else class="plan-main">
- <div class="plan-topline">
- <strong>{{ getRelatedPlanCode(plan, index) }}</strong>
- <span v-if="!isEquipmentDrawer && plan.orderNo">
- {{ plan.orderNo }}
- </span>
- </div>
- <div class="plan-name">{{ getRelatedPlanName(plan) }}</div>
- <div class="plan-bottomline">
- <span class="plan-metrics">
- <em v-if="!isEquipmentDrawer && getPlanQuantity(plan)">
- 数量 {{ getPlanQuantity(plan) }}
- </em>
- <em v-if="getPlanTimeRange(plan)">
- {{ getPlanTimeRange(plan) }}
- </em>
- </span>
- </div>
- </div>
- </div>
- </el-tooltip>
- </div>
- <div v-else class="drawer-empty plan-empty">
- <i class="el-icon-box"></i>
- <span>暂无关联计划</span>
- </div>
- </div>
- </div>
- </el-drawer>
- <commonDialog
- ref="commonDialogRef"
- v-if="commonDialogFlag"
- :common-dialog-flag.sync="commonDialogFlag"
- @reload="getCommonFunctionsList"
- ></commonDialog>
- <noticeIssuanceDetail ref="noticeIssuanceDetailRef"></noticeIssuanceDetail>
- </div>
- </template>
- <script>
- import { notifyMessagePageAPI } from '@/api/bpm/task';
- import {
- userResourceDeleteAPI,
- userResourceListAPI,
- getList,
- getMyProjectTotal,
- getMyWorkOrderTotal,
- getMyTaskTotal
- } from '@/api/home';
- import { viewCalendar } from '@/api/productionScheduling/factoryCalendar';
- import { deepClone } from 'ele-admin/lib/utils/core';
- import { mapGetters } from 'vuex';
- import vuedraggable from 'vuedraggable';
- import commonDialog from '@/views/home/common-dialog.vue';
- import { noticeDocumentPageV1API } from '@/api/documents/noticeIssuance/index.js';
- import noticeIssuanceDetail from '@/views/bpm/documents/noticeIssuance/components/addOrEditDraw.vue';
- export default {
- name: 'HomePage',
- components: {
- vuedraggable,
- commonDialog,
- noticeIssuanceDetail
- },
- data() {
- return {
- currentDate: new Date(),
- calendarRange: [],
- commonFunctions: [],
- activeTab: 'notice',
- notifications: [],
- currentPage: 1,
- pageSize: 4,
- hasMore: true,
- portals: [],
- selectedCalendarType: 1,
- activeCalendarTooltipKey: '',
- calendarTooltipPopperOptions: {
- modifiers: {
- preventOverflow: {
- boundariesElement: 'viewport',
- padding: 12
- },
- flip: {
- boundariesElement: 'viewport',
- padding: 12
- }
- }
- },
- calendarTypeOptions: [
- { label: '标准生产日历', shortLabel: '标准生产', value: 1 },
- { label: '设备维护日历', shortLabel: '设备维护', value: 2 },
- { label: '人员排班日历', shortLabel: '人员排班', value: 3 }
- ],
- isDelFlag: false,
- commonDialogFlag: false,
- myProjectList: {},
- myWorkOrderList: {},
- myTaskList: {},
- myWorkCalendar: {},
- groupedWorkCalendar: {}, // 分组后的工作日历数据
- selectedScheduleDate: '', // 当前选中的日期
- dayDrawerVisible: false,
- currentDay: {},
- weekNames: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
- };
- },
- computed: {
- ...mapGetters(['user']),
- calendarViewTitle() {
- const date = new Date(this.currentDate);
- const year = date.getFullYear();
- const month = date.getMonth() + 1;
- return `${year} 年 ${month} 月`;
- },
- calendarCells() {
- if (!this.calendarRange || this.calendarRange.length < 2) {
- return [];
- }
- const start = this.parseCalendarDate(this.calendarRange[0]);
- const end = this.parseCalendarDate(this.calendarRange[1]);
- if (!start || !end) {
- return [];
- }
- const cells = [];
- const startOffset = (start.getDay() + 6) % 7;
- for (let i = 0; i < startOffset; i += 1) {
- cells.push({ key: `empty-${i}`, date: '' });
- }
- const cursor = new Date(start);
- while (cursor <= end) {
- const date = this.formatCalendarDate(cursor);
- cells.push({
- key: date,
- date,
- dayText: String(cursor.getDate()),
- isToday: this.isSameCalendarDate(cursor, new Date()),
- isSelected: date === this.selectedScheduleDate,
- isWeekend: [0, 6].includes(cursor.getDay()),
- schedules: this.groupedWorkCalendar[date] || []
- });
- cursor.setDate(cursor.getDate() + 1);
- }
- const trailingCount = cells.length % 7;
- if (trailingCount) {
- for (let i = trailingCount; i < 7; i += 1) {
- cells.push({ key: `empty-tail-${i}`, date: '' });
- }
- }
- return cells;
- },
- calendarSummary() {
- const days = this.calendarCells.filter((day) => day.date);
- const busyDays = days.filter((day) =>
- this.hasSchedule(day.date)
- ).length;
- const restDays = days.filter((day) => day.isWeekend).length;
- const total = days.reduce((sum, day) => {
- return sum + this.getScheduleCount(day.date);
- }, 0);
- return {
- total,
- busyDays,
- idleDays: Math.max(days.length - busyDays - restDays, 0)
- };
- },
- currentNotifications() {
- const notifications = this.notifications[this.activeTab] || [];
- return notifications;
- },
- dayDrawerTitle() {
- return this.currentDay.date
- ? `${this.currentDay.date} 日历详情`
- : '日历详情';
- },
- drawerDateMonth() {
- return this.currentDay.date ? this.currentDay.date.slice(0, 7) : '';
- },
- drawerDateDay() {
- return this.currentDay.date ? this.currentDay.date.slice(8, 10) : '';
- },
- relatedSectionTitle() {
- return this.isTeamQueueDrawer ? '排班详情' : '关联计划';
- },
- isEquipmentDrawer() {
- return (
- Number(this.selectedCalendarType) === 2 ||
- (this.currentDay.details || []).some(
- (item) => Number(item.calendarType) === 2
- )
- );
- },
- isTeamQueueDrawer() {
- return (
- Number(this.selectedCalendarType) === 3 ||
- (this.currentDay.details || []).some(
- (item) => Number(item.calendarType) === 3
- )
- );
- }
- },
- watch: {
- currentDate: {
- handler(newVal, oldVal) {
- // 检查月份是否变化
- if (
- newVal.getMonth() !== oldVal.getMonth() ||
- newVal.getFullYear() !== oldVal.getFullYear()
- ) {
- // 重新计算日期范围
- this.calendarRange = this.getMonthRange();
- // 重新获取日程数据
- this.getMyWorkCalendar();
- }
- // 日期变化时,处理选中日期的日程
- if (newVal !== oldVal) {
- const year = newVal.getFullYear();
- const month = String(newVal.getMonth() + 1).padStart(2, '0');
- const day = String(newVal.getDate()).padStart(2, '0');
- const dateStr = `${year}-${month}-${day}`;
- this.handleDateClick(dateStr);
- }
- },
- deep: true
- }
- },
- created() {
- this.calendarRange = this.getMonthRange();
- this.selectedScheduleDate = this.formatCalendarDate(new Date());
- this.getPortalsList();
- this.getCommonFunctionsList();
- this.getMyProjectTotal();
- this.getMyWorkOrderTotal();
- this.getMyTaskTotal();
- this.getMessageList();
- this.getMyWorkCalendar();
- },
- methods: {
- openUrl(item) {
- // 统一门户配置
- if (item.architType === '1') {
- // bs门户配置
- window.open(item.linkUrl);
- } else {
- let url = item.linkUrl.split('//');
- window.open(url[1], '_blank');
- }
- },
- handleNotificationsClick(item) {
- console.log('item~~~', item);
- if (this.activeTab === 'system') return;
- this.$refs.noticeIssuanceDetailRef.openDrawer({
- id: item.id,
- type: 'view'
- });
- // this.$router.push({
- // // query
- // query: {
- // id: item.id,
- // type: 'detail'
- // }
- // });
- },
- async getMyWorkCalendar() {
- const date = new Date(this.currentDate);
- const res = await viewCalendar({
- calendarType: this.selectedCalendarType,
- year: date.getFullYear(),
- month: date.getMonth() + 1,
- viewType: 'month'
- });
- const list = Array.isArray(res) ? res : [];
- const groupedData = {};
- list.forEach((item) => {
- const detail = this.normalizeWorkCalendarItem(item);
- if (!detail.date) {
- return;
- }
- if (!groupedData[detail.date]) {
- groupedData[detail.date] = [];
- }
- groupedData[detail.date].push(detail);
- });
- this.groupedWorkCalendar = groupedData;
- this.$nextTick(() => {
- this.scrollCurrentWeekToTop();
- });
- if (
- !this.selectedScheduleDate ||
- !this.isDateInCurrentMonth(this.selectedScheduleDate)
- ) {
- this.selectedScheduleDate = this.formatCalendarDate(new Date());
- }
- },
- hasSchedule(day) {
- return this.getScheduleCount(day) > 0;
- },
- handleCalendarTypeChange() {
- this.calendarRange = this.getMonthRange();
- this.groupedWorkCalendar = {};
- this.getMyWorkCalendar();
- },
- scrollCurrentWeekToTop() {
- const grid = this.$refs.calendarGrid;
- if (!grid) {
- return;
- }
- const today = this.formatCalendarDate(new Date());
- const todayIndex = this.calendarCells.findIndex(
- (day) => day.date === today
- );
- if (todayIndex === -1) {
- grid.scrollTop = 0;
- return;
- }
- const weekIndex = Math.floor(todayIndex / 7);
- const weekStartCell = grid.querySelectorAll('.calendar-cell')[
- weekIndex * 7
- ];
- if (!weekStartCell) {
- grid.scrollTop = 0;
- return;
- }
- const targetTop =
- weekStartCell.getBoundingClientRect().top -
- grid.getBoundingClientRect().top +
- grid.scrollTop;
- grid.scrollTo({
- top: Math.max(targetTop, 0),
- behavior: 'auto'
- });
- },
- handleDateClick(day) {
- console.log('day~~~', day);
- this.selectedScheduleDate = day;
- },
- showCalendarTooltip(day) {
- if (day.date) {
- this.activeCalendarTooltipKey = day.key;
- }
- },
- hideCalendarTooltip(day) {
- if (!day || this.activeCalendarTooltipKey === day.key) {
- this.activeCalendarTooltipKey = '';
- }
- },
- openCalendarDayDrawer(day) {
- if (!day || !day.date) {
- return;
- }
- this.hideCalendarTooltip(day);
- this.handleDateClick(day.date);
- this.currentDay = {
- ...day,
- details: this.getDayDetails(day),
- planCount: this.getDayPlanCount(day),
- scheduleStatus: this.hasSchedule(day.date),
- isRest: this.isRestDay(day),
- isConflict: this.isConflictDay(day),
- isTempAdjust: this.isTempAdjustDay(day),
- isMaintenance: this.isMaintenanceDay(day),
- relatedPlans: this.getDayRelatedPlans(day),
- conflictText: this.getDayConflictText(day)
- };
- this.dayDrawerVisible = true;
- },
- getScheduleListByDate() {
- if (
- this.selectedScheduleDate &&
- this.groupedWorkCalendar[this.selectedScheduleDate]
- ) {
- return this.groupedWorkCalendar[this.selectedScheduleDate];
- }
- return [];
- },
- parseCalendarDate(value) {
- if (!value) {
- return null;
- }
- const date = new Date(String(value).replace(/-/g, '/'));
- return Number.isNaN(date.getTime()) ? null : date;
- },
- formatCalendarDate(date) {
- const year = date.getFullYear();
- const month = String(date.getMonth() + 1).padStart(2, '0');
- const day = String(date.getDate()).padStart(2, '0');
- return `${year}-${month}-${day}`;
- },
- isSameCalendarDate(date, targetDate) {
- return (
- this.formatCalendarDate(date) === this.formatCalendarDate(targetDate)
- );
- },
- getScheduleCount(day) {
- const list =
- this.groupedWorkCalendar && this.groupedWorkCalendar[day]
- ? this.groupedWorkCalendar[day]
- : [];
- return list.filter((item) => this.isCalendarDetailScheduled(item))
- .length;
- },
- getCalendarDayClass(day) {
- if (!day.date) {
- return ['empty'];
- }
- return {
- scheduled: this.hasSchedule(day.date),
- rest: !this.hasSchedule(day.date) && this.isRestDay(day),
- idle: !this.hasSchedule(day.date) && !this.isRestDay(day),
- holiday: this.isHolidayDay(day),
- maintenance: this.isMaintenanceDay(day),
- temp: this.isTempAdjustDay(day),
- conflict: this.isConflictDay(day),
- 'is-today': day.isToday,
- 'is-selected': day.isSelected
- };
- },
- getCalendarDayTitle(day) {
- if (!day.date) {
- return '';
- }
- const details = this.getDayDetails(day);
- const rangeText = this.getDayPeriodList(day).join(',') || '无时段';
- const statusText = this.hasSchedule(day.date)
- ? '已排产'
- : '未排产/空闲';
- const conflictText = this.getDayConflictText(day);
- return [
- `日期:${day.date}`,
- `日期类型:${this.getDateTypeText(this.getDayDateType(day))}`,
- `时段:${rangeText}`,
- `排班状态:${statusText}`,
- `临时调整:${this.isTempAdjustDay(day) ? '是' : '否'}`,
- `冲突说明:${conflictText || '无'}`,
- `关联计划数:${this.getDayPlanCount(day)}`,
- `明细数:${details.length}`
- ].join('\n');
- },
- getCalendarDayStatus(day) {
- const count = this.getScheduleCount(day.date);
- if (count) {
- return '项';
- }
- return day.isWeekend ? '休息' : '待排';
- },
- getCalendarLoadWidth(day) {
- const count = this.getScheduleCount(day.date);
- if (!count) {
- return '0%';
- }
- return `${Math.min(100, Math.max(18, count * 5))}%`;
- },
- getCalendarDayType(day) {
- if (this.hasSchedule(day.date)) {
- return '生产';
- }
- return day.isWeekend ? '休息' : '空闲';
- },
- getDayDetails(day) {
- return day && Array.isArray(day.schedules) ? day.schedules : [];
- },
- getDayPlanCount(day) {
- const details = this.getDayDetails(day);
- const relatedPlans = this.getDayRelatedPlans(day);
- if (relatedPlans.length) {
- return relatedPlans.length;
- }
- return details.reduce((sum, item) => {
- return (
- sum + Number(item.relationPlanCount || item.planCount || 0)
- );
- }, 0);
- },
- getDetailRelatedPlans(item) {
- return [
- ...(Array.isArray(item.relationPlanList) ? item.relationPlanList : []),
- ...(Array.isArray(item.relationEamPlanList)
- ? item.relationEamPlanList
- : []),
- ...(Array.isArray(item.relationTeamQueueList)
- ? item.relationTeamQueueList
- : [])
- ];
- },
- getDayRelatedPlans(day) {
- const planMap = {};
- this.getDayDetails(day).forEach((item) => {
- this.getDetailRelatedPlans(item).forEach((plan, index) => {
- const key = this.getPlanUniqueKey(
- plan,
- `${item.id || item.date}-${index}`
- );
- planMap[key] = plan;
- });
- });
- return Object.values(planMap);
- },
- getCurrentDayRelatedPlans() {
- return Array.isArray(this.currentDay.relatedPlans)
- ? this.currentDay.relatedPlans
- : [];
- },
- getSelectedDayPlanCount() {
- return this.getDayPlanCount({
- schedules: this.getScheduleListByDate()
- });
- },
- isSelectedDayConflict() {
- return this.getScheduleListByDate().some(
- (item) => Number(item.isConflict) === 1
- );
- },
- getDayDateType(day) {
- const first = this.getDayDetails(day)[0];
- if (first) {
- return first.dateType;
- }
- return day.isWeekend ? 2 : 1;
- },
- getDayConflictText(day) {
- const conflict = this.getDayDetails(day).find(
- (item) => Number(item.isConflict) === 1
- );
- return conflict
- ? conflict.conflictText ||
- conflict.message ||
- conflict.remark ||
- '存在冲突'
- : '';
- },
- getDayPeriodList(day) {
- return this.getDayDetails(day)
- .filter(
- (item) =>
- item.startHour || item.endHour || Number(item.dateType) !== 1
- )
- .slice(0, 2)
- .map((item) => {
- if (item.startHour || item.endHour) {
- return `${item.startHour || ''}-${item.endHour || ''}`;
- }
- return item.typeText;
- });
- },
- getDayRangeText(details = []) {
- const ranges = details
- .map((item) => this.getDetailTimeText(item))
- .filter(Boolean);
- return ranges.length ? ranges.join(',') : '无时段';
- },
- getDayStatusText(day) {
- const count = this.getDayPlanCount(day);
- if (count > 0) {
- return `计划数:${count > 999 ? '999+' : count}`;
- }
- return '';
- },
- getDayPlanCountText(day) {
- const count = this.getDayPlanCount(day);
- return count > 999 ? '999+' : count;
- },
- isRestDay(day) {
- const details = this.getDayDetails(day);
- if (!details.length) {
- return day.isWeekend;
- }
- return details.every((item) => [2, 3].includes(Number(item.dateType)));
- },
- isHolidayDay(day) {
- return this.getDayDetails(day).some(
- (item) => Number(item.dateType) === 3
- );
- },
- isMaintenanceDay(day) {
- return this.getDayDetails(day).some(
- (item) => Number(item.dateType) === 4
- );
- },
- isTempAdjustDay(day) {
- return this.getDayDetails(day).some(
- (item) =>
- Number(item.isTempAdjust) === 1 || Number(item.dateType) === 5
- );
- },
- isConflictDay(day) {
- return this.getDayDetails(day).some(
- (item) => Number(item.isConflict) === 1
- );
- },
- getDetailTimeText(item) {
- if (item.startHour || item.endHour) {
- return `${item.startHour || ''}-${item.endHour || ''}`;
- }
- return '全天';
- },
- getDetailTitle(item) {
- return item.dutyName || item.dateTypeName || item.typeText || this.getDateTypeText(item.dateType);
- },
- getPlanUniqueKey(plan = {}, fallback = '') {
- return (
- plan.planNo ||
- plan.planCode ||
- plan.productionPlanCode ||
- plan.code ||
- plan.id ||
- plan.planId ||
- fallback
- );
- },
- getPlanCode(plan, index) {
- return (
- plan.planNo ||
- plan.planCode ||
- plan.code ||
- plan.productionPlanCode ||
- plan.id ||
- plan.name ||
- plan.planName ||
- `计划${index + 1}`
- );
- },
- getRelatedPlanCode(plan = {}, index = 0) {
- return (
- (this.isEquipmentDrawer
- ? plan.deviceCode ||
- plan.equipmentCode ||
- plan.eamCode ||
- plan.assetCode ||
- plan.planNo ||
- plan.planCode ||
- plan.code
- : this.getPlanCode(plan, index)) || '-'
- );
- },
- getRelatedPlanName(plan = {}) {
- return (
- (this.isEquipmentDrawer
- ? plan.deviceName ||
- plan.equipmentName ||
- plan.eamName ||
- plan.assetName ||
- this.getPlanNameFallback(plan)
- : plan.taskName ||
- plan.planName ||
- plan.name ||
- this.getPlanObjectName(plan)) || '-'
- );
- },
- getRelatedQueueName(plan = {}) {
- return plan.teamQueueName || plan.queueName || this.getPlanNameFallback(plan) || '-';
- },
- getRelatedQueueUserName(plan = {}) {
- return plan.userName || plan.userNames || plan.staffName || '';
- },
- getPlanNameFallback(plan = {}) {
- return (
- plan.taskName ||
- plan.planName ||
- plan.name ||
- plan.title ||
- plan.productName ||
- plan.bomCategoryName ||
- plan.deviceName ||
- plan.equipmentName ||
- plan.eamName ||
- plan.assetName ||
- plan.machineName ||
- plan.resourceName ||
- ''
- );
- },
- getPlanObjectName(plan) {
- const calendarType = Number(plan.calendarType || this.selectedCalendarType);
- if (calendarType === 2) {
- return (
- plan.equipmentName ||
- plan.deviceName ||
- plan.eamName ||
- plan.assetName ||
- plan.machineName ||
- plan.resourceName ||
- this.getPlanNameFallback(plan) ||
- ''
- );
- }
- if (calendarType === 3) {
- return (
- plan.teamQueueName ||
- plan.queueName ||
- plan.userName ||
- this.getPlanNameFallback(plan) ||
- ''
- );
- }
- return (
- this.getPlanNameFallback(plan) ||
- plan.equipmentName ||
- plan.deviceName ||
- plan.machineName ||
- plan.resourceName ||
- plan.productionLineName ||
- plan.workCenterName ||
- plan.productName ||
- plan.materialName ||
- ''
- );
- },
- getPlanQuantity(plan) {
- return (
- plan.requiredFormingNum ||
- plan.quantity ||
- plan.qty ||
- plan.planQty ||
- plan.amount ||
- ''
- );
- },
- getPlanStartTime(plan) {
- return (
- plan.displayStartTime ||
- plan.startTime ||
- plan.planStartTime ||
- plan.beginTime ||
- ''
- );
- },
- getPlanEndTime(plan) {
- return (
- plan.displayEndTime ||
- plan.endTime ||
- plan.planEndTime ||
- plan.finishTime ||
- ''
- );
- },
- getPlanTimeRange(plan) {
- const start = this.getPlanStartTime(plan);
- const end = this.getPlanEndTime(plan);
- if (start && end) {
- return `${start} - ${end}`;
- }
- return start || end || '';
- },
- getDateTypeText(dateType) {
- const map = {
- 1: '正常工作日',
- 2: '休息日',
- 3: '节假日',
- 4: '设备检修期',
- 5: '临时调整时段'
- };
- return map[Number(dateType)] || '日历明细';
- },
- getDetailPlanCount(item) {
- const relationPlanList = Array.isArray(item.relationPlanList)
- ? item.relationPlanList
- : [];
- const relationEamPlanList = Array.isArray(item.relationEamPlanList)
- ? item.relationEamPlanList
- : [];
- const relationTeamQueueList = Array.isArray(item.relationTeamQueueList)
- ? item.relationTeamQueueList
- : [];
- const relationCountMap = {
- 2: relationEamPlanList.length,
- 3: relationTeamQueueList.length
- };
- const mappedCount =
- relationCountMap[
- Number(item.calendarType || this.selectedCalendarType)
- ];
- return mappedCount !== undefined
- ? mappedCount
- : Number(
- item.relationPlanCount ||
- item.planCount ||
- relationPlanList.length ||
- 0
- );
- },
- isCalendarDetailScheduled(item) {
- return (
- Number(item.scheduleStatus) === 1 || this.getDetailPlanCount(item) > 0
- );
- },
- normalizeCalendarTime(value) {
- if (!value) {
- return '';
- }
- const text = String(value);
- const time = text.includes(' ') ? text.split(' ')[1] : text;
- return time.slice(0, 5);
- },
- normalizeWorkCalendarItem(item) {
- const startDate =
- item.startTime && String(item.startTime).includes(' ')
- ? String(item.startTime).split(' ')[0]
- : '';
- const date = item.calendarDate || item.date || startDate;
- const dateType = Number(item.dateType || 1);
- const relationPlanCount = this.getDetailPlanCount(item);
- const typeText = item.dateTypeName || this.getDateTypeText(dateType);
- return {
- ...item,
- date,
- time: this.normalizeCalendarTime(item.startTime),
- startHour: this.normalizeCalendarTime(item.startTime),
- endHour: this.normalizeCalendarTime(item.endTime),
- dateType,
- typeText,
- relationPlanCount,
- scheduleStatus: Number(item.scheduleStatus || 0),
- title:
- item.title ||
- item.calendarName ||
- item.planName ||
- item.remark ||
- typeText,
- name:
- item.name ||
- item.shiftName ||
- item.teamName ||
- item.workCenterName ||
- ''
- };
- },
- isDateInCurrentMonth(date) {
- if (!date) {
- return false;
- }
- const current = new Date(this.currentDate);
- return (
- String(date).slice(0, 7) ===
- this.formatCalendarDate(current).slice(0, 7)
- );
- },
- getCalendarDaySummary(day) {
- const first = day.schedules && day.schedules[0];
- if (!first) {
- return '';
- }
- return (
- first.title ||
- first.name ||
- `${first.startHour || ''}~${first.endHour || ''}`
- );
- },
- handleToPro() {
- this.handelRouterTo('/page-pro/project-initiation');
- },
- handleTo(key) {
- switch (key) {
- case '测试项目':
- case '研发项目':
- case '实施项目':
- case '开发项目':
- this.handelRouterTo('/page-pro/project-initiation');
- break;
- case '运维工单':
- this.handelRouterTo(
- '/page-eam/maintenance/patrol?isWt=true&title=工单'
- );
- break;
- case '质检工单':
- this.handelRouterTo('/page-qms/inspectionWork');
- break;
- case '生产工单':
- this.handelRouterTo('/page-mes/produceOrder?isWt=true');
- break;
- case '盘点工单':
- this.handelRouterTo(
- '/page-wms/warehouseManagement/stocktaking/work'
- );
- break;
- case '盘点任务':
- this.handelRouterTo('');
- break;
- case '生产任务':
- this.handelRouterTo('/page-mes/rw');
- break;
- case '质检任务':
- this.handelRouterTo('/page-qms/inspectionProjectTask');
- break;
- case '项目任务':
- this.handelRouterTo('/page-pro/task/myTaskList');
- break;
- }
- },
- async getMessageList() {
- let list = [];
- let total = 0;
- if (this.activeTab === 'notice') {
- const res = await noticeDocumentPageV1API({
- pageNum: this.currentPage,
- size: 5,
- approvalStatus: 2
- });
- console.log('noticeDocumentPageV1API~~~', res);
- total = res.count || 0;
- list = (res.list || []).map((item) => {
- // 提取 HTML 中的图片地址
- const images = [];
- const content = item.content || '';
- const imgRegex = /<img[^>]+src=["']([^"']+)["']/gi;
- let match;
- while ((match = imgRegex.exec(content)) !== null) {
- images.push(match[1]);
- }
- // 提取纯文本内容(去除 HTML 标签和空格)
- const textContent = content
- .replace(/<[^>]+>/g, '')
- .replace(/ /g, '')
- .replace(/\s+/g, '')
- .trim();
- return {
- id: item.id,
- title: item.title,
- content: textContent,
- images: images,
- createUser: '拟稿人:' + item.draftAuthor,
- department: '发文机关:' + item.issuingAuthority,
- createTime: item.createTime
- };
- });
- } else if (this.activeTab === 'industry') {
- list = [];
- } else if (this.activeTab === 'system') {
- const res = await notifyMessagePageAPI({
- pageNum: this.currentPage,
- size: 5
- // userId: this.user.info.userId,
- });
- total = res.count || 0;
- list = (res.list || []).map((item) => {
- return {
- title: item.templateName,
- content: item.templateContent,
- createUser: '创建人:' + item.userName,
- department: item.department,
- createTime: item.createTime
- };
- });
- }
- // 如果是第一页,直接赋值;否则拼接到后面
- if (this.currentPage === 1) {
- this.notifications = list;
- } else {
- this.notifications = [...this.notifications, ...list];
- }
- // 判断是否还有更多数据
- this.hasMore = this.notifications.length < total;
- console.log(
- 'notifications~~~',
- this.notifications,
- 'hasMore:',
- this.hasMore
- );
- },
- async getMyProjectTotal() {
- this.myProjectList = await getMyProjectTotal({});
- },
- async getMyWorkOrderTotal() {
- this.myWorkOrderList = await getMyWorkOrderTotal({});
- },
- async getMyTaskTotal() {
- this.myTaskList = await getMyTaskTotal({});
- },
- handleAdd() {
- // if(this.commonFunctions.length > 12) return this.$message.warning('最多只能添加12个常用功能');
- this.commonDialogFlag = true;
- this.$nextTick(() => {
- this.$refs.commonDialogRef.init();
- });
- },
- handleEdit() {
- this.isDelFlag = !this.isDelFlag;
- },
- handleDel(item, index) {
- if (this.isDelFlag) return this.handleCommonListDel(item, index);
- let urlPath = item.topUrl + item.url;
- console.log('urlPath~~~', urlPath);
- this.handelRouterTo(urlPath);
- },
- async handleCommonListDel(item, index) {
- await userResourceDeleteAPI([item.id]);
- this.commonFunctions.splice(index, 1);
- },
- handelRouterTo(path) {
- window.history.pushState(null, '', path);
- },
- getIconPath(pic) {
- if (pic) {
- // 如果后端返回的是静态路径字符串,需要通过 require() 处理
- return require(`@/assets/home/commonIcon/${pic}`);
- }
- // 如果没有 pic 字段,使用默认图标
- return require('@/assets/home/commonIcon/icon_0.svg');
- },
- async getCommonFunctionsList() {
- this.commonFunctions = await userResourceListAPI();
- console.log('commonFunctions~~~', this.commonFunctions);
- },
- async getPortalsList() {
- let { list } = await getList({ pageNum: 1, size: 9999 });
- this.portals = list.map((item) => {
- return {
- ...item,
- img:
- window.location.origin +
- '/api/main/file/getFile?objectName=' +
- item.iconPath
- };
- });
- console.log(this.portals);
- },
- handleTabClick() {
- // 切换标签页时重置页码和hasMore
- this.currentPage = 1;
- this.hasMore = true;
- this.notifications = [];
- this.getMessageList();
- },
- loadMoreNotifications() {
- // 加载更多通知(增加页码)
- this.currentPage++;
- this.getMessageList();
- // switch(this.activeTab) {
- // case 'notice':
- // this.handelRouterTo('/page-wt/documents/noticeIssuance');
- // break;
- // case 'industry':
- // this.handelRouterTo('/industry');
- // break;
- // case 'system':
- // this.handelRouterTo('/page-wt/message');
- // break;
- // }
- },
- // 获取选中当月的范围
- getMonthRange() {
- const now = new Date(this.currentDate);
- const year = now.getFullYear();
- const month = now.getMonth();
- // 当月第一天
- const firstDay = new Date(year, month, 1);
- // 下月第一天,减一天就是当月最后一天
- const lastDay = new Date(year, month + 1, 0);
- const formatDate = (date) => {
- const year = date.getFullYear();
- const month = String(date.getMonth() + 1).padStart(2, '0');
- const day = String(date.getDate()).padStart(2, '0');
- return `${year}-${month}-${day}`;
- };
- return [formatDate(firstDay), formatDate(lastDay)];
- }
- }
- };
- </script>
- <style lang="scss" scoped>
- .home-container {
- width: 100%;
- padding: 10px;
- box-sizing: border-box;
- display: flex;
- flex-direction: column;
- height: calc(100vh - 96px);
- min-height: 0;
- overflow: hidden;
- .home-top-row {
- flex: 0 0 148px;
- height: 148px;
- }
- .home-overview-row {
- flex: 0 0 232px;
- height: 232px;
- }
- .home-bottom-row {
- flex: 1 1 auto;
- min-height: 0;
- height: auto;
- }
- .card-content {
- &.common-function-card {
- overflow-x: auto;
- overflow-y: hidden;
- white-space: nowrap;
- padding-bottom: 8px;
- &::-webkit-scrollbar {
- height: 6px;
- }
- &::-webkit-scrollbar-track {
- background: #f1f1f1;
- border-radius: 3px;
- }
- &::-webkit-scrollbar-thumb {
- background: #c1c1c1;
- border-radius: 3px;
- }
- &::-webkit-scrollbar-thumb:hover {
- background: #a8a8a8;
- }
- .common-function {
- flex-wrap: nowrap;
- display: inline-flex;
- }
- }
- &.portal-content {
- max-height: 172px;
- overflow-y: auto;
- overflow-x: hidden;
- padding-right: 8px;
- flex-shrink: 0;
- min-height: 0;
- .portal {
- max-height: 100%;
- overflow-y: auto;
- overflow-x: hidden;
- }
- &::-webkit-scrollbar {
- width: 6px;
- }
- &::-webkit-scrollbar-track {
- background: #f1f1f1;
- border-radius: 3px;
- }
- &::-webkit-scrollbar-thumb {
- background: #c1c1c1;
- border-radius: 3px;
- }
- &::-webkit-scrollbar-thumb:hover {
- background: #a8a8a8;
- }
- }
- &.calendar-content {
- height: 100%;
- min-height: 0;
- overflow-y: hidden;
- overflow-x: hidden;
- padding: 8px 8px 10px;
- box-sizing: border-box;
- &::-webkit-scrollbar {
- width: 6px;
- }
- &::-webkit-scrollbar-track {
- background: #f1f1f1;
- border-radius: 3px;
- }
- &::-webkit-scrollbar-thumb {
- background: #c1c1c1;
- border-radius: 3px;
- }
- &::-webkit-scrollbar-thumb:hover {
- background: #a8a8a8;
- }
- }
- .common-function {
- display: flex;
- flex-wrap: wrap;
- justify-content: flex-start;
- align-items: center;
- .common-function-item {
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- margin: 0 18px;
- border-radius: 5px;
- cursor: pointer;
- transition: all 0.3s ease-in-out;
- .common-function-item-icon {
- width: 50px;
- height: 50px;
- box-shadow: 0px 1px 2px 1px #eae7e7;
- background: #f8fafc;
- border-radius: 17px;
- display: flex;
- justify-content: center;
- align-items: center;
- img {
- width: 30px;
- height: 30px;
- }
- }
- .common-function-item-name {
- font-size: 14px;
- font-weight: 400;
- color: #3f3e3e;
- margin-top: 10px;
- }
- }
- .div-del {
- // background: #cccccc !important;
- position: relative;
- }
- .div-del::after {
- content: '—';
- position: absolute;
- padding: 5px; /* 按钮的内边距 */
- background-color: rgba(255, 0, 0, 0.91);
- color: white;
- border-radius: 50%;
- }
- }
- .overview-container {
- .overview {
- padding: 16px;
- box-sizing: border-box;
- border-radius: 17px;
- box-shadow: -1px 1px 0px 1px #ececec, 1px -1px 0px 1px #ececec;
- border: 1px solid #ececec;
- .overview-top {
- display: flex;
- justify-content: flex-start;
- align-items: center;
- .overview-top-img {
- width: 66px;
- height: 66px;
- border-radius: 50%;
- margin-right: 10px;
- img {
- width: 100%;
- height: 100%;
- }
- }
- .overview-top-content {
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: flex-start;
- .overview-top-content-name {
- font-size: 18px;
- font-weight: 500;
- color: #525252;
- }
- .overview-top-content-count {
- font-size: 28px;
- font-weight: 500;
- color: #2d80ee;
- line-height: 42px;
- // margin-top: 8px;
- }
- }
- }
- .el-divider {
- margin: 12px 0;
- }
- .overview-bottom {
- display: grid;
- grid-template-columns: repeat(2, 1fr);
- grid-gap: 10px;
- max-height: 45px;
- overflow-y: auto;
- .overview-bottom-item {
- display: flex;
- justify-content: flex-start;
- align-items: center;
- cursor: pointer;
- .overview-bottom-item-name {
- font-size: 14px;
- font-weight: 400;
- color: #686767;
- margin-right: 30px;
- }
- .overview-bottom-item-count {
- font-size: 15px;
- font-weight: 400;
- color: #303133;
- }
- }
- }
- }
- }
- .portal {
- .portal-item {
- margin-bottom: 12px;
- .portal-item-content {
- display: flex;
- justify-content: flex-start;
- align-items: center;
- border-radius: 11px;
- border: 1px solid #ebebeb;
- box-shadow: 0px 4px 4px #a7a7a740;
- padding: 6px 4px;
- cursor: pointer;
- .portal-item-img {
- width: 40px;
- height: 32px;
- border-radius: 5px;
- margin-right: 10px;
- img {
- width: 100%;
- height: 100%;
- }
- }
- .portal-item-name {
- font-size: 13px;
- font-weight: bold;
- color: #303133;
- }
- }
- }
- }
- .work-calendar {
- height: 100%;
- min-height: 0;
- border: 1px solid #e4edf7;
- border-radius: 6px;
- background: #fff;
- box-shadow: 0 10px 24px rgba(31, 45, 61, 0.05);
- overflow: hidden;
- display: flex;
- flex-direction: column;
- margin: 4px 0 0;
- .calendar-view-title {
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: 8px;
- height: 38px;
- flex: 0 0 38px;
- padding: 0 12px;
- border-bottom: 1px solid #e4edf7;
- color: #303133;
- font-size: 15px;
- font-weight: 600;
- background: linear-gradient(90deg, #f4f9ff, #ffffff);
- .calendar-title-tools {
- display: flex;
- align-items: center;
- justify-content: flex-end;
- min-width: 0;
- .calendar-type-switch {
- display: inline-flex;
- padding: 3px;
- border: 1px solid #d9e5f2;
- border-radius: 8px;
- background: #f6f9fd;
- white-space: nowrap;
- ::v-deep .el-radio-button__inner {
- height: 28px;
- padding: 0 13px;
- border: 0;
- border-radius: 6px;
- color: #536273;
- font-size: 12px;
- font-weight: 700;
- line-height: 28px;
- background: transparent;
- box-shadow: none;
- }
- ::v-deep .el-radio-button:first-child .el-radio-button__inner {
- border-radius: 6px;
- }
- ::v-deep .el-radio-button:last-child .el-radio-button__inner {
- border-radius: 6px;
- }
- ::v-deep
- .el-radio-button__orig-radio:checked
- + .el-radio-button__inner {
- background: #2f80ed;
- color: #fff;
- box-shadow: 0 4px 10px rgba(47, 128, 237, 0.24);
- }
- }
- }
- }
- .calendar-week {
- display: grid;
- grid-template-columns: repeat(7, minmax(0, 1fr));
- border-top: 2px solid #2f80ed;
- border-bottom: 1px solid #d8e6f5;
- flex: 0 0 30px;
- background: linear-gradient(180deg, #f1f7ff 0%, #ffffff 100%);
- span {
- position: relative;
- height: 30px;
- line-height: 30px;
- text-align: center;
- color: #344968;
- font-size: 12px;
- font-weight: 700;
- background: transparent;
- &::after {
- content: '';
- position: absolute;
- left: 50%;
- bottom: 4px;
- width: 16px;
- height: 2px;
- border-radius: 2px;
- background: #2f80ed;
- transform: translateX(-50%);
- opacity: 0.72;
- }
- &:nth-child(6),
- &:nth-child(7) {
- color: #c45656;
- &::after {
- background: #f56c6c;
- }
- }
- }
- }
- .calendar-grid {
- display: grid;
- grid-template-columns: repeat(7, minmax(0, 1fr));
- grid-auto-rows: minmax(96px, auto);
- flex: 1 1 auto;
- min-height: 0;
- overflow-y: auto;
- overflow-x: hidden;
- background: #e5edf6;
- gap: 1px;
- padding-bottom: 8px;
- &::-webkit-scrollbar {
- width: 6px;
- }
- &::-webkit-scrollbar-track {
- background: #f1f4f8;
- border-radius: 3px;
- }
- &::-webkit-scrollbar-thumb {
- background: #aeb8c4;
- border-radius: 3px;
- }
- &::-webkit-scrollbar-thumb:hover {
- background: #8c96a3;
- }
- }
- .calendar-cell {
- min-height: 96px;
- padding: 6px 7px 6px 10px;
- border: 0;
- background: #fff;
- position: relative;
- cursor: pointer;
- overflow: hidden;
- transition: box-shadow 0.2s, background 0.2s, transform 0.2s;
- &::before {
- content: '';
- position: absolute;
- left: 0;
- top: 0;
- width: 3px;
- height: 100%;
- background: transparent;
- }
- &:hover {
- z-index: 1;
- box-shadow: inset 0 0 0 1px #409eff,
- 0 8px 18px rgba(64, 158, 255, 0.12);
- }
- &.empty {
- cursor: default;
- background: #f8fafc;
- }
- &.scheduled {
- background: #ecf5ff;
- &::before {
- background: #409eff;
- }
- }
- &.rest {
- background: #f2f3f5;
- &::before {
- background: #a8abb2;
- }
- }
- &.idle {
- background: #fff;
- }
- &.holiday {
- background: #fff7e8;
- &::before {
- background: #f59e0b;
- }
- }
- &.maintenance {
- background: #fff3e6;
- &::before {
- background: #e6a23c;
- }
- }
- &.temp {
- background: #f5efff;
- &::before {
- background: #9254de;
- }
- }
- &.conflict {
- background: #fef0f0;
- animation: conflictFlash 1.4s infinite;
- &::before {
- background: #f56c6c;
- }
- }
- &.is-today {
- box-shadow: inset 0 0 0 1px rgba(64, 158, 255, 0.45);
- }
- &.is-selected {
- box-shadow: inset 0 0 0 2px #409eff;
- }
- }
- .day-head,
- .day-foot {
- display: flex;
- align-items: center;
- justify-content: space-between;
- min-height: 18px;
- }
- .day-head {
- gap: 3px;
- span {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- min-width: auto;
- height: 18px;
- padding: 0;
- border-radius: 0;
- color: #303133;
- font-size: 15px;
- font-weight: 700;
- }
- em {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- width: 16px;
- height: 16px;
- margin-left: auto;
- border-radius: 50%;
- background: #409eff;
- color: #fff;
- font-size: 11px;
- font-style: normal;
- line-height: 1;
- text-align: center;
- }
- }
- .temp-adjust-tag {
- height: 15px;
- padding: 0 3px;
- border-color: #d3b7ff;
- background: #f4efff;
- color: #7c3fd1;
- font-size: 9px;
- font-weight: 700;
- line-height: 13px;
- white-space: nowrap;
- transform: scale(0.88);
- transform-origin: right top;
- margin-left: auto;
- }
- .holiday-tag {
- height: 15px;
- padding: 0 3px;
- border-color: #f7c873;
- background: #fff3d6;
- color: #b76e00;
- font-size: 9px;
- font-weight: 700;
- line-height: 13px;
- white-space: nowrap;
- transform: scale(0.86);
- transform-origin: right top;
- }
- .day-body {
- min-height: 34px;
- margin: 4px 0;
- }
- .period-pill {
- display: block;
- width: fit-content;
- max-width: 100%;
- margin-bottom: 3px;
- padding: 0 4px;
- border: 1px solid rgba(144, 147, 153, 0.16);
- border-radius: 4px;
- background: rgba(255, 255, 255, 0.72);
- color: #606266;
- font-size: 10px;
- line-height: 16px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- .day-foot {
- position: relative;
- display: flex;
- align-items: center;
- justify-content: flex-start;
- color: #5f6f85;
- gap: 2px;
- font-size: 11px;
- line-height: 16px;
- white-space: nowrap;
- min-width: 0;
- min-height: 18px;
- padding-right: 0;
- span {
- overflow: hidden;
- text-overflow: ellipsis;
- min-width: 0;
- }
- .plan-text {
- color: #5f6f85;
- flex: 0 0 auto;
- max-width: none;
- overflow: visible;
- text-overflow: clip;
- font-size: 10px;
- font-weight: 600;
- letter-spacing: -0.2px;
- line-height: 16px;
- }
- .conflict-text {
- flex: 0 0 auto;
- margin-left: auto;
- color: #ff4d4f;
- font-size: 11px;
- font-weight: 700;
- }
- }
- }
- }
- }
- .mt-20 {
- margin-top: 6px;
- }
- .box-col {
- height: 100%;
- }
- .box-card {
- height: 100%;
- margin-bottom: 0;
- display: flex;
- flex-direction: column;
- ::v-deep .el-card__header {
- flex: 0 0 auto;
- padding: 10px 8px;
- font-weight: bold;
- color: #303133;
- }
- ::v-deep .el-card__body {
- flex: 1 1 auto;
- min-height: 0;
- padding: 12px;
- }
- }
- .calendar-card {
- ::v-deep .el-card__body {
- display: flex;
- flex-direction: column;
- padding: 8px 10px;
- }
- }
- ::v-deep .calendar-day-tooltip {
- max-width: 310px;
- padding: 0;
- border: 1px solid #cfe0f5;
- border-radius: 8px;
- box-shadow: 0 12px 28px rgba(31, 45, 61, 0.16);
- .popper__arrow {
- border-top-color: #cfe0f5 !important;
- border-bottom-color: #cfe0f5 !important;
- }
- }
- .calendar-tooltip-content {
- min-width: 260px;
- padding: 12px 14px;
- color: #303133;
- background: linear-gradient(180deg, #ffffff 0%, #f7fbff 100%);
- border-radius: 8px;
- }
- .tooltip-head {
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: 12px;
- margin-bottom: 10px;
- padding-bottom: 8px;
- border-bottom: 1px solid #e6eef8;
- strong {
- color: #1f3d66;
- font-size: 15px;
- line-height: 20px;
- font-weight: 700;
- }
- span {
- height: 20px;
- padding: 0 8px;
- border-radius: 10px;
- background: #fff1f0;
- color: #f5222d;
- font-size: 12px;
- font-weight: 700;
- line-height: 20px;
- }
- }
- .tooltip-row {
- display: grid;
- grid-template-columns: 68px minmax(0, 1fr);
- gap: 10px;
- align-items: start;
- margin-top: 7px;
- font-size: 13px;
- line-height: 20px;
- span {
- color: #7b8794;
- }
- strong {
- color: #2f3a4a;
- font-weight: 600;
- word-break: break-all;
- }
- }
- .tooltip-stats {
- display: flex;
- gap: 8px;
- margin-top: 12px;
- span {
- padding: 3px 9px;
- border-radius: 12px;
- background: #edf5ff;
- color: #1f66c2;
- font-size: 12px;
- font-weight: 700;
- line-height: 18px;
- }
- }
- ::v-deep .calendar-day-drawer {
- display: flex;
- flex-direction: column;
- .el-drawer__header {
- flex: 0 0 auto;
- margin-bottom: 0;
- padding: 22px 24px 14px;
- border-bottom: 1px solid #e8eef7;
- color: #303133;
- font-size: 18px;
- font-weight: 600;
- background: linear-gradient(90deg, #f4f9ff, #ffffff);
- }
- .el-drawer__body {
- flex: 1 1 auto;
- min-height: 0;
- height: auto;
- overflow: hidden;
- background: #f5f7fb;
- }
- }
- .drawer-body {
- height: 100%;
- padding: 18px;
- overflow-y: auto;
- box-sizing: border-box;
- }
- .drawer-summary {
- display: grid;
- grid-template-columns: 78px 1fr;
- gap: 14px;
- margin-bottom: 18px;
- padding: 16px;
- border: 1px solid #cfe7ff;
- border-radius: 8px;
- background: linear-gradient(135deg, #f2f8ff, #ffffff 72%);
- box-shadow: 0 10px 24px rgba(64, 158, 255, 0.1);
- }
- .summary-date {
- height: 82px;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- border-radius: 8px;
- background: linear-gradient(180deg, #409eff, #1f78e8);
- text-align: center;
- box-shadow: 0 10px 20px rgba(64, 158, 255, 0.22);
- span {
- display: block;
- color: rgba(255, 255, 255, 0.86);
- font-size: 12px;
- font-weight: 600;
- }
- strong {
- display: block;
- color: #fff;
- font-size: 34px;
- line-height: 38px;
- }
- }
- .summary-info {
- flex: 1;
- min-width: 0;
- .summary-title {
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: 8px;
- color: #303133;
- font-size: 16px;
- font-weight: 600;
- }
- p {
- margin: 8px 0 10px;
- color: #606266;
- font-size: 14px;
- line-height: 20px;
- }
- }
- .summary-tags {
- display: flex;
- flex-wrap: wrap;
- gap: 6px;
- }
- .drawer-section {
- margin-bottom: 18px;
- padding: 16px;
- border: 1px solid #e4edf7;
- border-radius: 8px;
- background: #fff;
- box-shadow: 0 8px 18px rgba(31, 45, 61, 0.05);
- }
- .drawer-title {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 14px;
- span {
- position: relative;
- padding-left: 10px;
- color: #303133;
- font-size: 17px;
- font-weight: 600;
- &::before {
- content: '';
- position: absolute;
- left: 0;
- top: 3px;
- width: 3px;
- height: 15px;
- border-radius: 2px;
- background: #409eff;
- }
- }
- em {
- color: #909399;
- font-style: normal;
- font-size: 14px;
- }
- }
- .detail-timeline,
- .plan-list {
- display: flex;
- flex-direction: column;
- gap: 12px;
- }
- .detail-item {
- display: grid;
- grid-template-columns: 126px 1fr;
- gap: 12px;
- align-items: stretch;
- }
- .detail-time {
- display: flex;
- align-items: center;
- justify-content: center;
- min-height: 68px;
- padding: 10px;
- border: 1px solid #cfe7ff;
- border-radius: 8px;
- background: linear-gradient(180deg, #f3f8ff, #ffffff);
- box-sizing: border-box;
- text-align: center;
- strong {
- color: #1f4e86;
- font-size: 16px;
- line-height: 22px;
- white-space: nowrap;
- font-variant-numeric: tabular-nums;
- }
- }
- .detail-content {
- display: grid;
- grid-template-columns: minmax(0, 1fr) auto;
- align-items: center;
- gap: 12px;
- min-height: 68px;
- padding: 12px 14px;
- border: 1px solid #edf2f7;
- border-left: 4px solid #409eff;
- border-radius: 8px;
- background: linear-gradient(180deg, #ffffff, #f8fbff);
- box-sizing: border-box;
- strong,
- span {
- display: block;
- }
- strong {
- color: #303133;
- font-size: 16px;
- line-height: 22px;
- }
- span {
- margin-top: 4px;
- color: #909399;
- font-size: 14px;
- line-height: 20px;
- }
- }
- .detail-meta {
- grid-column: 1 / -1;
- display: flex;
- flex-wrap: wrap;
- gap: 6px;
- margin-top: 2px;
- span {
- margin-top: 0;
- padding: 2px 8px;
- border-radius: 10px;
- background: #eef5ff;
- color: #5b6f8f;
- font-size: 12px;
- line-height: 20px;
- &.danger {
- background: #fff1f0;
- color: #ff4d4f;
- }
- }
- }
- .drawer-empty {
- padding: 22px 0 10px;
- color: #909399;
- font-size: 14px;
- text-align: center;
- }
- .plan-empty {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 12px;
- i {
- color: #d8dee8;
- font-size: 72px;
- }
- }
- .plan-tooltip {
- max-width: 360px;
- line-height: 24px;
- color: #303133;
- word-break: break-all;
- }
- .plan-item {
- display: block;
- padding: 12px 16px;
- border: 1px solid #edf2f7;
- border-left: 4px solid #67c23a;
- border-radius: 8px;
- background: linear-gradient(180deg, #ffffff, #f8fbff);
- }
- .plan-main {
- min-width: 0;
- }
- .plan-topline {
- display: grid;
- grid-template-columns: minmax(0, 1fr) max-content;
- align-items: center;
- gap: 12px;
- margin-bottom: 6px;
- strong {
- color: #303133;
- font-size: 16px;
- line-height: 22px;
- }
- span {
- margin-top: 0;
- color: #8a97a8;
- font-size: 14px;
- line-height: 20px;
- text-align: right;
- }
- }
- .plan-name,
- .plan-metrics,
- .plan-topline strong,
- .plan-topline span {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- .plan-name {
- display: block;
- width: 100%;
- margin: 0 0 8px;
- color: #606266;
- font-size: 14px;
- line-height: 20px;
- }
- .plan-metrics {
- display: flex;
- align-items: center;
- justify-content: flex-start;
- gap: 14px;
- color: #8a97a8;
- font-size: 13px;
- line-height: 20px;
- font-variant-numeric: tabular-nums;
- em {
- font-style: normal;
- }
- }
- @keyframes conflictFlash {
- 0%,
- 100% {
- box-shadow: inset 0 0 0 1px rgba(245, 108, 108, 0.25);
- }
- 50% {
- box-shadow: inset 0 0 0 2px rgba(245, 108, 108, 0.75);
- }
- }
- .notification-card {
- .card-content {
- height: 100%;
- min-height: 0;
- display: flex;
- flex-direction: column;
- }
- ::v-deep .el-card__body {
- padding-top: 0;
- }
- ::v-deep .el-tabs__item {
- font-size: 15px;
- font-weight: bold;
- color: #333;
- }
- }
- @media (max-width: 1440px) {
- .notification-col {
- width: 50%;
- }
- .calendar-col {
- width: 50%;
- }
- .home-container {
- .work-calendar {
- .calendar-view-title {
- font-size: 16px;
- .calendar-title-tools {
- .calendar-type-switch {
- ::v-deep .el-radio-button__inner {
- height: 26px;
- padding: 6px 9px;
- font-size: 11px;
- line-height: 12px;
- }
- }
- }
- }
- .calendar-cell {
- min-height: 92px;
- padding: 6px 7px 6px 9px;
- }
- }
- }
- }
- @media (max-width: 1200px) {
- .home-container {
- .work-calendar {
- .calendar-view-title {
- gap: 6px;
- }
- .calendar-title-tools {
- justify-content: flex-end;
- .calendar-type-switch {
- ::v-deep .el-radio-button__inner {
- padding: 6px 7px;
- }
- }
- }
- .calendar-week span {
- height: 28px;
- line-height: 28px;
- }
- .calendar-cell {
- min-height: 90px;
- padding: 6px 6px 6px 8px;
- }
- }
- }
- }
- @media (max-width: 768px) {
- ::v-deep .calendar-day-drawer {
- width: 92% !important;
- }
- .drawer-summary,
- .detail-item {
- grid-template-columns: 1fr;
- }
- }
- /* 通知公告样式 */
- .notification-list {
- // margin-top: 16px;
- flex: 1 1 auto;
- min-height: 0;
- overflow-y: auto;
- overflow-x: hidden;
- padding-right: 8px;
- &::-webkit-scrollbar {
- width: 6px;
- }
- &::-webkit-scrollbar-track {
- background: #f1f1f1;
- border-radius: 3px;
- }
- &::-webkit-scrollbar-thumb {
- background: #c1c1c1;
- border-radius: 3px;
- }
- &::-webkit-scrollbar-thumb:hover {
- background: #a8a8a8;
- }
- }
- .notification-item {
- display: flex;
- align-items: center;
- padding: 12px 0;
- border-bottom: 1px solid #f0f0f0;
- &:last-child {
- border-bottom: none;
- }
- }
- .notification-dot {
- width: 10px;
- height: 10px;
- background-color: #a6ccff;
- border-radius: 50%;
- margin-right: 12px;
- margin-top: 5px;
- flex-shrink: 0;
- }
- .notification-content {
- flex: 1;
- min-width: 0;
- cursor: pointer;
- color: #333;
- &:hover {
- color: #1890ff;
- }
- }
- .notification-header {
- display: flex;
- align-items: center;
- margin-bottom: 4px;
- }
- .notification-title {
- font-size: 15px;
- font-weight: 500;
- // color: #333;
- margin-right: 12px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- flex-shrink: 1;
- max-width: 200px;
- }
- .notification-info {
- font-size: 12px;
- // color: #333;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- .notification-text {
- font-size: 14px;
- // color: #333;
- line-height: 1.4;
- flex: 1;
- min-width: 0;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- .notification-images {
- margin-top: 8px;
- }
- .image-url {
- font-size: 12px;
- color: #1890ff;
- cursor: pointer;
- margin-bottom: 4px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- &:hover {
- text-decoration: underline;
- }
- }
- .notification-date {
- font-size: 13px;
- // color: #333;
- margin-left: 12px;
- flex-shrink: 0;
- }
- .notification-more {
- text-align: right;
- margin-top: 12px;
- font-size: 15px;
- color: #1890ff;
- cursor: pointer;
- &:hover {
- text-decoration: underline;
- }
- }
- </style>
- <style lang="scss">
- body .calendar-day-tooltip {
- max-width: min(360px, calc(100vw - 32px));
- max-height: calc(100vh - 32px);
- padding: 0;
- border: 1px solid #d8e6f7;
- border-radius: 8px;
- box-shadow: 0 16px 36px rgba(31, 45, 61, 0.18);
- overflow: auto;
- .popper__arrow {
- border-top-color: #d8e6f7 !important;
- border-bottom-color: #d8e6f7 !important;
- }
- }
- body .calendar-day-tooltip .calendar-tooltip-content {
- min-width: 270px;
- max-width: 340px;
- padding: 12px 14px;
- color: #303133;
- background: linear-gradient(180deg, #ffffff 0%, #f7fbff 100%);
- border-radius: 8px;
- }
- body .calendar-day-tooltip .tooltip-head {
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: 12px;
- margin-bottom: 10px;
- padding-bottom: 8px;
- border-bottom: 1px solid #e6eef8;
- strong {
- color: #1f3d66;
- font-size: 15px;
- line-height: 20px;
- font-weight: 700;
- }
- span {
- height: 20px;
- padding: 0 8px;
- border-radius: 10px;
- background: #fff1f0;
- color: #f5222d;
- font-size: 12px;
- font-weight: 700;
- line-height: 20px;
- }
- }
- body .calendar-day-tooltip .tooltip-row {
- display: grid;
- grid-template-columns: 72px minmax(0, 1fr);
- gap: 10px;
- align-items: start;
- margin-top: 7px;
- padding: 6px 8px;
- border-radius: 6px;
- background: rgba(236, 246, 255, 0.68);
- font-size: 13px;
- line-height: 20px;
- span {
- color: #7b8794;
- }
- strong {
- color: #2f3a4a;
- font-weight: 600;
- word-break: break-word;
- }
- }
- body .calendar-day-tooltip .tooltip-stats {
- display: flex;
- flex-wrap: wrap;
- gap: 8px;
- margin-top: 12px;
- span {
- padding: 3px 9px;
- border-radius: 12px;
- background: #edf5ff;
- color: #1f66c2;
- font-size: 12px;
- font-weight: 700;
- line-height: 18px;
- }
- }
- </style>
|