12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207 |
- <!-- <?xml version="1.0" encoding="UTF-8"?> -->
- <template>
- <div class="app-container">
- <!-- 搜索栏 -->
- <el-form
- :model="queryParams"
- ref="queryForm"
- :inline="true"
- class="demo-form-inline"
- >
- <el-form-item>
- <el-input
- v-model="queryParams.orderNo"
- placeholder="服务单号"
- clearable
- size="small"
- style="width: 150px"
- />
- </el-form-item>
- <el-form-item>
- <el-input
- v-model="queryParams.contractNo"
- placeholder="合同单号"
- clearable
- size="small"
- style="width: 150px"
- />
- </el-form-item>
- <el-form-item>
- <el-input
- v-model="queryParams.deliveryNo"
- placeholder="发货单号"
- clearable
- size="small"
- style="width: 150px"
- />
- </el-form-item>
- <el-form-item>
- <el-select
- v-model="queryParams.serviceStaffIds"
- placeholder="服务人员"
- clearable
- filterable
- size="small"
- style="width: 120px"
- >
- <el-option
- v-for="item in installerOptions"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-input
- v-model="queryParams.customerName"
- placeholder="客户名称"
- clearable
- size="small"
- style="width: 120px"
- />
- </el-form-item>
- <el-form-item>
- <el-select
- v-model="queryParams.statusName"
- placeholder="处理状态"
- clearable
- size="small"
- style="width: 120px"
- >
- <el-option
- v-for="dict in statusOptions"
- :key="dict.value"
- :label="dict.label"
- :value="dict.value"
- />
- </el-select>
- </el-form-item>
- <el-form-item>
- <!-- <el-select
- v-model="queryParams.projectId"
- placeholder="项目名称"
- clearable
- size="small"
- style="width: 120px"
- >
- <el-option
- v-for="dict in projectOptions"
- :key="dict.id"
- :label="dict.name"
- :value="dict.id"
- />
- </el-select> -->
- </el-form-item>
- <el-form-item>
- <el-date-picker
- v-model="queryParams.orderTimeRange"
- class="inputDatetime"
- type="daterange"
- size="small"
- range-separator="至"
- start-placeholder="下单开始日期"
- end-placeholder="下单结束日期"
- style="width: 250px"
- />
- </el-form-item>
- <el-form-item>
- <el-date-picker
- v-model="queryParams.completeTimeRange"
- class="inputDatetime"
- type="daterange"
- size="small"
- range-separator="至"
- start-placeholder="完成开始日期"
- end-placeholder="完成结束日期"
- style="width: 250px"
- />
- </el-form-item>
- <div style="width: 100%"></div>
- <el-form-item>
- <el-button
- size="small"
- class="successBorder"
- icon="el-icon-search"
- @click="handleQuery"
- >搜索</el-button
- >
- <el-button
- size="small"
- class="successBorder"
- icon="el-icon-download"
- @click="onExportClick"
- v-if="
- checkButtonPermission('productManagement:installationOrder:export')
- "
- >导出</el-button
- >
- <el-button
- size="small"
- type="primary"
- icon="el-icon-plus"
- @click="handleAdd"
- v-if="
- checkButtonPermission('productManagement:installationOrder:add')
- "
- >新增计划</el-button
- >
- <el-radio-group
- v-model="queryParams.viewType"
- size="small"
- @change="handleViewTypeChange"
- style="margin-left: 8px"
- >
- <el-radio-button label="">全部</el-radio-button>
- <el-radio-button label="未接单"
- >未接单<el-badge
- v-if="pendingCount > 0"
- :value="pendingCount"
- class="pending-badge"
- /></el-radio-button>
- <el-radio-button label="已完成">已完成</el-radio-button>
- </el-radio-group>
- </el-form-item>
- </el-form>
- <!-- 表格 -->
- <el-table
- v-loading="loading"
- element-loading-text="数据加载中..."
- element-loading-spinner="el-icon-loading"
- element-loading-background="rgba(255, 255, 255, 0.8)"
- :data="tableData"
- border
- style="width: 100%; margin-top: 15px"
- :empty-text="'暂无数据'"
- :header-cell-style="{ background: '#f5f7fa' }"
- @row-dblclick="handleView"
- height="calc(100vh - 250px)"
- :row-class-name="tableRowClassName"
- >
- <el-table-column label="序号" width="50" align="center">
- <template slot-scope="scope">
- {{
- (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1
- }}
- </template>
- </el-table-column>
- <el-table-column prop="orderNo" label="服务单号" align="center">
- <template slot-scope="scope">
- <el-link
- type="primary"
- :underline="false"
- class="order-no-link"
- @click="handleView(scope.row)"
- >
- {{ scope.row.orderNo }}
- </el-link>
- </template>
- </el-table-column>
- <!-- <el-table-column prop="projectName" label="项目名称" align="center" /> -->
- <el-table-column
- prop="statusName"
- label="处理状态"
- align="center"
- width="100"
- >
- <template slot-scope="scope">
- <el-tag :type="getStatusType(scope.row.statusName)">{{
- scope.row.statusName
- }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column
- prop="customerName"
- label="客户名称"
- align="center"
- width="120"
- />
- <el-table-column prop="goodsName" label="货品" align="center" width="150">
- <template slot-scope="scope">
- <div class="product-tags">
- <template v-if="scope.row.goodsName">
- <el-tag
- v-for="(item, index) in scope.row.goodsName.split(',')"
- :key="index"
- size="mini"
- :type="['success', 'warning', 'danger', 'primary'][index % 4]"
- effect="light"
- :class="{ 'long-text': item.length > 10 }"
- >
- {{ item }}
- </el-tag>
- </template>
- </div>
- </template>
- </el-table-column>
- <el-table-column
- prop="progress"
- label="服务进度"
- align="center"
- width="250"
- >
- <template slot-scope="scope">
- <div
- class="progress-wrapper"
- @mouseenter="
- showProgressTooltip($event, parseInt(scope.row.progress))
- "
- @mouseleave="hideProgressTooltip"
- >
- <div class="progress-container">
- <div class="progress-bar">
- <div class="custom-progress">
- <div
- class="progress-inner"
- :style="{
- width:
- scope.row.progress > 0
- ? parseInt(scope.row.progress) + '%'
- : '2px',
- backgroundColor: getProgressBarColor(
- scope.row.statusName
- ),
- }"
- >
- <span class="progress-text" v-if="scope.row.progress > 0">
- {{ parseInt(scope.row.progress) }}%
- </span>
- </div>
- </div>
- </div>
- </div>
- </div>
- </template>
- </el-table-column>
- <el-table-column
- prop="totalQuantity"
- label="计划总量"
- align="center"
- width="100"
- />
- <el-table-column
- prop="installedQuantity"
- label="已完成量"
- align="center"
- width="100"
- />
- <el-table-column
- prop="uninstalledQuantity"
- label="未完成量"
- align="center"
- width="100"
- />
- <!-- <el-table-column
- prop="dispatcherName"
- label="派单人"
- align="center"
- width="100"
- /> -->
- <el-table-column
- prop="serviceStaffNames"
- label="服务人员"
- align="center"
- width="120"
- >
- <template slot-scope="scope">
- <div class="staff-tags">
- <template v-if="scope.row.serviceStaffNames">
- <el-tag
- v-for="(item, index) in scope.row.serviceStaffNames.split(',')"
- :key="index"
- size="mini"
- :type="['primary', 'success', 'warning', 'danger'][index % 4]"
- effect="light"
- :class="{ 'long-text': item.length > 10 }"
- >
- {{ item }}
- </el-tag>
- </template>
- </div>
- </template>
- </el-table-column>
- <el-table-column
- prop="createName"
- label="下单人"
- align="center"
- width="100"
- />
- <el-table-column
- prop="orderTime"
- label="下单时间"
- align="center"
- width="140"
- />
- <el-table-column
- prop="acceptTime"
- label="接单时间"
- align="center"
- width="140"
- />
- <el-table-column
- prop="estimatedCompleteTime"
- label="预估完成时间"
- align="center"
- width="140"
- />
- <el-table-column
- prop="remainingTime"
- label="距预估完成时间还剩"
- align="center"
- width="160"
- >
- <template slot-scope="scope">
- <template
- v-if="
- scope.row.remainingTime !== null &&
- scope.row.remainingTime !== undefined
- "
- >
- <span
- :class="{
- 'normal-time': scope.row.remainingTime > 3,
- 'warning-time':
- scope.row.remainingTime >= 0 && scope.row.remainingTime <= 3,
- 'overdue-time': scope.row.remainingTime < 0,
- }"
- >
- <template v-if="scope.row.remainingTime < 0">
- 已逾期 {{ Math.abs(scope.row.remainingTime) }} 天
- </template>
- <template v-else> {{ scope.row.remainingTime }} 天 </template>
- </span>
- </template>
- </template>
- </el-table-column>
- <el-table-column
- prop="actualCompleteTime"
- label="实际完成时间"
- align="center"
- width="140"
- />
- <el-table-column
- prop="remark"
- label="备注"
- align="center"
- min-width="120"
- />
- <el-table-column label="操作" align="center" width="220" fixed="right">
- <template slot-scope="scope">
- <el-button
- size="mini"
- type="primary"
- @click="handleView(scope.row)"
- v-if="
- getButtonVisible(
- {
- permission: 'productManagement:installationOrder:view',
- type: 'view',
- },
- scope.row
- )
- "
- >查看</el-button
- >
- <el-button
- size="mini"
- type="primary"
- @click="handleEdit(scope.row)"
- v-if="
- getButtonVisible(
- {
- permission: 'productManagement:installationOrder:edit',
- type: 'edit',
- },
- scope.row
- )
- "
- >编辑</el-button
- >
- <el-button
- size="mini"
- type="danger"
- @click="handleDelete(scope.row)"
- v-if="
- getButtonVisible(
- {
- permission: 'productManagement:installationOrder:delete',
- type: 'delete',
- },
- scope.row
- )
- "
- >删除</el-button
- >
- <el-button
- size="mini"
- type="success"
- @click="handleDispatch(scope.row)"
- v-if="
- getButtonVisible(
- {
- permission: 'productManagement:installationOrder:dispatch',
- type: 'dispatch',
- },
- scope.row
- )
- "
- >派单</el-button
- >
- <el-button
- size="mini"
- style="
- background-color: #e74c3c;
- border-color: #e74c3c;
- color: #fff;
- "
- @click="handleReject(scope.row)"
- v-if="
- getButtonVisible(
- {
- permission: 'productManagement:installationOrder:reject',
- type: 'reject',
- },
- scope.row
- )
- "
- >驳回</el-button
- >
- <el-button
- size="mini"
- style="
- background-color: #f39c12;
- border-color: #f39c12;
- color: #fff;
- "
- @click="handleAccept(scope.row)"
- v-if="
- getButtonVisible(
- {
- permission: 'productManagement:installationOrder:accept',
- type: 'accept',
- },
- scope.row
- )
- "
- >接单</el-button
- >
- <el-button
- size="mini"
- style="
- background-color: #409eff;
- border-color: #409eff;
- color: #fff;
- "
- @click="handleDailyWrite(scope.row)"
- v-if="
- getButtonVisible(
- {
- permission: 'productManagement:installationOrder:dailyWrite',
- type: 'write',
- },
- scope.row
- )
- "
- >填写</el-button
- >
- <el-button
- size="mini"
- type="success"
- @click="handleComplete(scope.row)"
- v-if="
- getButtonVisible(
- {
- permission: 'productManagement:installationOrder:complete',
- type: 'complete',
- },
- scope.row
- )
- "
- >完成</el-button
- >
- <el-button
- size="mini"
- type="warning"
- @click="handleCheck(scope.row)"
- v-if="
- getButtonVisible(
- {
- permission: 'productManagement:installationOrder:check',
- type: 'check',
- },
- scope.row
- )
- "
- >验收</el-button
- >
- </template>
- </el-table-column>
- </el-table>
- <!-- 分页 -->
- <pagination
- :total="total"
- :page.sync="queryParams.pageNum"
- :limit.sync="queryParams.pageSize"
- :page-sizes="[10, 20, 30, 50]"
- @pagination="getList"
- />
- <!-- 新增服务计划弹窗
- 传递 installerOptions 给下单人和服务人员选择器
- 传递 projectOptions 给服务项目选择器
- 传递 currentUser 给下单人选择器-->
- <add-dialog
- :visible.sync="dialogVisible"
- :installer-options="installerOptions"
- :project-options="projectOptions"
- :current-user="currentUser"
- @success="getList"
- />
- <!-- 编辑弹窗 -->
- <edit-dialog
- :visible.sync="editDialogVisible"
- :installer-options="installerOptions"
- :project-options="projectOptions"
- :current-user="currentUser"
- :row-data="currentRow"
- @success="handleEditSuccess"
- />
- <!-- 查看弹窗 -->
- <view-dialog
- :visible.sync="viewDialogVisible"
- :installer-options="installerOptions"
- :project-options="projectOptions"
- :row-data="currentRow"
- :check-button-permission="checkButtonPermission"
- :is-current-user-in-service-staff="isCurrentUserInServiceStaff"
- @reject="() => (rejectDialogVisible = true)"
- @accept="() => (acceptDialogVisible = true)"
- />
- <!-- 派单弹窗 -->
- <dispatch-dialog
- :visible.sync="dispatchDialogVisible"
- :installer-options="installerOptions"
- :current-user="currentUser"
- :row-data="currentRow"
- @success="getList"
- />
- <!-- 驳回弹窗 -->
- <reject-dialog
- :visible.sync="rejectDialogVisible"
- :row-data="currentRow"
- @confirm="handleRejectConfirm"
- />
- <!-- 填写弹窗 -->
- <daily-write-dialog
- :visible.sync="dailyWriteDialogVisible"
- :row-data="currentRow"
- :current-user="currentUser"
- @confirm="handleDailyWriteConfirm"
- />
- <!-- 接单弹窗 -->
- <accept-dialog
- :visible.sync="acceptDialogVisible"
- :row-data="currentRow"
- :current-user="currentUser"
- @confirm="handleAcceptConfirm"
- />
- <!-- 验收弹窗 -->
- <check-dialog
- :visible.sync="checkDialogVisible"
- :row-data="currentRow"
- :installer-options="installerOptions"
- @confirm="handleCheckConfirm"
- :customer-contact-options="customerContactOptions"
- :current-user="currentUser"
- />
- </div>
- </template>
- <script>
- import Pagination from "@/components/Pagination";
- import {
- GetDataByName,
- GetDataByNames,
- PostDataByName,
- ExecDataByConfig,
- } from "@/api/common";
- import AddDialog from "./components/AddDialog";
- import exportMixin from "@/mixins/exportMixin";
- import paramsMixin from "./mixins/paramsMixin";
- import { exportInstallationOrder } from "@/api/productManagement/installation";
- import Cookies from "js-cookie";
- import EditDialog from "./components/EditDialog.vue";
- import ViewDialog from "./components/ViewDialog.vue";
- import DispatchDialog from "./components/DispatchDialog.vue";
- import RejectDialog from "./components/RejectDialog.vue";
- import DailyWriteDialog from "./components/DailyWriteDialog.vue";
- import AcceptDialog from "./components/AcceptDialog.vue";
- import CheckDialog from "./components/CheckDialog.vue";
- import * as XLSX from "xlsx";
- export default {
- name: "InstallationOrder",
- components: {
- Pagination,
- AddDialog,
- EditDialog,
- ViewDialog,
- DispatchDialog,
- RejectDialog,
- DailyWriteDialog,
- AcceptDialog,
- CheckDialog,
- },
- mounted() {
- // 打印整个路由对象,看看具体结构
- console.log("路由信息:", this.$route);
- this.buttonMenu = JSON.parse(sessionStorage.getItem("buttons"));
- const menuId = this.$route.query.menuId;
- if (menuId) {
- this.currentMenuId = parseInt(menuId);
- } else {
- console.log("没有获取到菜单ID");
- }
- },
- mixins: [exportMixin, paramsMixin],
- data() {
- return {
- // 表格高度
- tableHeight: window.innerHeight - 300,
- // 遮罩层
- loading: false,
- // 总条数
- total: 0,
- // 表格数据
- tableData: [],
- // 当前菜单ID
- currentMenuId: 0,
- // 按钮菜单
- buttonMenu: [],
- // 服务人员选项
- installerOptions: [],
- // 客户联系人选项
- customerContactOptions: [],
- // 查询参数
- queryParams: {
- pageNum: 1,
- pageSize: 10,
- serviceStaffIds: "",
- customerName: "",
- statusName: "",
- projectName: "",
- projectId: "",
- orderTimeRange: [],
- completeTimeRange: [],
- viewType: "",
- orderNo: "",
- deliveryNo: "",
- contractNo: "",
- userId: Cookies.get("g_userId") || "",
- roleId: Cookies.get("g_roleId") || "",
- },
- // 状态选项
- statusOptions: [
- { label: "未接单", value: "未接单" },
- { label: "已接单", value: "已接单" },
- { label: "处理中", value: "处理中" },
- { label: "已完成未验收", value: "已完成未验收" },
- { label: "已完成", value: "已完成" },
- { label: "接单驳回", value: "接单驳回" },
- ],
- // 项目选项
- projectOptions: [],
- // 日期选择器快捷选项
- pickerOptions: {
- shortcuts: [
- {
- text: "最近一周",
- onClick(picker) {
- const end = new Date();
- const start = new Date();
- start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
- picker.$emit("pick", [start, end]);
- },
- },
- {
- text: "最近一个月",
- onClick(picker) {
- const end = new Date();
- const start = new Date();
- start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
- picker.$emit("pick", [start, end]);
- },
- },
- {
- text: "最近三个月",
- onClick(picker) {
- const end = new Date();
- const start = new Date();
- start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
- picker.$emit("pick", [start, end]);
- },
- },
- ],
- },
- pendingCount: 0,
- // 弹窗显示控制
- dialogVisible: false,
- // 当前用户信息
- currentUser: {
- id: Cookies.get("g_userId") || "",
- name: Cookies.get("g_empname") || "",
- roleId: Cookies.get("g_roleId") || "",
- },
- editDialogVisible: false,
- viewDialogVisible: false,
- currentRow: {},
- progressTooltip: null,
- dispatchDialogVisible: false,
- rejectDialogVisible: false,
- dailyWriteDialogVisible: false,
- acceptDialogVisible: false,
- checkDialogVisible: false,
- };
- },
- created() {
- this.getList();
- this.getSelectOptions();
- // 添加resize事件监听
- this.resizeHandler = this.debounce(() => {
- this.tableHeight = window.innerHeight - 300;
- }, 100);
- window.addEventListener("resize", this.resizeHandler);
- },
- beforeDestroy() {
- // 移除resize事件监听
- window.removeEventListener("resize", this.resizeHandler);
- this.hideProgressTooltip();
- },
- methods: {
- // 添加防抖函数
- debounce(fn, delay) {
- let timer = null;
- return function () {
- const context = this;
- const args = arguments;
- clearTimeout(timer);
- timer = setTimeout(() => {
- fn.apply(context, args);
- }, delay);
- };
- },
- // 获取列表数据
- getList() {
- this.loading = true;
- // 使用参数处理混入方法
- const send_data = [
- this.handleParams(this.queryParams, "getInstallationOrderList"),
- {
- name: "getInstallationOrderToDoNum",
- offset: 0,
- pagecount: 0,
- parammaps: {
- userId: this.currentUser.id,
- roleId: this.currentUser.roleId,
- },
- },
- ];
- GetDataByNames(send_data)
- .then((response) => {
- this.tableData = response.data.getInstallationOrderList.list || [];
- this.total = response.data.getInstallationOrderList.total || 0;
- // 获取处理工单数量
- this.pendingCount =
- response.data.getInstallationOrderToDoNum.list[0].num;
- this.loading = false;
- })
- .catch((error) => {
- console.error("获取服务工单列表失败:", error);
- this.loading = false;
- });
- },
- // 获取下拉框选项数据
- getSelectOptions() {
- const send_select_list = [
- {
- name: "getUsersSelect",
- offset: 0,
- pagecount: 0,
- parammaps: {
- enable: "1",
- },
- },
- {
- name: "getDictListSelect",
- offset: 0,
- pagecount: 0,
- parammaps: {
- pid: "79",
- },
- },
- ];
- GetDataByNames(send_select_list)
- .then((response) => {
- // 处理服务人员数据
- const installerList = response.data.getUsersSelect.list || [];
- this.installerOptions = installerList.map((item) => ({
- value: item.id,
- label: item.name,
- }));
- console.log("服务人员下拉框", this.installerOptions);
- // 处理项目数据
- this.projectOptions = response.data.getDictListSelect.list || [];
- console.log("项目下拉框", this.projectOptions);
- })
- .catch((error) => {
- console.error("获取下拉框数据失败:", error);
- });
- },
- handleQuery() {
- this.queryParams.pageNum = 1;
- this.getList();
- },
- // 获取格式化的日期时间
- getFormattedDateTime() {
- const now = new Date();
- const year = now.getFullYear();
- const month = String(now.getMonth() + 1).padStart(2, "0");
- const day = String(now.getDate()).padStart(2, "0");
- const hours = String(now.getHours()).padStart(2, "0");
- const minutes = String(now.getMinutes()).padStart(2, "0");
- const seconds = String(now.getSeconds()).padStart(2, "0");
- return `${year}${month}${day}${hours}${minutes}${seconds}`;
- },
- // 导出功能
- async onExportClick() {
- try {
- // 使用现有的查询参数,但不分页
- const exportParams = {
- name: "getInstallationOrderList",
- returntype: "Map",
- parammaps: {},
- };
- const response = await GetDataByName(exportParams);
- if (response.msg !== "ok") {
- this.$message.error("获取导出数据失败");
- return;
- }
- const data = response.data.list || [];
- if (data.length === 0) {
- this.$message.warning("暂无数据可导出");
- return;
- }
- // 定义表头
- const headers = [
- "序号",
- "服务单号",
- "下单人",
- "下单时间",
- "服务人员",
- "接单时间",
- "客户",
- "发货单号",
- "合同",
- "货品名称",
- "计划总量",
- "已完成量",
- "未完成量",
- "预计完成时间",
- "实际完成时间",
- "距预估完成时间",
- "安装进度",
- "派单人",
- "客户联系人",
- "客户联系人电话",
- "备注",
- ];
- // 格式化数据
- const rows = data.map((item, index) => [
- index + 1,
- item.orderNo || "",
- item.createName || "",
- item.orderTime || "",
- item.serviceStaffNames || "",
- item.acceptTime || "",
- item.customerName || "",
- item.deliveryNo || "",
- item.contractNo || "",
- item.goodsName || "",
- item.totalQuantity || "",
- item.installedQuantity || "",
- item.uninstalledQuantity || "",
- item.estimatedCompleteTime || "",
- item.actualCompleteTime || "",
- item.remainingTime !== null && item.remainingTime !== undefined
- ? item.remainingTime < 0
- ? `已逾期 ${Math.abs(item.remainingTime)} 天`
- : `${item.remainingTime} 天`
- : "",
- item.progress ? `${item.progress}%` : "0%",
- item.dispatcherName || "",
- item.contactName || "",
- item.contactPhone || "",
- item.remark || "",
- ]);
- // 创建工作簿
- const wb = XLSX.utils.book_new();
- // 组合表头和数据
- const wsData = [headers, ...rows];
- // 创建工作表
- const ws = XLSX.utils.aoa_to_sheet(wsData);
- // 设置列宽
- const colWidths = [
- { wch: 8 }, // 序号
- { wch: 15 }, // 服务单号
- { wch: 12 }, // 下单人
- { wch: 20 }, // 下单时间
- { wch: 15 }, // 服务项目
- { wch: 20 }, // 服务人员
- { wch: 20 }, // 接单时间
- { wch: 20 }, // 客户
- { wch: 15 }, // 发货单号
- { wch: 15 }, // 合同
- { wch: 30 }, // 货品名称
- { wch: 12 }, // 计划总量
- { wch: 12 }, // 已完成量
- { wch: 12 }, // 未完成量
- { wch: 20 }, // 预计完成时间
- { wch: 20 }, // 实际完成时间
- { wch: 20 }, // 距预估完成时间
- { wch: 12 }, // 安装进度
- { wch: 12 }, // 派单人
- { wch: 15 }, // 客户联系人
- { wch: 15 }, // 客户联系人电话
- { wch: 30 }, // 备注
- ];
- ws["!cols"] = colWidths;
- // 添加工作表到工作簿
- XLSX.utils.book_append_sheet(wb, ws, "服务工单列表");
- // 生成文件名
- const fileName = `服务工单列表_${this.getFormattedDateTime()}.xlsx`;
- // 导出文件
- XLSX.writeFile(wb, fileName);
- this.$message.success("导出成功");
- } catch (error) {
- console.error("导出失败:", error);
- this.$message.error("导出失败");
- }
- },
- handleAdd() {
- this.dialogVisible = true;
- },
- handleViewTypeChange(value) {
- this.queryParams.statusName = value;
- this.queryParams.serviceStaffIds = "";
- this.queryParams.customerName = "";
- this.queryParams.projectName = "";
- this.queryParams.projectId = "";
- this.queryParams.orderTimeRange = [];
- this.queryParams.completeTimeRange = [];
- this.queryParams.orderNo = "";
- this.queryParams.deliveryNo = "";
- this.queryParams.contractNo = "";
- this.getList();
- },
- getStatusType(statusName) {
- const statusMap = {
- 未接单: "info",
- 已接单: "primary",
- 处理中: "primary",
- 已完成: "success",
- 已完成未验收: "warning",
- 接单驳回: "danger",
- };
- return statusMap[statusName] || "info";
- },
- handleView(row) {
- this.currentRow = row;
- this.viewDialogVisible = true;
- },
- // 处理编辑按钮点击
- handleEdit(row) {
- this.currentRow = row;
- this.editDialogVisible = true;
- },
- // 删除
- async handleDelete(row) {
- await this.$confirm("是否确认删除服务工单?", "警告", {
- type: "warning",
- });
- try {
- const params = {
- common: {
- returnmap: "0",
- },
- data: [
- {
- name: "deleteInstallationOrderById",
- type: "e",
- parammaps: {
- orderId: row.id,
- },
- }, // 在 handleDelete 方法的 params.data 数组中添加:
- {
- name: "insertInstallationOrderProcessLog",
- type: "e",
- parammaps: {
- orderId: row.id,
- operationType: "delete",
- operationUserId: this.currentUser.id,
- operationUserName: this.currentUser.name,
- beforeStatus: row.statusName,
- afterStatus: row.statusName,
- operationContent: "删除服务工单",
- },
- },
- ],
- };
- const response = await ExecDataByConfig(params);
- if (response.msg === "ok") {
- this.$message.success("删除成功");
- this.getList();
- } else {
- this.$message.error(response.msg || "删除失败");
- }
- } catch (error) {
- console.error("删除失败:", error);
- this.$message.error("删除失败");
- }
- },
- // 派单
- async handleDispatch(row) {
- if (!row.estimatedCompleteTime) {
- this.$message.error("当前工单没有预计完成时间,无法派单,请编辑工单");
- return;
- }
- this.currentRow = row;
- this.dispatchDialogVisible = true;
- },
- // 驳回
- async handleReject(row) {
- this.currentRow = row;
- this.rejectDialogVisible = true;
- },
- // 接单
- async handleAccept(row) {
- this.currentRow = row;
- this.acceptDialogVisible = true;
- },
- // 每日填写
- async handleDailyWrite(row) {
- this.currentRow = row;
- this.dailyWriteDialogVisible = true;
- },
- // 处理填写确认
- async handleDailyWriteConfirm(formData) {
- try {
- const params = {
- common: {
- returnmap: "0",
- },
- data: [
- {
- name: "deleteInstallationDailyWriteByDates",
- type: "e",
- parammaps: {
- datas: formData.dates.join(","),
- userId: this.currentUser.id,
- orderId: this.currentRow.id,
- },
- },
- {
- name: "submitInstallationDailyWrite",
- resultmaps: {
- list: formData.records.map((item) => ({
- installDate: this.formatDate(item.date),
- goodsName: item.goodsName,
- goodsId: item.goodsId,
- todayQuantity: item.todayQuantity || 0,
- remark: item.installRemark,
- projectId: item.projectId,
- projectName: item.projectName,
- })),
- },
- children: [
- {
- name: "insertInstallationDailyWrite",
- type: "e",
- parammaps: {
- orderId: this.currentRow.id,
- installUserId: this.currentUser.id,
- installUserName: this.currentUser.name,
- goodsName: "@submitInstallationDailyWrite.goodsName",
- installDate: "@submitInstallationDailyWrite.installDate",
- goodsId: "@submitInstallationDailyWrite.goodsId",
- todayQuantity:
- "@submitInstallationDailyWrite.todayQuantity",
- remark: "@submitInstallationDailyWrite.remark",
- projectId: "@submitInstallationDailyWrite.projectId",
- projectName: "@submitInstallationDailyWrite.projectName",
- },
- },
- ],
- },
- {
- name: "refreshInstallationOrderDetailQuantity",
- type: "e",
- parammaps: {
- orderId: this.currentRow.id,
- },
- },
- {
- name: "refreshInstallationOrderProcessByOrderId",
- type: "e",
- parammaps: {
- orderId: this.currentRow.id,
- },
- },
- {
- name: "updateDailyDetailYesterdayAndBeforeQuantity",
- type: "e",
- parammaps: {
- orderId: this.currentRow.id,
- },
- }, // 在 handleDailyWriteConfirm 方法的 params.data 数组中添加:
- {
- name: "insertInstallationOrderProcessLog",
- type: "e",
- parammaps: {
- orderId: this.currentRow.id,
- operationType: "write",
- operationUserId: this.currentUser.id,
- operationUserName: this.currentUser.name,
- beforeStatus: this.currentRow.statusName,
- afterStatus: this.currentRow.statusName,
- operationContent: `填写日期:${formData.dates.join(
- ","
- )}|产品名称:${formData.records
- .map((item) => item.goodsName)
- .join(",")}|数量:${formData.records.reduce(
- (sum, item) => sum + (parseInt(item.todayQuantity) || 0),
- 0
- )}`,
- },
- },
- ],
- };
- const response = await ExecDataByConfig(params);
- if (response.msg === "ok") {
- this.$message.success("提交成功");
- this.dailyWriteDialogVisible = false;
- this.getList();
- } else {
- this.$message.error(response.msg || "提交失败");
- }
- } catch (error) {
- console.error("提交失败:", error);
- this.$message.error("提交失败");
- }
- },
- // 完成
- async handleComplete(row) {
- await this.$confirm("是否确认完成当前服务工单?", "警告", {
- type: "warning",
- });
- try {
- const params = {
- common: {
- returnmap: "0",
- },
- data: [
- {
- name: "completeInstallationOrder",
- type: "e",
- parammaps: {
- orderId: row.id,
- },
- }, // 在 handleComplete 方法的 params.data 数组中添加:
- {
- name: "insertInstallationOrderProcessLog",
- type: "e",
- parammaps: {
- orderId: row.id,
- operationType: "complete",
- operationUserId: this.currentUser.id,
- operationUserName: this.currentUser.name,
- beforeStatus: row.statusName,
- afterStatus: "已完成未验收",
- operationContent: "完成服务工单",
- },
- },
- ],
- };
- const response = await ExecDataByConfig(params);
- if (response.msg === "ok") {
- this.$message.success("操作成功");
- this.getList();
- } else {
- this.$message.error(response.msg || "操作失败");
- }
- } catch (error) {
- console.error("操作失败:", error);
- this.$message.error("操作失败");
- }
- },
- // 验收-获取客户联系人
- async handleCheck(row) {
- this.currentRow = row;
- this.checkDialogVisible = true;
- const send_data = {
- name: "getContacts",
- returntype: "Map",
- parammaps: {
- customerId: row.customerId,
- },
- };
- GetDataByName(send_data)
- .then((response) => {
- this.customerContactOptions = response.data.list || [];
- console.log("客户联系人选项", this.customerContactOptions);
- })
- .catch((error) => {
- console.error("获取客户联系人选项失败:", error);
- });
- },
- // 处理验收确认
- async handleCheckConfirm(formData) {
- try {
- const params = {
- common: {
- returnmap: "0",
- },
- data: [],
- };
- if (formData.isNewContact) {
- params.data.push({
- name: "insertContacts",
- type: "e",
- parammaps: {
- customerId: this.currentRow.customerId,
- contactName: formData.customContact,
- telephone: formData.telephone,
- },
- });
- }
- // 处理验收图片
- if (formData.checkImage.length > 0) {
- params.data.push({
- name: "insertInstallationOrderImages",
- resultmaps: {
- list: formData.checkImage.map((item, index) => ({
- imageId: item,
- imageType: "check_image",
- })),
- },
- children: [
- {
- name: "insertInstallationOrderImages",
- type: "e",
- parammaps: {
- orderId: this.currentRow.id,
- imageId: "@insertInstallationOrderImages.imageId",
- imageType: "@insertInstallationOrderImages.imageType",
- },
- },
- ],
- });
- }
- params.data.push(
- {
- name: "checkInstallationOrder",
- type: "e",
- parammaps: {
- orderId: formData.orderId,
- checkUserId: formData.serviceStaffId,
- checkUserName:
- this.installerOptions.find(
- (item) => item.id === formData.serviceStaffId
- )?.label || "",
- contactId: formData.isNewContact
- ? "@insertContacts.LastInsertId"
- : formData.customContact,
- checkDate: formData.checkDate,
- },
- },
- {
- name: "insertInstallationOrderProcessLog",
- type: "e",
- parammaps: {
- orderId: this.currentRow.id,
- operationType: "check",
- operationUserId: this.currentUser.id,
- operationUserName: this.currentUser.name,
- beforeStatus: this.currentRow.statusName,
- afterStatus: "已完成",
- operationContent: "验收服务工单",
- },
- }
- );
- const response = await ExecDataByConfig(params);
- if (response.msg === "ok") {
- this.$message.success("验收成功");
- this.checkDialogVisible = false;
- this.getList();
- } else {
- this.$message.error(response.msg || "验收失败");
- }
- } catch (error) {
- console.error("验收失败:", error);
- this.$message.error("验收失败");
- }
- },
- // 检查按钮权限
- checkButtonPermission(buttonPath) {
- return this.buttonMenu?.some((item) => item.path === buttonPath) || false;
- },
- // 格式化日期为yyyy-MM-dd
- formatDate(date) {
- if (!date) return "";
- const d = new Date(date);
- const year = d.getFullYear();
- const month = String(d.getMonth() + 1).padStart(2, "0");
- const day = String(d.getDate()).padStart(2, "0");
- return `${year}-${month}-${day}`;
- },
- // 处理编辑成功
- handleEditSuccess() {
- this.getList(); // 刷新列表数据
- },
- getProgressBarColor(status) {
- // 根据状态返回对应的颜色
- const statusColorMap = {
- 未接单: "#909399", // 灰色
- 已接单: "#409eff", // 蓝色
- 处理中: "#409eff", // 蓝色
- 已完成未验收: "#e6a23c", // 橙色
- 已完成: "#67c23a", // 绿色
- 接单驳回: "#f56c6c", // 红色
- };
- return statusColorMap[status] || "#909399";
- },
- showProgressTooltip(event, percentage) {
- // 先移除可能存在的旧tooltip
- this.hideProgressTooltip();
- this.progressTooltip = document.createElement("div");
- this.progressTooltip.className = "progress-tooltip";
- this.progressTooltip.textContent = (() => {
- const num = parseFloat(percentage);
- if (!Number.isFinite(num)) return "0%";
- if (num < 0) return "0%";
- if (num > 100) return "100%";
- return num.toFixed(0) + "%";
- })();
- document.body.appendChild(this.progressTooltip);
- const rect = event.target.getBoundingClientRect();
- const tooltipRect = this.progressTooltip.getBoundingClientRect();
- this.progressTooltip.style.left =
- rect.left + rect.width / 2 - tooltipRect.width / 2 + "px";
- this.progressTooltip.style.top = rect.top - tooltipRect.height - 8 + "px";
- // 使用 requestAnimationFrame 确保 DOM 更新后再添加显示类
- requestAnimationFrame(() => {
- if (this.progressTooltip) {
- this.progressTooltip.classList.add("show");
- }
- });
- },
- hideProgressTooltip() {
- if (this.progressTooltip) {
- // 移除显示类
- this.progressTooltip.classList.remove("show");
- // 确保移除所有可能存在的旧tooltip
- const oldTooltips = document.querySelectorAll(".progress-tooltip");
- oldTooltips.forEach((tooltip) => {
- if (tooltip.parentNode) {
- tooltip.parentNode.removeChild(tooltip);
- }
- });
- this.progressTooltip = null;
- }
- },
- // 处理驳回
- async handleRejectConfirm(form) {
- try {
- const params = {
- common: {
- returnmap: "0",
- },
- data: [
- {
- name: "rejectInstallationOrder",
- type: "e",
- parammaps: {
- orderId: this.currentRow.id,
- rejectReason: form.rejectReason,
- },
- },
- {
- name: "insertInstallationOrderProcessLog",
- type: "e",
- parammaps: {
- orderId: this.currentRow.id,
- operationType: "reject",
- operationUserId: this.currentUser.id,
- operationUserName: this.currentUser.name,
- beforeStatus: this.currentRow.statusName,
- afterStatus: "接单驳回",
- operationContent: `驳回原因:${form.rejectReason}`,
- },
- },
- ],
- };
- const response = await ExecDataByConfig(params);
- if (response.msg === "ok") {
- this.$message.success("驳回成功");
- this.rejectDialogVisible = false;
- this.viewDialogVisible = false;
- this.getList();
- } else {
- this.$message.error(response.msg || "驳回失败");
- }
- } catch (error) {
- console.error("驳回失败:", error);
- this.$message.error("驳回失败");
- }
- },
- // 处理接单
- async handleAcceptConfirm(form) {
- try {
- const params = {
- common: {
- returnmap: "0",
- },
- data: [
- {
- name: "acceptInstallationOrder",
- type: "e",
- parammaps: {
- orderId: form.orderId,
- acceptId: this.currentUser.id,
- acceptName: this.currentUser.name,
- },
- },
- {
- name: "insertInstallationOrderProcessLog",
- type: "e",
- parammaps: {
- orderId: this.currentRow.id,
- operationType: "accept",
- operationUserId: this.currentUser.id,
- operationUserName: this.currentUser.name,
- beforeStatus: this.currentRow.statusName,
- afterStatus: "处理中",
- operationContent: "接单处理",
- },
- },
- ],
- };
- const response = await ExecDataByConfig(params);
- if (response.msg === "ok") {
- this.$message.success("接单成功");
- this.acceptDialogVisible = false;
- this.viewDialogVisible = false;
- this.getList();
- } else {
- this.$message.error(response.msg || "接单失败");
- }
- } catch (error) {
- console.error("接单失败:", error);
- this.$message.error("接单失败");
- }
- },
- // 设置行的class
- tableRowClassName({ row }) {
- return row.statusName === "已驳回" ? "rejected-row" : "";
- },
- // 判断当前用户是否在服务人员列表中
- isCurrentUserInServiceStaff(serviceStaffIds) {
- console.log("serviceStaffIds", serviceStaffIds);
- if (!serviceStaffIds) return false;
- const currentUserId = parseInt(this.currentUser.id);
- const staffIds = serviceStaffIds
- .split(",")
- .map((id) => parseInt(id.trim()));
- return staffIds.includes(currentUserId);
- },
- // 判断当前用户是否是创建人
- isCurrentUserInCreateId(createId) {
- if (!createId) return false;
- return createId === parseInt(this.currentUser.id);
- },
- /**
- * 按钮显示控制逻辑
- * @param {Object} button - 按钮配置对象
- * @param {Object} row - 行数据
- * @returns {boolean} - 是否显示按钮
- */
- getButtonVisible(button, row) {
- // 权限检查
- if (!this.checkButtonPermission(button.permission)) {
- return false;
- }
- // 状态检查
- const statusMap = {
- view: true, // 查看按钮始终显示
- edit: ["未接单", "已接单", "处理中", "接单驳回"].includes(
- row.statusName
- ),
- delete: ["未接单", "接单驳回"].includes(row.statusName),
- dispatch: ["未接单", "已接单", "处理中"].includes(row.statusName),
- reject: row.statusName === "未接单",
- accept: row.statusName === "未接单",
- write: ["已接单", "处理中"].includes(row.statusName),
- complete: ["已接单", "处理中"].includes(row.statusName),
- check: row.statusName === "已完成未验收",
- };
- if (!statusMap[button.type]) {
- return false;
- }
- // 角色检查
- const roleMap = {
- view: true, // 查看按钮所有人可见
- edit:
- this.isCurrentUserInCreateId(row.createId) ||
- this.isCurrentUserInServiceStaff(row.serviceStaffIds),
- delete: this.isCurrentUserInCreateId(row.createId),
- dispatch: this.isCurrentUserInCreateId(row.createId),
- reject: this.isCurrentUserInServiceStaff(row.serviceStaffIds),
- accept: this.isCurrentUserInServiceStaff(row.serviceStaffIds),
- write: this.isCurrentUserInServiceStaff(row.serviceStaffIds),
- complete: this.isCurrentUserInServiceStaff(row.serviceStaffIds),
- check: true, // 验收按钮所有人可见
- };
- return roleMap[button.type] || false;
- },
- },
- };
- </script>
- <style lang="scss" scoped>
- .app-container {
- padding: 15px;
- background-color: #f5f7fa;
- .el-table {
- // 表格整体样式
- border-radius: 4px;
- box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
- // 表头样式
- :deep(.el-table__header-wrapper) {
- position: sticky;
- top: 0;
- z-index: 2;
- .el-table__header {
- thead {
- tr {
- th {
- background-color: #f5f7fa;
- color: #333;
- font-weight: 500;
- height: 44px;
- padding: 8px 0;
- &.is-leaf {
- border-bottom: 1px solid #e8e8e8;
- }
- }
- }
- }
- }
- }
- // 表格内容样式
- :deep(.el-table__body-wrapper) {
- overflow-y: auto;
- &::-webkit-scrollbar {
- width: 6px;
- height: 6px;
- }
- &::-webkit-scrollbar-thumb {
- border-radius: 3px;
- background: #c0c4cc;
- }
- &::-webkit-scrollbar-track {
- border-radius: 3px;
- background: #f5f7fa;
- }
- .el-table__body {
- td {
- padding: 12px 0;
- height: 50px;
- }
- }
- }
- // 重写表格行样式
- ::v-deep(.el-table__body) {
- tr.rejected-row {
- background-color: rgba(245, 108, 108, 0.1) !important;
- }
- tr.rejected-row td {
- background-color: rgba(245, 108, 108, 0.1) !important;
- }
- tr.rejected-row:hover td {
- background-color: rgba(245, 108, 108, 0.15) !important;
- }
- tr.rejected-row.el-table__row--striped td {
- background-color: rgba(245, 108, 108, 0.1) !important;
- }
- tr.rejected-row.current-row td {
- background-color: rgba(245, 108, 108, 0.1) !important;
- }
- }
- // 鼠标悬停效果
- :deep(.el-table__body tr:hover) {
- td {
- background-color: #f0f7ff !important;
- }
- }
- // 移除之前的按钮样式,添加新的美化样式
- :deep(.el-button--mini) {
- margin: 2px 3px;
- padding: 6px 12px;
- height: 28px;
- border-radius: 4px;
- font-size: 12px;
- font-weight: 500;
- transition: all 0.3s;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
- &:hover {
- transform: translateY(-1px);
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
- }
- &.el-button--primary {
- background-color: #409eff;
- border-color: #409eff;
- &:hover {
- background-color: #66b1ff;
- border-color: #66b1ff;
- }
- }
- &.el-button--success {
- background-color: #67c23a;
- border-color: #67c23a;
- &:hover {
- background-color: #85ce61;
- border-color: #85ce61;
- }
- }
- &.el-button--warning {
- background-color: #e6a23c;
- border-color: #e6a23c;
- &:hover {
- background-color: #ebb563;
- border-color: #ebb563;
- }
- }
- &.el-button--danger {
- background-color: #f56c6c;
- border-color: #f56c6c;
- &:hover {
- background-color: #f78989;
- border-color: #f78989;
- }
- }
- &.el-button--info {
- background-color: #909399;
- border-color: #909399;
- &:hover {
- background-color: #a6a9ad;
- border-color: #a6a9ad;
- }
- }
- // 所有按钮文字颜色设为白色
- color: #fff;
- // 禁用状态样式
- &.is-disabled {
- &:hover {
- transform: none;
- box-shadow: none;
- }
- }
- }
- // 进度条样式
- :deep(.progress-wrapper) {
- padding: 6px 0;
- width: 100%;
- height: 100%;
- cursor: pointer;
- .progress-container {
- display: flex;
- align-items: center;
- justify-content: center;
- .progress-bar {
- width: 100%;
- padding: 0 20px;
- .custom-progress {
- width: 100%;
- height: 12px;
- background-color: #f5f7fa;
- border: 1px solid #e4e7ed;
- border-radius: 100px;
- overflow: hidden;
- position: relative;
- .progress-inner {
- height: 100%;
- transition: all 0.3s ease;
- border-radius: 100px;
- position: relative;
- min-width: 2px;
- .progress-text {
- position: absolute;
- right: 6px;
- top: 50%;
- transform: translateY(-50%);
- color: #fff;
- font-size: 11px;
- line-height: 1;
- text-shadow: 0 0 2px rgba(0, 0, 0, 0.3);
- white-space: nowrap;
- font-weight: 500;
- }
- }
- .progress-text-zero {
- position: absolute;
- left: 10px;
- top: 50%;
- transform: translateY(-50%);
- color: #909399;
- font-size: 11px;
- line-height: 1;
- white-space: nowrap;
- font-weight: 500;
- background-color: #fff;
- padding: 0 4px;
- border-radius: 10px;
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
- }
- }
- }
- }
- }
- // 状态标签样式
- :deep(.el-tag) {
- border-radius: 2px;
- padding: 0 8px;
- height: 24px;
- line-height: 22px;
- // 已完成未验收状态特殊样式
- &.el-tag--warning {
- &:not(.is-hit) {
- background-color: #fdf6ec;
- border-color: #faecd8;
- color: #e6a23c;
- &[type="warning"] {
- background-color: #fdf6ec;
- border-color: #faecd8;
- color: #e6a23c;
- }
- }
- }
- // 已驳回状态样式
- &.el-tag--danger {
- background-color: #fef0f0;
- border-color: #fde2e2;
- color: #f56c6c;
- }
- // 其他状态保持原样
- &.el-tag--success {
- background-color: #f0f9eb;
- border-color: #e1f3d8;
- color: #67c23a;
- }
- &.el-tag--primary {
- background-color: #ecf5ff;
- border-color: #d9ecff;
- color: #409eff;
- }
- }
- // 空数据样式
- :deep(.el-table__empty-block) {
- min-height: 200px;
- .el-table__empty-text {
- color: #909399;
- font-size: 14px;
- line-height: 200px;
- text-align: left;
- }
- }
- // 固定列样式
- :deep(.el-table__fixed-right) {
- height: 100% !important;
- box-shadow: -2px 0 8px rgba(0, 0, 0, 0.05);
- right: 0 !important;
- }
- // 表格边框样式
- :deep(.el-table--border) {
- border: 1px solid #e8e8e8;
- &::after {
- background-color: #e8e8e8;
- }
- th,
- td {
- border-right: 1px solid #e8e8e8;
- }
- }
- // 下拉菜单项样式
- :deep(.el-dropdown-menu__item) {
- padding: 8px 20px;
- font-size: 13px;
- &:hover {
- background-color: #f5f7fa;
- }
- &.dropdown-primary {
- color: #409eff;
- }
- &.dropdown-success {
- color: #67c23a;
- }
- &.dropdown-warning {
- color: #e6a23c;
- }
- &.dropdown-danger {
- color: #f56c6c;
- }
- &.dropdown-info {
- color: #909399;
- }
- }
- // 更多按钮样式
- :deep(.el-dropdown) {
- margin-left: 2px;
- .el-button {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- i {
- margin-left: 3px;
- }
- }
- }
- }
- // 其他已有样式保持不变
- .pagination-container {
- padding: 15px 0;
- text-align: left;
- }
- .demo-form-inline {
- background-color: #fff;
- padding: 15px 15px;
- border-radius: 4px;
- box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
- :deep(.el-form-item) {
- margin-bottom: 0;
- margin-top: 3px;
- margin-bottom: 3px;
- margin-right: 5px;
- display: inline-flex;
- align-items: center;
- vertical-align: top;
- }
- :deep(.el-input__inner) {
- height: 32px;
- line-height: 32px;
- }
- :deep(.el-range-editor.el-input__inner) {
- padding: 0 10px;
- margin: 0;
- }
- :deep(.el-button),
- :deep(.el-radio-button__inner) {
- height: 32px;
- padding: 0 15px;
- line-height: 30px;
- vertical-align: top;
- }
- :deep(.el-radio-group) {
- display: inline-flex;
- vertical-align: top;
- }
- :deep(.el-input) {
- margin-left: 0 !important; // 强制覆盖左边距
- }
- :deep(.el-form-item__content) {
- line-height: 32px;
- display: inline-flex;
- align-items: center;
- }
- :deep(.pending-badge) {
- position: absolute;
- top: -8px;
- right: -3px;
- z-index: 2;
- .el-badge__content {
- height: 16px;
- line-height: 16px;
- padding: 0 4px;
- border: none;
- font-size: 12px;
- background-color: #f56c6c;
- }
- }
- :deep(.el-range-separator) {
- color: #606266;
- line-height: 30px;
- font-size: 13px;
- padding: 0 3px;
- }
- }
- :deep(.el-loading-mask) {
- .el-loading-spinner {
- .el-icon-loading {
- font-size: 30px;
- color: #409eff;
- }
- .el-loading-text {
- font-size: 14px;
- margin-top: 10px;
- color: #606266;
- }
- }
- }
- // 货品标签样式
- :deep(.product-tags) {
- display: flex;
- flex-wrap: wrap;
- gap: 4px;
- justify-content: center;
- padding: 2px;
- .el-tag {
- margin: 2px;
- max-width: 150px;
- white-space: normal;
- height: auto;
- padding: 2px 6px;
- line-height: 16px;
- word-break: break-all;
- text-align: center;
- &.long-text {
- font-size: 11px;
- }
- }
- }
- // 服务人员标签样式
- :deep(.staff-tags) {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 2px;
- padding: 1px;
- .el-tag {
- margin: 1px;
- min-width: 70px;
- max-width: 100px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- height: 20px;
- padding: 0 6px;
- line-height: 20px;
- font-size: 11px;
- &.long-text {
- font-size: 10px;
- }
- }
- }
- // 时间显示样式
- :deep(.normal-time) {
- color: #606266;
- font-size: 13px;
- }
- :deep(.warning-time) {
- color: #f56c6c;
- font-size: 15px;
- font-weight: bold;
- }
- :deep(.overdue-time) {
- color: #f56c6c;
- font-size: 15px;
- font-weight: bold;
- }
- .order-no-link {
- font-size: 13px;
- font-weight: 500;
- &:hover {
- color: #66b1ff;
- }
- &:active {
- color: #3a8ee6;
- }
- }
- }
- </style>
- <style lang="scss">
- .progress-tooltip {
- position: fixed;
- background: rgba(0, 0, 0, 0.8);
- color: #fff;
- padding: 4px 8px;
- border-radius: 4px;
- font-size: 12px;
- pointer-events: none;
- z-index: 9999;
- opacity: 0;
- transform: translateY(5px);
- transition: all 0.2s ease;
- &::after {
- content: "";
- position: absolute;
- bottom: -4px;
- left: 50%;
- transform: translateX(-50%);
- border-left: 4px solid transparent;
- border-right: 4px solid transparent;
- border-top: 4px solid rgba(0, 0, 0, 0.8);
- }
- &.show {
- opacity: 1;
- transform: translateY(0);
- }
- }
- .el-table {
- tbody {
- tr.rejected-row {
- background-color: rgba(245, 108, 108, 0.1) !important;
- td {
- background-color: rgba(245, 108, 108, 0.1) !important;
- }
- &:hover td {
- background-color: rgba(245, 108, 108, 0.15) !important;
- }
- }
- }
- }
- </style>
|