gaoluyang
昨天 352fbcfaa09e261918f5a7b50bcd9ba15583b1aa
src/views/salesManagement/returnOrder/index.vue
@@ -4,22 +4,22 @@
      <el-form :model="searchForm" class="demo-form-inline">
        <el-row :gutter="20">
          <el-col :span="4">
            <el-form-item>
            <el-form-item label="退货单号">
              <el-input v-model="searchForm.returnNo" placeholder="请输入退货单号" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="4">
            <el-form-item>
            <el-form-item label="客户名称">
              <el-input v-model="searchForm.customerName" placeholder="客户名称" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="4">
            <el-form-item>
            <el-form-item label="销售单号">
              <el-input v-model="searchForm.salesContractNo" placeholder="销售单号" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="4">
            <el-form-item>
            <el-form-item label="关联出库单号">
              <el-input v-model="searchForm.shippingNo" placeholder="关联出库单号" clearable />
            </el-form-item>
          </el-col>
@@ -33,46 +33,27 @@
      </el-form>
    </div>
    <div class="table_list">
      <div class="table_header" style="display:flex;justify-content:space-between;align-items:center;">
        <div>
          <el-button type="primary" @click="openForm('add')">新建销售退货</el-button>
        </div>
        <div>
          <el-button type="danger" plain @click="handleDelete">删除</el-button>
          <el-button @click="columnsDialogVisible = true">列表字段</el-button>
        </div>
      <div class="table_header" style="display: flex;justify-content: flex-end;margin-bottom: 10px;">
        <el-button type="primary" @click="openForm('add')">新建销售退货</el-button>
        <el-button type="danger" plain @click="handleDelete">删除</el-button>
      </div>
      <PIMTable
        rowKey="id"
        :column="visibleColumns"
        :column="tableColumn"
        :tableData="tableData"
        :page="page"
        :isSelection="true"
        @selection-change="handleSelectionChange"
        :tableLoading="tableLoading"
        @pagination="pagination"
      />
      >
        <template #status="{ row }">
          <el-tag :type="getStatusType(row.status)">{{ getStatusText(row.status) }}</el-tag>
        </template>
      </PIMTable>
    </div>
    <form-dia ref="formDia" @close="handleQuery" />
    <el-dialog v-model="columnsDialogVisible" title="自定义显示列项" width="600px">
      <div class="columns-tip">注:列表项显示不得少于5项;拖动右侧把手可调整显示顺序</div>
      <ul class="columns-list">
        <li v-for="(col, idx) in allColumns" :key="col.prop"
            class="columns-item"
            draggable="true"
            @dragstart="onDragStart(idx)"
            @dragover.prevent
            @drop="onDrop(idx)">
          <el-checkbox v-model="col.selected">{{ col.label }}</el-checkbox>
          <span class="drag-handle">≡</span>
        </li>
      </ul>
      <template #footer>
        <el-button @click="resetColumns">恢复默认</el-button>
        <el-button type="primary" @click="saveColumns">保存</el-button>
      </template>
    </el-dialog>
    <detail-dia ref="detailDia" />
  </div>
</template>
@@ -80,12 +61,18 @@
import { reactive, ref, toRefs, computed, getCurrentInstance, nextTick, onMounted } from "vue";
import { ElMessageBox } from "element-plus";
import FormDia from "./components/formDia.vue";
import DetailDia from "./components/detailDia.vue";
import { returnManagementList, returnManagementDel, returnManagementHandle } from "@/api/salesManagement/returnOrder.js";
const { proxy } = getCurrentInstance();
const formDia = ref();
const detailDia = ref();
const openForm = (type, row) => {
  nextTick(() => formDia.value?.openDialog(type, row));
};
const openDetail = (row) => {
  nextTick(() => detailDia.value?.openDialog(row));
};
const handleRowDelete = (row) => {
@@ -95,7 +82,7 @@
    cancelButtonText: "取消",
    type: "warning",
  }).then(() => {
    returnManagementDel({ ids: [row.id] }).then(() => {
    returnManagementDel([row.id]).then(() => {
      proxy.$modal.msgSuccess("删除成功");
      getList();
    });
@@ -132,86 +119,36 @@
const { searchForm } = toRefs(data);
const documentStatusOptions = ref([
  { label: "待审核", value: 0 },
  { label: "审核中", value: 1 },
  { label: "已审核", value: 2 }
  { label: "待处理", value: 0 },
  { label: "已处理", value: 1 }
]);
const defaultColumns = [
  { label: "退货单号", prop: "returnNo", minWidth: 160 },
  { label: "单据状态", prop: "status", minWidth: 120, formatData: (v) => ({ "0": "待审核", "1": "审核中", "2": "已审核" }[String(v)] ?? v) },
  { label: "制单时间", prop: "makeTime", minWidth: 170 },
  { label: "客户名称", prop: "customerName", minWidth: 220 },
  { label: "销售单号", prop: "salesContractNo", minWidth: 160 },
  { label: "业务员", prop: "salesman", minWidth: 120 },
  { label: "关联出库单号", prop: "shippingNo", minWidth: 170 },
  { label: "项目名称", prop: "projectName", minWidth: 180 },
  { label: "项目阶段", prop: "projectStage", minWidth: 120 },
  { label: "制单人", prop: "maker", minWidth: 120 },
  { label: "结算人", prop: "settler", minWidth: 120 },
  { label: "退货单号", prop: "returnNo", width: 160 },
  { label: "单据状态", prop: "status", width: 90, dataType: "slot", slot: "status" },
  { label: "制单时间", prop: "makeTime", width: 170 },
  { label: "客户名称", prop: "customerName", width: 220 },
  { label: "销售单号", prop: "salesContractNo", width: 160 },
  { label: "业务员", prop: "salesman", width: 120 },
  { label: "关联出库单号", prop: "shippingNo", width: 170 },
  { label: "项目名称", prop: "projectName", width: 180 },
  { label: "制单人", prop: "maker", width: 120 },
  {
    label: "操作",
    prop: "operation",
    dataType: "action",
    align: "center",
    fixed: "right",
    width: 160,
    width: 240,
    operation: [
      { name: "编辑", disabled: (row) => row.status !== 0, type: "text", clickFun: (row) => openForm("edit", row) },
      { name: "处理", disabled: (row) => row.status !== 0, type: "text", clickFun: (row) => handleRowHandle(row) },
      { name: "退款处理", disabled: (row) => row.status !== 0, type: "text", clickFun: (row) => handleRowHandle(row) },
      { name: "详情", type: "text", clickFun: (row) => openDetail(row) },
      { name: "删除", disabled: (row) => row.status !== 0, type: "text", clickFun: (row) => handleRowDelete(row) },
    ],
  },
];
const COLUMNS_KEY = "return_order_columns_v2";
const columnsDialogVisible = ref(false);
const allColumns = ref([]);
const initColumns = () => {
  const saved = localStorage.getItem(COLUMNS_KEY);
  if (saved) {
    try {
      const parsed = JSON.parse(saved);
      // 合并默认列与已保存配置,避免后续新增列丢失
      const map = new Map(parsed.map(c => [c.prop, c]));
      allColumns.value = defaultColumns.map(d => {
        const found = map.get(d.prop);
        return { ...d, selected: found ? !!found.selected : true };
      });
      // 以保存的顺序为准
      const order = parsed.map(p => p.prop);
      allColumns.value.sort((a, b) => order.indexOf(a.prop) - order.indexOf(b.prop));
      return;
    } catch {}
  }
  allColumns.value = defaultColumns.map(c => ({ ...c, selected: true }));
};
initColumns();
const visibleColumns = computed(() => allColumns.value.filter(c => c.selected));
let dragFrom = -1;
const onDragStart = (idx) => {
  dragFrom = idx;
};
const onDrop = (to) => {
  if (dragFrom < 0 || dragFrom === to) return;
  const arr = [...allColumns.value];
  const [moved] = arr.splice(dragFrom, 1);
  arr.splice(to, 0, moved);
  allColumns.value = arr;
  dragFrom = -1;
};
const resetColumns = () => {
  allColumns.value = defaultColumns.map(c => ({ ...c, selected: true }));
  localStorage.removeItem(COLUMNS_KEY);
};
const saveColumns = () => {
  const toSave = allColumns.value.map(({ label, prop, width, selected }) => ({ label, prop, width, selected }));
  localStorage.setItem(COLUMNS_KEY, JSON.stringify(toSave));
  columnsDialogVisible.value = false;
};
const tableColumn = defaultColumns;
const tableData = ref([]);
const tableLoading = ref(false);
@@ -221,6 +158,7 @@
const handleReset = () => {
  Object.keys(searchForm.value).forEach(k => searchForm.value[k] = "");
  handleQuery();
};
const handleSelectionChange = (selection) => {
  selectedRows.value = selection;
@@ -265,6 +203,22 @@
  });
};
const getStatusType = (status) => {
  const statusMap = {
    0: "warning",
    1: "success"
  };
  return statusMap[status] || "info";
};
const getStatusText = (status) => {
  const statusMap = {
    0: "待处理",
    1: "已处理"
  };
  return statusMap[status] || "未知";
};
onMounted(() => {
  getList();
});
@@ -276,20 +230,5 @@
  padding: 1rem 1rem 0 1rem;
  border: 8px;
  border-radius: 16px;
}
.table_list {
  height: calc(100vh - 230px);
  min-height: 360px;
  background: #fff;
  margin-top: 20px;
  display: flex;
  flex-direction: column;
}
.columns-tip{color:#909399;margin-bottom:10px;font-size:12px;}
.columns-list{list-style:none;padding:0;margin:0;max-height:360px;overflow:auto;}
.columns-item{display:flex;justify-content:space-between;align-items:center;padding:8px 10px;border:1px solid #f0f0f0;border-radius:6px;margin-bottom:8px;cursor:move;background:#fff;}
.columns-item .drag-handle{color:#909399;padding-left:12px;user-select:none;}
.table_header {
  margin-bottom: 15px;
}
</style>