<!-- 查看服务计划弹窗 -->
<template>
  <el-dialog
    :visible.sync="visible"
    width="1000px"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    @close="handleDialogClose"
    :show-close="true"
  >
    <el-tabs v-model="activeTab" class="dialog-tabs">
      <!-- 基本信息标签页 -->
      <el-tab-pane label="基本信息" name="basic">
        <el-form ref="form" :model="form" label-width="120px">
          <el-row :gutter="10">
            <el-col :span="8">
              <el-form-item label="服务单号">
                <el-input v-model="form.orderNo" readonly />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="下单人">
                <el-input v-model="form.createName" readonly />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="下单时间">
                <el-input v-model="form.orderTime" readonly />
              </el-form-item>
            </el-col>
          </el-row>

          <el-row :gutter="10">
            <el-col :span="8">
              <el-form-item label="派单人">
                <el-input v-model="form.dispatcherName" readonly />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="服务人员">
                <el-input v-model="form.serviceStaffNames" readonly />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="接单时间">
                <el-input v-model="form.acceptTime" readonly />
              </el-form-item>
            </el-col>
          </el-row>

          <el-row :gutter="10">
            <el-col :span="8">
              <el-form-item label="客户">
                <el-input v-model="form.customerName" readonly />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="发货单号">
                <el-input v-model="form.deliveryNo" readonly />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="合同">
                <el-input v-model="form.contractNo" readonly />
              </el-form-item>
            </el-col>
          </el-row>

          <el-row :gutter="10">
            <el-col :span="8">
              <el-form-item label="计划总量">
                <el-input v-model="form.totalQuantity" readonly />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="已完成量">
                <el-input v-model="form.installedQuantity" readonly />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="未完成量">
                <el-input v-model="form.uninstalledQuantity" readonly />
              </el-form-item>
            </el-col>
          </el-row>

          <el-row :gutter="10">
            <el-col :span="8">
              <el-form-item label="预计完成时间">
                <el-input v-model="form.estimatedCompleteTime" readonly />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="实际完成时间">
                <el-input v-model="form.actualCompleteTime" readonly />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="距预估完成时间">
                <el-input v-model="remainingTimeText" readonly />
              </el-form-item>
            </el-col>
          </el-row>

          <el-row :gutter="10">
            <el-col :span="8">
              <el-form-item label="安装进度">
                <el-input :value="(form.progress || 0) + '%'" readonly />
              </el-form-item>
            </el-col>

            <el-col :span="8">
              <el-form-item label="客户联系人">
                <el-input v-model="form.contactName" readonly />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="客户联系人电话">
                <el-input v-model="form.contactPhone" readonly />
              </el-form-item>
            </el-col>
          </el-row>

          <el-row :gutter="10">
            <el-col :span="16">
              <el-form-item label="备注">
                <el-input
                  type="textarea"
                  v-model="form.remark"
                  :rows="2"
                  readonly
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-form-item label-width="0">
            <div class="detail-section">
              <div class="table-header">
                <div class="section-title">货品明细</div>
                <el-button
                  type="text"
                  class="fold-button"
                  @click="isTableVisible = !isTableVisible"
                >
                  <span>{{ isTableVisible ? "收起" : "展开" }}</span>
                  <i
                    :class="
                      isTableVisible ? 'el-icon-arrow-up' : 'el-icon-arrow-down'
                    "
                  />
                </el-button>
              </div>
              <div v-show="isTableVisible">
                <el-table :data="form.products" border style="width: 100%">
                  <el-table-column
                    type="index"
                    label="序号"
                    width="50"
                    align="center"
                  />
                  <el-table-column
                    prop="projectName"
                    label="服务项目"
                    align="center"
                    width="150"
                  />
                  <el-table-column
                    prop="goodsCode"
                    label="货品编号"
                    align="center"
                    width="80"
                  />
                  <el-table-column
                    prop="goodsName"
                    label="货品名称"
                    align="center"
                    width="150"
                  />
                  <el-table-column
                    prop="goodsSpecification"
                    label="货品规格"
                    align="center"
                    width="100"
                  />
                  <el-table-column
                    prop="goodsImagePath"
                    label="货品图片"
                    align="center"
                  >
                    <template slot-scope="scope">
                      <el-image
                        v-if="scope.row.goodsImagePath"
                        :src="baseApi + scope.row.goodsImagePath"
                        style="width: 50px; height: 50px"
                        :preview-src-list="[baseApi + scope.row.goodsImagePath]"
                        fit="contain"
                      >
                        <div slot="error" class="image-slot">
                          <i class="el-icon-picture-outline"></i>
                        </div>
                      </el-image>
                      <div
                        v-else
                        class="image-slot"
                        style="
                          width: 50px;
                          height: 50px;
                          display: inline-flex;
                          justify-content: center;
                          align-items: center;
                          background: #f5f7fa;
                          border-radius: 4px;
                        "
                      >
                        <i
                          class="el-icon-picture-outline"
                          style="font-size: 20px; color: #909399"
                        ></i>
                      </div>
                    </template>
                  </el-table-column>
                  <el-table-column
                    prop="goodsUnit"
                    label="计量单位"
                    align="center"
                    width="50"
                  />
                  <el-table-column
                    prop="stock"
                    label="现有库存"
                    align="center"
                    width="60"
                  />
                  <el-table-column
                    prop="orderQuantity"
                    label="计划总量"
                    align="center"
                    width="110"
                  />
                  <el-table-column
                    prop="shippedQuantity"
                    label="已完成量"
                    align="center"
                    width="70"
                  />
                  <el-table-column
                    prop="unshippedQuantity"
                    label="未完成量"
                    align="center"
                    width="80"
                  >
                    <template slot-scope="scope">
                      <span
                        :style="{
                          color:
                            parseInt(scope.row.unshippedQuantity) < 0
                              ? '#67C23A'
                              : '',
                        }"
                      >
                        {{
                          formatUnshippedQuantity(scope.row.unshippedQuantity)
                        }}
                      </span>
                    </template>
                  </el-table-column>
                  <el-table-column
                    prop="remark"
                    label="备注"
                    align="center"
                    width="100"
                  />
                </el-table>
              </div>
            </div>
          </el-form-item>

          <!-- 服务验收 -->
          <el-form-item label-width="0">
            <div class="detail-section">
              <div class="section-title">服务验收</div>
              <div class="acceptance-image">
                <template v-if="acceptanceImages.length">
                  <el-image
                    v-for="(imgPath, index) in acceptanceImages"
                    :key="index"
                    :src="baseApi + imgPath"
                    style="width: 120px; height: 120px; margin-right: 10px"
                    :preview-src-list="acceptanceImageUrls"
                    fit="cover"
                  >
                    <div slot="error" class="image-slot">
                      <i class="el-icon-picture-outline"></i>
                    </div>
                  </el-image>
                </template>
                <div v-else class="empty-image">
                  <i
                    class="el-icon-picture-outline"
                    style="font-size: 24px"
                  ></i>
                  <span style="margin-top: 8px">暂无验收图片</span>
                </div>
              </div>
            </div>
          </el-form-item>

          <!-- 流程进度 -->
          <el-form-item label-width="0">
            <div class="detail-section">
              <div class="section-title">流程进度</div>
              <div class="process-steps">
                <el-steps
                  :active="getActiveStep"
                  align-center
                  finish-status="success"
                  :status="stepStatus"
                >
                  <el-step title="服务下单">
                    <template slot="description">
                      <div class="step-description">
                        <div>{{ getStepInfo("create").operationUserName }}</div>
                        <div>{{ getStepInfo("create").createTime }}</div>
                      </div>
                    </template>
                    <template slot="icon">
                      <i
                        :class="getActiveStep >= 1 ? 'el-icon-check' : ''"
                        :style="{ color: getActiveStep >= 1 ? '#67C23A' : '' }"
                      ></i>
                    </template>
                  </el-step>
                  <el-step
                    :title="isLastStepReject ? '接单驳回' : '服务接单'"
                    :status="isLastStepReject ? 'error' : ''"
                  >
                    <template slot="description">
                      <div
                        class="step-description"
                        :class="{ 'reject-status': isLastStepReject }"
                      >
                        <div>{{ getAcceptStepInfo.operationUserName }}</div>
                        <div>{{ getAcceptStepInfo.createTime }}</div>
                        <div v-if="isLastStepReject" class="reject-reason">
                          <i
                            class="el-icon-warning-outline"
                            style="margin-right: 5px"
                          ></i>
                          {{ getAcceptStepInfo.operationContent }}
                        </div>
                      </div>
                    </template>
                    <template slot="icon">
                      <i
                        v-if="isLastStepReject"
                        class="el-icon-close"
                        style="color: #f56c6c"
                      ></i>
                      <i
                        v-else-if="getActiveStep >= 2"
                        class="el-icon-check"
                        style="color: #67c23a"
                      ></i>
                    </template>
                  </el-step>
                  <el-step title="开始服务" :status="getStepStatus(3)">
                    <template slot="description">
                      <div class="step-description">
                        <div>{{ getStepInfo("write").operationUserName }}</div>
                        <div>{{ getStepInfo("write").createTime }}</div>
                      </div>
                    </template>
                  </el-step>
                  <el-step title="完成服务" :status="getStepStatus(4)">
                    <template slot="description">
                      <div class="step-description">
                        <div>
                          {{ getStepInfo("complete").operationUserName }}
                        </div>
                        <div>{{ getStepInfo("complete").createTime }}</div>
                      </div>
                    </template>
                  </el-step>
                  <el-step title="验收" :status="getStepStatus(5)">
                    <template slot="description">
                      <div class="step-description">
                        <div>{{ getStepInfo("check").operationUserName }}</div>
                        <div>{{ getStepInfo("check").createTime }}</div>
                      </div>
                    </template>
                  </el-step>
                </el-steps>
              </div>
            </div>
          </el-form-item>
        </el-form>
      </el-tab-pane>

      <!-- 服务进度标签页 -->
      <el-tab-pane label="服务记录" name="progress">
        <div class="service-progress">
          <div class="progress-header">
            <div class="header-item">
              <span class="label">客户：</span>
              <span class="value">{{ form.customerName }}</span>
            </div>
            <div class="header-item">
              <span class="label">预计完成时间：</span>
              <span class="value">{{ form.estimatedCompleteTime }}</span>
            </div>
            <div class="header-item">
              <span class="label">服务人员：</span>
              <span class="value">{{ form.serviceStaffNames }}</span>
            </div>
          </div>

          <div class="filter-section">
            <div class="filter-left">
              <el-date-picker
                v-model="filterDate"
                type="daterange"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
                value-format="yyyy-MM-dd"
                style="width: 260px; margin-right: 15px"
              />
              <el-select
                v-model="filterStaff"
                filterable
                placeholder="请选择服务人员"
                clearable
                style="width: 200px; margin-right: 15px"
              >
                <el-option
                  v-for="item in serviceStaffList"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
              <el-button
                type="primary"
                icon="el-icon-search"
                @click="getOrderDailyData"
                >查 询</el-button
              >
              <el-button
                type="primary"
                icon="el-icon-download"
                @click="handleExport"
                >导 出</el-button
              >
            </div>
          </div>

          <el-table
            :data="displayProgressData"
            border
            style="width: 100%; margin-top: 20px"
            :header-cell-style="{
              background: '#f5f7fa',
              color: '#606266',
              fontWeight: 500,
            }"
            :span-method="handleSpanMethod"
          >
            <el-table-column
              prop="installDate"
              label="日期"
              align="center"
              width="100"
            />
            <el-table-column
              prop="projectName"
              label="项目名称"
              align="center"
              min-width="120"
            />
            <el-table-column
              prop="goodsCode"
              label="货品编号"
              align="center"
              min-width="80"
            />

            <el-table-column
              prop="goodsName"
              label="货品名称"
              align="center"
              min-width="120"
            />

            <el-table-column
              prop="orderQuantity"
              label="计划总量"
              align="center"
              width="80"
            />
            <el-table-column
              prop="unshippedQuantity"
              label="剩余量"
              align="center"
              width="80"
            >
              <template slot-scope="scope">
                <span
                  :style="{
                    color:
                      parseInt(scope.row.unshippedQuantity) < 0
                        ? '#67C23A'
                        : '',
                  }"
                >
                  {{ formatUnshippedQuantity(scope.row.unshippedQuantity) }}
                </span>
              </template>
            </el-table-column>
            <el-table-column
              prop="installUserName"
              label="服务人员"
              align="center"
              min-width="80"
            />

            <el-table-column
              prop="installQuantity"
              label="当天完成量"
              align="center"
              width="100"
            />
            <el-table-column
              prop="shippedQuantity"
              label="累计完成量"
              align="center"
              width="100"
            />
            <el-table-column
              prop="installRemark"
              label="备注"
              align="center"
              min-width="150"
            />
          </el-table>
        </div>
      </el-tab-pane>
    </el-tabs>

    <div slot="footer" class="dialog-footer">
      <el-button v-if="showRejectButton" type="danger" @click="handleReject"
        >驳 回</el-button
      >
      <el-button v-if="showAcceptButton" type="primary" @click="handleAccept"
        >接 单</el-button
      >
      <el-button @click="handleDialogClose">关 闭</el-button>
    </div>
  </el-dialog>
</template>

<script>
import { GetDataByNames, GetDataByName } from "@/api/common";
import * as XLSX from "xlsx";

export default {
  name: "ViewDialog",
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    installerOptions: {
      type: Array,
      default: () => [],
    },
    projectOptions: {
      type: Array,
      default: () => [],
    },
    rowData: {
      type: Object,
      default: () => ({}),
    },
    checkButtonPermission: {
      type: Function,
      required: false,
      default: () => () => false,
    },
    isCurrentUserInServiceStaff: {
      type: Function,
      required: false,
      default: () => () => false,
    },
  },
  computed: {
    baseApi() {
      return process.env.VUE_APP_BASE_API;
    },
    showRejectButton() {
      return (
        this.form.statusName === "未接单" &&
        this.checkButtonPermission(
          "productManagement:installationOrder:reject"
        ) &&
        this.isCurrentUserInServiceStaff(this.form.serviceStaffIds)
      );
    },
    showAcceptButton() {
      return (
        this.form.statusName === "未接单" &&
        this.checkButtonPermission(
          "productManagement:installationOrder:accept"
        ) &&
        this.isCurrentUserInServiceStaff(this.form.serviceStaffIds)
      );
    },
    ordererName() {
      return (
        this.installerOptions.find(
          (item) => item.value === parseInt(this.form.orderer)
        )?.label || ""
      );
    },
    projectName() {
      return (
        this.projectOptions.find(
          (item) => item.value === parseInt(this.form.serviceProject)
        )?.label || ""
      );
    },
    remainingTimeText() {
      if (
        this.form.remainingTime === null ||
        this.form.remainingTime === undefined
      )
        return "";
      if (this.form.remainingTime < 0) {
        return `已逾期 ${Math.abs(this.form.remainingTime)} 天`;
      }
      return `${this.form.remainingTime} 天`;
    },
    acceptanceImages() {
      if (!this.form.acceptanceImagePath) {
        return [];
      }
      const images = this.form.acceptanceImagePath.split(",");
      return images.slice(0, 3);
    },
    acceptanceImageUrls() {
      if (!this.form.acceptanceImagePath) {
        return [];
      }
      const images = this.form.acceptanceImagePath.split(",");
      return images.map((path) => this.baseApi + path);
    },
    isLastStepReject() {
      if (!this.form.processData || this.form.processData.length === 0) {
        return false;
      }

      const sortedData = this.form.processData.slice().sort((a, b) => {
        return new Date(b.createTime) - new Date(a.createTime);
      });

      return sortedData[0].operationType === "reject";
    },
    getAcceptStepInfo() {
      const emptyResult = {
        operationUserName: "",
        createTime: "",
        operationContent: "",
      };

      if (!this.form.processData || this.form.processData.length === 0) {
        return emptyResult;
      }

      const sortedData = this.form.processData.slice().sort((a, b) => {
        return new Date(b.createTime) - new Date(a.createTime);
      });

      if (this.isLastStepReject) {
        return sortedData[0];
      }

      const acceptItem = sortedData.find(
        (item) => item.operationType === "accept"
      );
      return acceptItem || emptyResult;
    },
    getActiveStep() {
      if (!this.form.processData || this.form.processData.length === 0) {
        return 0;
      }

      const stepMap = {
        create: 1,
        accept: 2,
        write: 3,
        complete: 4,
        check: 5,
      };

      const hasReject = this.form.processData.some(
        (item) => item.operationType === "reject"
      );
      if (hasReject) {
        return 2;
      }

      let maxStep = 0;
      this.form.processData.forEach((item) => {
        const currentStep = stepMap[item.operationType] || 0;
        maxStep = Math.max(maxStep, currentStep);
      });

      return maxStep;
    },
    stepStatus() {
      return this.isLastStepReject ? "error" : "process";
    },
    displayProgressData() {
      return this.form.serviceProgressData;
    },
    formatUnshippedQuantity() {
      return (value) => {
        const num = parseInt(value) || 0;
        if (num < 0) {
          return `超量 ${Math.abs(num)}`;
        }
        return num.toString();
      };
    },
  },
  watch: {
    visible(val) {
      if (val) {
        this.$nextTick(() => {
          this.initData();
        });
      } else {
        this.resetData();
      }
    },
    activeTab(val) {
      if (val === "progress") {
        this.getOrderDailyData();
        this.$nextTick(() => {
          this.mergeGroups = [];
        });
      }
    },
    "form.serviceStaffIds": {
      handler(val) {
        if (val && this.form.serviceStaffNames) {
          const ids = val.split(",");
          const names = this.form.serviceStaffNames.split(",");

          this.serviceStaffList = ids.map((id, index) => ({
            value: id.trim(),
            label: names[index].trim(),
          }));
        } else {
          this.serviceStaffList = [];
        }
      },
      immediate: true,
    },
  },
  data() {
    return {
      isTableVisible: true,
      isAcceptanceVisible: true,
      isProcessVisible: true,
      form: {
        orderNo: "",
        orderTime: "",
        orderer: "",
        serviceProject: "",
        serviceStaffNames: "",
        statusName: "",
        serviceStaffIds: "",
        projectName: "",
        estimatedCompleteTime: "",
        deliveryNo: "",
        contractNo: "",
        customerName: "",
        remark: "",
        products: [],
        totalQuantity: 0,
        installedQuantity: 0,
        uninstalledQuantity: 0,
        progress: 0,
        acceptTime: "",
        actualCompleteTime: "",
        remainingTime: null,
        acceptanceImagePath: "",
        currentStep: 2,
        isRejected: true,
        rejectReason: "xxxxxxx",
        startTime: "",
        acceptanceTime: "",
        createName: "",
        serviceProgressData: [],
      },
      activeTab: "basic",
      spanCount: 1,
      mergeGroups: [],
      dateMergeGroups: [],
      filterDate: [],
      filterStaff: null,
      serviceStaffList: [],
    };
  },
  methods: {
    async handleReject() {
      try {
        this.$emit("reject");
        this.handleDialogClose();
      } catch (error) {
        console.error("驳回失败:", error);
      }
    },
    async handleAccept() {
      try {
        this.$emit("accept");
        this.handleDialogClose();
      } catch (error) {
        console.error("接单失败:", error);
      }
    },
    initData() {
      this.isTableVisible = true;
      this.mergeGroups = [];
      this.activeTab = "basic";
      this.getOrderData();
    },
    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}`;
    },
    resetData() {
      this.form = {
        orderNo: "",
        orderTime: "",
        orderer: "",
        serviceProject: "",
        serviceStaffNames: "",
        serviceStaffIds: "",
        projectName: "",
        estimatedCompleteTime: "",
        deliveryNo: "",
        contractNo: "",
        customerName: "",
        remark: "",
        products: [],
        totalQuantity: 0,
        installedQuantity: 0,
        uninstalledQuantity: 0,
        progress: 0,
        acceptTime: "",
        actualCompleteTime: "",
        remainingTime: null,
        acceptanceImagePath: "",
        currentStep: 2,
        isRejected: true,
        rejectReason: "",
        startTime: "",
        acceptanceTime: "",
        createName: "",
        serviceProgressData: [],
      };
      this.mergeGroups = [];
      this.isTableVisible = true;
      this.filterStaff = null;
      this.filterDate = [];
    },
    async getOrderData() {
      try {
        this.isTableVisible = true;
        const params = [
          {
            name: "getInstallationOrderById",
            returntype: "Map",
            parammaps: {
              id: this.rowData.id,
            },
          },
          {
            name: "getInstallationOrderDetail",
            returntype: "Map",
            parammaps: {
              orderId: this.rowData.id,
            },
          },
          {
            name: "getInstallationOrderProcessLogByOrderId",
            returntype: "Map",
            parammaps: {
              orderId: this.rowData.id,
            },
          },
        ];

        const response = await GetDataByNames(params);
        if (response.msg === "ok") {
          const mainData = response.data.getInstallationOrderById.list[0] || {};
          const detailData =
            response.data.getInstallationOrderDetail.list || [];
          const processData =
            response.data.getInstallationOrderProcessLogByOrderId.list || [];
          this.form = {
            statusName: mainData.statusName || "",
            orderNo: mainData.orderNo || "",
            orderTime: mainData.orderTime || "",
            orderer: mainData.dispatcherId,
            serviceProject: mainData.projectId,
            projectName: mainData.projectName || "",
            serviceStaffNames: mainData.serviceStaffNames || "",
            serviceStaffIds: mainData.serviceStaffIds || "",
            estimatedCompleteTime: mainData.estimatedCompleteTime || "",
            deliveryNo: mainData.deliveryNo || "",
            contractNo: mainData.contractNo || "",
            customerName: mainData.customerName || "",
            remark: mainData.remark || "",
            totalQuantity: mainData.totalQuantity || 0,
            installedQuantity: mainData.installedQuantity || 0,
            uninstalledQuantity: mainData.uninstalledQuantity || 0,
            progress: mainData.progress || 0,
            acceptTime: mainData.acceptTime || "",
            actualCompleteTime: mainData.actualCompleteTime || "",
            remainingTime: mainData.remainingTime,
            serviceProgressData: this.form.serviceProgressData,
            products: detailData.map((item) => ({
              goodsId: item.goodsId,
              goodsCode: item.goodsCode || "",
              goodsName: item.goodsName || "",
              goodsSpecification: item.goodsSpecification || "",
              goodsImagePath: item.goodsImagePath || "",
              goodsUnit: item.goodsUnit || "",
              stock: item.stock || 0,
              orderQuantity: item.orderQuantity || 0,
              shippedQuantity: item.shippedQuantity || 0,
              unshippedQuantity: item.unshippedQuantity || 0,
              remark: item.remark || "",
              projectName: item.projectName || "",
              projectId: item.projectId || "",
            })),
            processData: processData,
            acceptanceImagePath: mainData.acceptanceImagePath || "",
            currentStep: mainData.currentStep || 2,
            isRejected: mainData.isRejected || true,
            rejectReason: mainData.rejectReason || "",
            startTime: mainData.startTime || "",
            acceptanceTime: mainData.acceptanceTime || "",
            createName: mainData.createName || "",
            dispatcherName: mainData.dispatcherName || "",
            contactName: mainData.contactName || "",
            contactPhone: mainData.contactPhone || "",
            goodsCode: mainData.goodsCode || "",
          };
        } else {
          this.$message.error("获取数据失败");
        }
      } catch (error) {
        console.error("获取数据失败:", error);
        this.$message.error("获取数据失败");
      }
    },
    async getOrderDailyData() {
      const [beginDate, endDate] = this.filterDate;
      try {
        const params = {
          name: "getInstallationDailyDetailByOrderId",
          returntype: "Map",
          parammaps: {
            orderId: this.rowData.id,
            beginDate: beginDate || "",
            endDate: endDate || "",
            staffId: this.filterStaff || "",
          },
        };

        const response = await GetDataByName(params);
        if (response.msg === "ok") {
          this.dateMergeGroups = [];
          this.mergeGroups = [];

          this.form.serviceProgressData = response.data.list || [];

          this.$nextTick(() => {
            const data = this.form.serviceProgressData;
            if (!data || !data.length) return;

            let dateGroup = {
              start: 0,
              count: 1,
            };

            let currentGroup = {
              start: 0,
              count: 1,
            };

            for (let i = 1; i < data.length; i++) {
              const currentRow = data[i - 1];
              const nextRow = data[i];

              if (currentRow.installDate === nextRow.installDate) {
                dateGroup.count++;
              } else {
                this.dateMergeGroups.push({ ...dateGroup });
                dateGroup = {
                  start: i,
                  count: 1,
                };
              }

              const isSameProduct =
                currentRow.goodsCode === nextRow.goodsCode &&
                currentRow.goodsName === nextRow.goodsName &&
                currentRow.orderQuantity === nextRow.orderQuantity &&
                currentRow.projectName === nextRow.projectName &&
                currentRow.unshippedQuantity === nextRow.unshippedQuantity &&
                currentRow.installDate === nextRow.installDate;

              if (isSameProduct) {
                currentGroup.count++;
              } else {
                this.mergeGroups.push({ ...currentGroup });
                currentGroup = {
                  start: i,
                  count: 1,
                };
              }
            }
            this.dateMergeGroups.push({ ...dateGroup });
            this.mergeGroups.push({ ...currentGroup });
          });
        } else {
          this.$message.error("获取数据失败");
        }
      } catch (error) {
        console.error("获取数据失败:", error);
        this.$message.error("获取数据失败");
      }
    },
    handleDialogClose() {
      this.$emit("update:visible", false);
    },
    getStepInfo(operationType) {
      const emptyResult = {
        operationUserName: "",
        createTime: "",
      };

      if (!this.form.processData || this.form.processData.length === 0) {
        return emptyResult;
      }

      const sortedData = this.form.processData.slice().sort((a, b) => {
        return new Date(b.createTime) - new Date(a.createTime);
      });

      const targetItem = sortedData.find(
        (item) => item.operationType === operationType
      );
      return targetItem || emptyResult;
    },
    getStepStatus(step) {
      if (this.isLastStepReject && step > 2) {
        return "wait";
      }
      if (step <= this.getActiveStep) {
        return "success";
      }
      return "wait";
    },
    handleSpanMethod({ row, column, rowIndex, columnIndex }) {
      const data = this.displayProgressData;
      if (!data || data.length === 0) {
        return;
      }

      if (columnIndex === 0) {
        const result = this.dateMergeGroups.find((group) => {
          return (
            rowIndex >= group.start && rowIndex < group.start + group.count
          );
        });

        if (result) {
          if (rowIndex === result.start) {
            return {
              rowspan: result.count,
              colspan: 1,
            };
          }
          return {
            rowspan: 0,
            colspan: 0,
          };
        }
      }

      if (columnIndex > 0 && columnIndex <= 5) {
        const result = this.mergeGroups.find((group) => {
          return (
            rowIndex >= group.start && rowIndex < group.start + group.count
          );
        });

        if (result) {
          if (rowIndex === result.start) {
            return {
              rowspan: result.count,
              colspan: 1,
            };
          }
          return {
            rowspan: 0,
            colspan: 0,
          };
        }
      }

      return {
        rowspan: 1,
        colspan: 1,
      };
    },
    async handleExport() {
      const params = {
        name: "getInstallationDailyDetailByOrderId",
        returntype: "Map",
        parammaps: {
          orderId: this.rowData.id,
          beginDate: "",
          endDate: "",
          staffId: "",
        },
      };
      let data = [];
      try {
        data = (await GetDataByName(params)).data.list || [];
        if (!data || data.length === 0) {
          this.$message.warning("暂无数据可导出");
          return;
        }
      } catch (error) {
        console.error("导出数据失败:", error);
        this.$message.error("导出数据失败");
        return;
      }

      const headers = [
        "序号",
        "服务单号",
        "客户",
        "预计完成时间",
        "服务人员",
        "项目名称",
        "日期",
        "货品",
        "计划总量",
        "累计完成量",
        "当天完成量",
        "剩余量",
        "备注",
      ];

      const rows = data.map((item, index) => [
        index + 1,
        this.form.orderNo || "",
        this.form.customerName || "",
        this.form.estimatedCompleteTime || "",
        item.installUserName || "",
        item.projectName || "",
        item.installDate || "",
        item.goodsName || "",
        parseInt(item.orderQuantity) || 0,
        parseInt(item.shippedQuantity) || 0,
        parseInt(item.installQuantity) || 0,
        parseInt(item.unshippedQuantity) < 0
          ? `超量 ${Math.abs(parseInt(item.unshippedQuantity))}`
          : parseInt(item.unshippedQuantity) || 0,
        item.installRemark || "",
      ]);

      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: 20 }, // 客户
        { wch: 20 }, // 预计完成时间
        { wch: 15 }, // 服务人员
        { wch: 20 }, // 项目名称
        { wch: 12 }, // 日期
        { wch: 30 }, // 货品
        { wch: 12 }, // 计划总量
        { wch: 12 }, // 累计完成量
        { wch: 12 }, // 当天完成量
        { wch: 12 }, // 剩余量
        { wch: 30 }, // 备注
      ];
      ws["!cols"] = colWidths;

      XLSX.utils.book_append_sheet(wb, ws, "服务记录");

      const fileName = `服务记录_${
        this.form.orderNo
      }_${this.getFormattedDateTime()}.xlsx`;

      XLSX.writeFile(wb, fileName);
    },
  },
};
</script>

<style lang="scss" scoped>
:deep(.el-dialog) {
  border-radius: 8px;

  .el-dialog__header {
    height: 0;
    padding: 0;
    position: relative;
    margin: 0;

    .el-dialog__headerbtn {
      position: absolute;
      top: 20px;
      right: 20px;
      z-index: 10;
    }
  }

  .el-dialog__body {
    padding: 0;

    .dialog-tabs {
      .el-tabs__header {
        margin: 0;
        padding: 10px 20px 0;
        background-color: #fff;
        border-radius: 8px 8px 0 0;
      }

      .el-tabs__content {
        padding: 20px;
      }
    }
  }

  .el-dialog__footer {
    padding: 15px 20px;
    border-top: 1px solid #ebeef5;
    text-align: right;

    .el-button {
      padding: 9px 20px;
      font-size: 13px;
      border-radius: 4px;
    }
  }
}

.progress-wrapper {
  padding: 0 10px;
  .progress-text {
    display: block;
    text-align: center;
    margin-bottom: 5px;
    color: #606266;
  }
  :deep(.el-progress-bar__outer) {
    background-color: #ebeef5;
  }
  :deep(.el-progress-bar__inner) {
    transition: all 0.3s;
  }
}

.table-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;

  .fold-button {
    padding: 0;
    font-size: 13px;
    color: #909399;

    span {
      margin-right: 4px;
    }

    &:hover {
      color: #409eff;
    }
  }
}

.acceptance-image {
  margin-top: 10px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;

  :deep(.el-image) {
    border-radius: 4px;
    overflow: hidden;
    border: 1px solid #ebeef5;
  }
}

.empty-image {
  width: 120px;
  height: 120px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background-color: #f5f7fa;
  color: #909399;
  font-size: 13px;
  border-radius: 4px;
  border: 1px solid #ebeef5;
}

.section-title {
  font-size: 15px;
  font-weight: 500;
  color: #303133;
  margin-bottom: 15px;
  position: relative;
  padding-left: 10px;

  &::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 3px;
    height: 15px;
    background-color: #409eff;
    border-radius: 2px;
  }
}

.process-steps {
  padding: 20px;
  background-color: #f8f9fb;
  border-radius: 4px;

  :deep(.el-steps) {
    .el-step {
      .el-step__title {
        font-size: 13px;
        line-height: 16px;
      }

      .el-step__description {
        min-width: 150px;
        padding: 0 10px;
        margin: 0 -10px;
      }
    }
  }

  .step-description {
    font-size: 12px;
    line-height: 1.5;
    min-width: 150px;

    div {
      width: 100%;
      word-break: break-all;
      white-space: normal;
    }

    div:first-child {
      color: #409eff;
      margin-bottom: 2px;
    }

    div:last-child {
      color: #909399;
    }
  }
}

.detail-section {
  padding-left: 20px;
}

.step-description {
  &.reject-status {
    color: #f56c6c;

    div:first-child {
      color: #f56c6c !important;
    }

    div:last-child {
      color: #f56c6c !important;
    }
  }
}

:deep(.el-steps) {
  .el-step.is-error {
    .el-step__title {
      font-size: 13px;
    }
    .el-step__description {
      color: #f56c6c;
    }
  }

  .el-step.is-wait {
    .el-step__title {
      font-size: 13px;
    }
    .el-step__description {
      color: #c0c4cc;
    }
  }
}

.service-progress {
  padding: 20px;
  background-color: #fff;
  border-radius: 4px;

  .progress-header {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    padding: 16px 20px;
    background-color: #f8f9fb;
    border-radius: 4px;

    .header-item {
      display: flex;
      align-items: center;

      .label {
        color: #606266;
        margin-right: 8px;
        font-size: 14px;
      }

      .value {
        color: #303133;
        font-weight: 500;
        font-size: 14px;
      }
    }
  }

  :deep(.el-table) {
    th {
      padding: 12px 0;
      font-size: 13px;
    }

    td {
      padding: 12px 0;
      font-size: 13px;
    }

    .red-text {
      color: #f56c6c;
    }
  }
}

:deep(.el-tabs__header) {
  margin-bottom: 20px;

  .el-tabs__item {
    font-size: 14px;
    height: 40px;
    line-height: 40px;

    &.is-active {
      font-weight: 500;
    }
  }
}

.filter-section {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin: 15px 0;
  padding: 0 20px;

  .filter-left {
    display: flex;
    align-items: center;

    :deep(.el-input__inner) {
      height: 32px;
      line-height: 32px;
    }

    :deep(.el-range-editor.el-input__inner) {
      height: 32px;
      line-height: 32px;
      padding: 0 10px;
    }

    :deep(.el-range-separator) {
      line-height: 24px;
      font-size: 12px;
    }

    :deep(.el-range__icon),
    :deep(.el-range__close-icon) {
      line-height: 24px;
    }

    :deep(.el-range-input) {
      height: 30px;
      line-height: 30px;
    }

    :deep(.el-select) {
      .el-input__inner {
        height: 32px;
        line-height: 32px;
      }
    }

    .el-button {
      height: 32px;
      padding: 8px 20px;
      font-size: 13px;
    }
  }

  .filter-right {
    .el-button {
      height: 32px;
      padding: 8px 20px;
      font-size: 13px;
    }
  }
}
</style>
