d98d62b4149bd7efd7898299925c14058a93fda1..193af68d72a71268054f7d07395c2ea11210ecc1
2 天以前 张诺
提交基础信息 三个模块 提交采购管理
193af6 对比 | 目录
2 天以前 gaoluyang
用户管理修改
8b287d 对比 | 目录
已修改4个文件
已添加10个文件
2537 ■■■■■ 文件已修改
src/components/Table/ETable.vue 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/useFormData.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/usePaginationApi.jsx 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/Settings/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/modules/settings.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicInformation/index.vue 528 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicInformation/indexs.vue 541 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicInformation/mould/coal.vue 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicInformation/mould/customer.vue 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicInformation/mould/supplier.vue 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procureMent/components/ProductionDialog.vue 253 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procureMent/index.vue 308 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/user/index.vue 107 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tool/build/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Table/ETable.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,182 @@
<template>
    <el-table
      v-loading="loading"
      :data="tableData"
      style="width: 100%"
      :border="border"
      :show-selection="showSelection"
      :max-height="maxHeight"
      @selection-change="handleSelectionChange"
      @row-click="handleRowClick"
      @row-dblclick="handleRowDblClick"
      @cell-click="handleCellClick"
      :max-width="maxWidth"
      @export="handleExport"
    >
      <el-table-column v-if="showSelection" type="selection" width="55" align="center" />
      <el-table-column v-if="showIndex" label="序号" type="index" width="60" align="center" />
      <template v-for="col in columns" :key="col.prop">
        <el-table-column
          v-bind="col"
          :show-overflow-tooltip="col.showOverflowTooltip !== false"
        >
          <template v-if="col.slot" #default>
            <slot></slot>
          </template>
        </el-table-column>
      </template>
      <!-- æ“ä½œåˆ— -->
      <el-table-column v-if="showOperations" :label="operationsLabel" :width="operationsWidth" fixed="right">
        <template #default="scope">
          <slot name="operations" :row="scope.row">
            <el-button
              v-if="operations.includes('edit')"
              link
              type="primary"
              size="small"
              @click="handleEdit(scope.row)"
            >编辑</el-button>
            <el-button
              v-if="operations.includes('delete')"
              link
              type="danger"
              size="small"
              @click="handleDelete(scope.row)"
            >删除</el-button>
          </slot>
        </template>
      </el-table-column>
    </el-table>
  </template>
  <script setup>
  import { defineEmits } from 'vue'
  import { ElMessage, ElMessageBox } from 'element-plus'
  const props = defineProps({
    // æœ€å¤§å®½åº¦
    maxWidth: {
      type: [String, Number],
      default: 'auto'
    },
    handleCellClick: {
      type: Function,
      default: () => {}
    },
    handleRowClick: {
      type: Function,
      default: () => {}
    },
    handleExport: {
      type: Function,
      default: () => {}
    },
    handleRowDblClick: {
      type: Function,
      default: () => {}
    },
    // é«˜åº¦
    maxHeight: {
      type: [String, Number],
      default: 'auto'
    },
    // åŠ è½½çŠ¶æ€
    loading: {
      type: Boolean,
      default: false
    },
    //   border
    border: {
      type: Boolean,
      default: false
    },
    // è¡¨æ ¼æ•°æ®
    tableData: {
      type: Array,
      default: () => []
    },
    // æ˜¯å¦æ˜¾ç¤ºé€‰æ‹©åˆ—
    showSelection: {
      type: Boolean,
      default: true
    },
    // æ˜¯å¦æ˜¾ç¤ºåºå·åˆ—
    showIndex: {
      type: Boolean,
      default: true
    },
    // åˆ—配置
    columns: {
      type: Array,
      default: () => []
    },
    // æ˜¯å¦æ˜¾ç¤ºæ“ä½œåˆ—
    showOperations: {
      type: Boolean,
      default: true
    },
    // æ“ä½œåˆ—标签
    operationsLabel: {
      type: String,
      default: '操作'
    },
    // æ“ä½œåˆ—宽度
    operationsWidth: {
      type: [String, Number],
      default: 160
    },
    // æ˜¾ç¤ºå“ªäº›æ“ä½œæŒ‰é’®
    operations: {
      type: Array,
      default: () => ['edit', 'delete', 'export']
    },
    // åˆ é™¤ç¡®è®¤ä¿¡æ¯
    deleteConfirmText: {
      type: String,
      default: '确认删除该记录?'
    }
  })
  const emit = defineEmits(['selection-change', 'edit', 'delete', 'export'])
  const handleSelectionChange = (selection) => {
    emit('selection-change', selection)
  }
  const handleEdit = (row) => {
    emit('edit', row)
  }
  const handleDelete = (row) => {
    ElMessageBox.confirm(
      props.deleteConfirmText,
      '警告',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    ).then(() => {
      emit('delete', row)
    }).catch(() => {})
  }
  const handleExport = (row) => {
    emit('export', row)
  }
  </script>
  <style scoped>
  :deep(.el-table) {
    margin-bottom: 20px;
    overflow-x: auto;
  }
  :deep(.el-table th) {
    background-color: #f5f7fa;
  }
  /* å“åº”式样式 */
  @media screen and (max-width: 768px) {
    :deep(.el-table) {
      width: 100%;
      overflow-x: auto;
    }
  }
  </style>
src/hooks/useFormData.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
import { reactive } from "vue";
import { clone } from "lodash";
export default function useFormData(initData) {
  const form = reactive(clone(initData, true));
  function resetForm() {
    const initData2 = JSON.parse(JSON.stringify(initData));
    Object.keys(initData).forEach(key => {
      form[key] = initData2[key];
    });
  }
  return { form, resetForm };
}
src/hooks/usePaginationApi.jsx
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,145 @@
import { ref, reactive, watchEffect, unref } from "vue";
import useFormData from "./useFormData.js";
// import { message } from "@/utils/message";
import { clone, isEqual } from "lodash";
/**
 * åˆ†é¡µapi
 * @param api æŽ¥å£
 * @param initalFilters åˆå§‹åŒ–筛选条件
 * @param sorters
 * @param filterTransformer
 */
export function usePaginationApi(
  api,
  initalFilters,
  columns,
  sorters,
  filterTransformer,
  cb
) {
  const dataList = ref([]);
  const { form: filters, resetForm } = useFormData(initalFilters);
  let lastFilters = clone(initalFilters);
  const sorter = reactive(sorters || {});
  const others = ref({});
  const loading = ref(true);
  const paginationAlign = ref("right");
  /** åˆ†é¡µé…ç½® */
  const pagination = reactive({
    pageSize: 10,
    currentPage: 1,
    pageSizes: [10, 15, 20],
    total: 0,
    align: "right",
    background: true
  });
  /** åŠ è½½åŠ¨ç”»é…ç½® */
  const loadingConfig = reactive({
    text: "正在加载第一页...",
    viewBox: "-10, -10, 50, 50",
    spinner: `
        <path class="path" d="
          M 30 15
          L 28 17
          M 25.61 25.61
          A 15 15, 0, 0, 1, 15 30
          A 15 15, 0, 1, 1, 27.99 7.5
          L 15 15
        " style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)"/>
      `
    // svg: "",
    // background: rgba()
  });
  function getFinalParams() {
    const finalFilters = {};
    const beforeParams = unref(filters);
    if (filterTransformer) {
      Object.keys(beforeParams).forEach(key => {
        if (filterTransformer[key]) {
          Object.assign(
            finalFilters,
            filterTransformer[key](beforeParams[key], beforeParams)
          );
        } else {
          finalFilters[key] = beforeParams[key];
        }
      });
    }
    return filterTransformer
      ? { ...finalFilters, ...sorter }
      : { ...beforeParams, ...sorter };
  }
  async function getTableData() {
    // å¦‚果这次和上次的filter不同,那么就重置页码
    if (!isEqual(unref(filters), lastFilters)) {
      pagination.currentPage = 1;
      lastFilters = clone(unref(filters));
    }
    loading.value = true;
    api({
      ...getFinalParams(),
      current: pagination.currentPage,
      size: pagination.pageSize
    }).then(({ code, data, ...rest }) => {
      if (code == 200) {
        // pagination.currentPage = meta.current_page;
        // pagination.pageSize = meta.per_page;
        pagination.total = data.total;
        others.value = rest;
        dataList.value = data.records;
        cb && cb(data);
        loading.value = false;
      } else {
        loading.value = false;
        // message(data.msg, { type: "error" });
      }
    });
  }
  function onSizeChange(val) {
    pagination.pageSize = val;
    pagination.currentPage = 1;
    getTableData();
  }
  function onCurrentChange(val) {
    loadingConfig.text = `正在加载第${val}页...`;
    loading.value = true;
    getTableData();
  }
  function resetFilters() {
    resetForm();
    pagination.currentPage = 1;
    getTableData();
  }
  watchEffect(() => {
    pagination.align = paginationAlign.value;
  });
  // onMounted(() => {
  //   getTableData();
  // });
  return {
    loading,
    columns,
    dataList,
    pagination,
    loadingConfig,
    paginationAlign,
    filters,
    sorter,
    others,
    onSizeChange,
    onCurrentChange,
    getTableData,
    resetFilters
  };
}
src/layout/components/Settings/index.vue
@@ -108,7 +108,7 @@
}
function themeChange(val) {
  settingsStore.theme = val
  settingsStore.theme = '165DFF'
  handleThemeStyle(val)
}
src/store/modules/settings.js
@@ -14,7 +14,7 @@
  {
    state: () => ({
      title: '',
      theme: storageSetting.theme || '#409EFF',
      theme: storageSetting.theme || '#165DFF',
      sideTheme: storageSetting.sideTheme || sideTheme,
      showSettings: showSettings,
      topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
src/views/basicInformation/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,528 @@
<template>
  <div class="app-container">
      <el-form :inline="true" :model="queryParams" class="search-form">
        <el-form-item label="搜索">
          <el-input
            v-model="queryParams.searchText"
            placeholder="请输入关键词"
            clearable
            :style="{ width: '100%' }"
          />
        </el-form-item>
        <el-form-item label="供应商名称">
          <el-input
            v-model="queryParams.supplierName"
            placeholder="请输入"
            clearable
            :style="{ width: '100%' }"
          />
        </el-form-item>
        <el-form-item label="统一人识别号">
          <el-input
            v-model="queryParams.identifyNumber"
            placeholder="请输入"
            clearable
            :style="{ width: '100%' }"
          />
        </el-form-item>
        <el-form-item label="经营地址">
          <el-input
            v-model="queryParams.address"
            placeholder="请输入"
            clearable
            :style="{ width: '100%' }"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleQuery">查询</el-button>
          <el-button @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>
    <el-card>
      <!-- æ ‡ç­¾é¡µ -->
      <el-tabs
        v-model="activeTab"
        class="info-tabs"
        @tab-click="handleTabClick"
      >
        <el-tab-pane
          v-for="tab in tabs"
          :key="tab.name"
          :label="tab.label"
          :name="tab.name"
        />
      </el-tabs>
      <!-- æ“ä½œæŒ‰é’®åŒº -->
      <el-row :gutter="24" class="table-toolbar">
        <el-button type="primary" :icon="Plus" @click="handleAdd"
          >新建</el-button
        >
        <el-button type="danger" :icon="Delete" @click="handleDelete">删除</el-button>
        <el-button type="info" :icon="Download" @click="handleExport">导出</el-button>
      </el-row>
      <!-- è¡¨æ ¼ç»„ä»¶ -->
      <div>
        <data-table
          :loading="loading"
          :table-data="tableData"
          :columns="columns"
          @selection-change="handleSelectionChange"
          @edit="handleEdit"
          @delete="handleDeleteSuccess"
          :show-selection="true"
          :border="true"
          :maxHeight="440"
        />
      </div>
      <pagination
        v-if="total>0"
        :page-num="pageNum"
        :page-size="pageSize"
        :total="total"
        @pagination="handleQuery"
        :layout="'total, prev, pager, next, jumper'"
      />
      <Supplier
        v-if="tabName === 'supplier'"
        v-model:supplierDialogFormVisible="dialogFormVisible"
        :form="form"
        :title="title"
        @submit="handleSubmit"
        @beforeClose="handleBeforeClose"
        @update:dialogFormVisible="handleDialogFormVisible"
        :addOrEdit="addOrEdit"
      />
      <Customer
        v-if="tabName === 'customer'"
        v-model:customerDialogFormVisible="dialogFormVisible"
        :form="form"
        :title="title"
        @submit="handleSubmit"
        @beforeClose="handleBeforeClose"
      />
      <Coal
        v-if="tabName === 'coal'"
        v-model:coalDialogFormVisible="dialogFormVisible"
        :form="form"
        :title="title"
        @submit="handleSubmit"
      />
    </el-card>
  </div>
</template>
<script setup>
import { ref, reactive, onMounted } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { Plus, Edit, Delete, Download } from "@element-plus/icons-vue";
import DataTable from "@/components/Table/ETable.vue";
import Pagination from "@/components/Pagination";
import Supplier from "./mould/supplier.vue";
import Customer from "./mould/customer.vue";
import Coal from "./mould/coal.vue";
const { proxy } = getCurrentInstance()
// å¼¹çª—
const customerDialogFormVisible = ref(false);
const coalDialogFormVisible = ref(false);
const supplierDialogFormVisible = ref(false);
const dialogFormVisible = ref(false);
const form = ref({});
const title = ref("");
const copyForm = ref({});
// å½“前标签
const tabName = ref("supplier");
// çŠ¶æ€å˜é‡
const loading = ref(false);
const total = ref(200);
const pageNum = ref(1);
const pageSize = ref(10);
const activeTab = ref("supplier");
const selectedRows = ref([]);
// æŸ¥è¯¢å‚æ•°
const queryParams = reactive({
  searchText: "",
  supplierName: "",
  identifyNumber: "",
  address: "",
});
onMounted(() => {
  handleTabClick({ props: { name: "supplier" } });
});
const columns = ref();
// æ ‡ç­¾é¡µæ•°æ®
const tabs = reactive([
  { name: "supplier", label: "供应商信息" },
  { name: "customer", label: "客户信息" },
  { name: "coal", label: "煤种信息" },
]);
// æ˜¯å¦ç¼–辑
const addOrEdit = ref("add");
// è¡¨æ ¼æ•°æ®
const tableData = ref([]);
// æ–¹æ³•定义
const handleQuery = () => {
  loading.value = true;
  setTimeout(() => {
    loading.value = false;
  }, 500);
};
// supplier ä¾›åº”商数据
const supplierColumns = reactive([
  { prop: "supplierName", label: "供应商名称", minWidth: 200 },
  { prop: "identifyNumber", label: "统一人识别号", minWidth: 120 },
  { prop: "address", label: "经营地址", minWidth: 150 },
  { prop: "bank", label: "开户行", minWidth: 120 },
  { prop: "bankAccount", label: "银行账号", minWidth: 150 },
  { prop: "contacts", label: "联系人", minWidth: 100 },
  { prop: "contactAddress", label: "联系地址", minWidth: 150 },
  { prop: "maintainer", label: "维护人", minWidth: 100 },
  { prop: "maintainDate", label: "维护日期", minWidth: 100 },
]);
// customer å®¢æˆ·æ•°æ®
const customerColumns = reactive([
  { prop: "customerName", label: "客户名称", minWidth: 200 },
  { prop: "identifyNumber", label: "统一人识别号", minWidth: 120 },
  { prop: "address", label: "经营地址", minWidth: 150 },
  { prop: "bank", label: "开户行", minWidth: 120 },
  { prop: "bankAccount", label: "银行账号", minWidth: 150 },
  { prop: "contacts", label: "联系人", minWidth: 100 },
  { prop: "contactAddress", label: "联系地址", minWidth: 150 },
  { prop: "maintainer", label: "维护人", minWidth: 100 },
  { prop: "maintainDate", label: "维护日期", minWidth: 100 },
]);
// coal ç…¤ç§æ•°æ®
const coalColumns = reactive([
  { prop: "coalName", label: "煤种名称", minWidth: 200 },
  { prop: "maintainer", label: "维护人", minWidth: 120 },
  { prop: "maintenanceDate", label: "维护日期", minWidth: 150 },
]);
// æ ‡ç­¾é¡µç‚¹å‡»
const handleTabClick = (tab) => {
  form.value = {};
  getList();
  addOrEdit.value = "add";
  loading.value = true;
  tabName.value = tab.props.name;
  tableData.value = [];
  getList();
  switch (tabName.value) {
    case "supplier":
      columns.value = supplierColumns;
      dialogFormVisible.value = supplierDialogFormVisible.value;
      break;
    case "customer":
      columns.value = customerColumns;
      dialogFormVisible.value = customerDialogFormVisible.value;
      break;
    case "coal":
      columns.value = coalColumns;
      dialogFormVisible.value = coalDialogFormVisible.value;
      break;
  }
  setTimeout(() => {
    loading.value = false;
  }, 500);
};
// é‡ç½®æŸ¥è¯¢
const resetQuery = () => {
  Object.keys(queryParams).forEach((key) => {
    if (key !== "pageNum" && key !== "pageSize") {
      queryParams[key] = "";
    }
  });
  handleQuery();
};
// æ–°å¢ž
const handleAdd = () => {
  addOrEdit.value = "add";
  handleAddEdit(tabName.value);
};
// æ–°å¢žç¼–辑
const handleAddEdit = (tabName) => {
  addOrEdit.value == "add" ? (title.value = "新增") : (title.value = "编辑");
  if (tabName === "supplier") {
    dialogFormVisible.value = true;
    title.value = title.value + "供应商信息";
    openDialog();
  } else if (tabName === "customer") {
    dialogFormVisible.value = true;
    title.value = title.value + "客户信息";
    openDialog();
  } else if (tabName === "coal") {
    dialogFormVisible.value = true;
    title.value = title.value + "煤种信息";
    openDialog();
  }
};
// æ‰“开弹窗
const openDialog = () => {
  if (addOrEdit.value === "edit") {
    copyForm.value = JSON.parse(JSON.stringify(form.value));
    dialogFormVisible.value = true;
    return;
  }
  form.value = {};
  dialogFormVisible.value = true;
};
// æäº¤è¡¨å•
const handleSubmit = (val) => {
  // æ‹¿åˆ°æäº¤æ•°æ®
  dialogFormVisible.value = false;
  getList();
};
const handleDialogFormVisible = (value) => {
  dialogFormVisible.value = value;
};
// é€‰æ‹©è¡Œ
const handleSelectionChange = (selection) => {
  selectedRows.value = selection;
};
// ç¼–辑
const handleEdit = (row) => {
    form.value = JSON.parse(JSON.stringify(row));
    addOrEdit.value = "edit";
    handleAddEdit(tabName.value);
};
// æ‰¹é‡åˆ é™¤
const handleDelete = () => {
  if (selectedRows.value.length === 0) {
    ElMessage.warning("请选择要删除的数据");
    return;
  }
  ElMessageBox.confirm("确定删除选中的数据吗?", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(() => {
      ElMessage.success("删除成功,共删除" + selectedRows.value.length + "条数据");
      selectedRows.value.forEach((row) => {
        tableData.value = tableData.value.filter(
          (item) => item !== row
        );
      });
      total.value = tableData.value.length;
      // æ¸…空选中行
      selectedRows.value = [];
  }).catch(() => {
    ElMessage.info("已取消删除操作");
  });
}
// è¡¨æ ¼åˆ é™¤
const handleDeleteSuccess = (row) => {
  ElMessage.success("删除成功:" + row.supplierName);
};
// å…³é—­å¼¹çª—
const handleBeforeClose = () => {
  dialogFormVisible.value = false;
  form.value = {};
};
const handleExport = (row) => {
  proxy.download("system/post/export", {
    ...queryParams.value
  }, `post_${new Date().getTime()}.xlsx`)
  ElMessage.success("导出数据:" + row.supplierName);
};
const getList = () => {
  loading.value = true;
  setTimeout(() => {
    // æš‚时引入测试数据
    tableData.value = [
      {
        supplierName: "中国冶金科工股份有限公司",
        identifyNumber: "123412123123123111",
        address: "山西省",
        bank: "交通银行",
        bankAccount: "901234567890123456",
        contacts: "李雪芹",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "李雪芹",
        maintainDate: "2022-09-26",
        contactsPhone: "19345678901",
      },
      {
        supplierName: "中国冶金科工股份有限公司",
        identifyNumber: "123412123123123111",
        address: "山西省",
        bank: "交通银行",
        bankAccount: "901234567890123456",
        contacts: "李雪芹",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "李雪芹",
        maintainDate: "2022-09-26",
        contactsPhone: "19345678901",
      },
      {
        supplierName: "中国冶金科工股份有限公司",
        identifyNumber: "123412123123123111",
        address: "山西省",
        bank: "交通银行",
        bankAccount: "901234567890123456",
        contacts: "李雪芹",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "李雪芹",
        maintainDate: "2022-09-26",
        contactsPhone: "19345678901",
      },
      {
        supplierName: "交通银行股份有限公司",
        identifyNumber: "042-26881314",
        address: "江西省",
        bank: "平安银行",
        bankAccount: "123456789012345678",
        contacts: "周白玉",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "周白玉",
        maintainDate: "2022-08-29",
      },
      {
        supplierName: "中国冶金科工股份有限公司",
        identifyNumber: "019-65851198",
        address: "山西省",
        bank: "交通银行",
        bankAccount: "901234567890123456",
        contacts: "李雪芹",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "李雪芹",
        maintainDate: "2022-09-26",
      },
      {
        supplierName: "交通银行股份有限公司",
        identifyNumber: "042-26881314",
        address: "江西省",
        bank: "平安银行",
        bankAccount: "123456789012345678",
        contacts: "周白玉",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "周白玉",
        maintainDate: "2022-08-29",
      },
      {
        supplierName: "中国冶金科工股份有限公司",
        identifyNumber: "019-65851198",
        address: "山西省",
        bank: "交通银行",
        bankAccount: "901234567890123456",
        contacts: "李雪芹",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "李雪芹",
        maintainDate: "2022-09-26",
      },
      {
        supplierName: "交通银行股份有限公司",
        identifyNumber: "042-26881314",
        address: "江西省",
        bank: "平安银行",
        bankAccount: "123456789012345678",
        contacts: "周白玉",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "周白玉",
        maintainDate: "2022-08-29",
      },
      {
        supplierName: "中国冶金科工股份有限公司",
        identifyNumber: "019-65851198",
        address: "山西省",
        bank: "交通银行",
        bankAccount: "901234567890123456",
        contacts: "李雪芹",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "李雪芹",
        maintainDate: "2022-09-26",
      },
      {
        supplierName: "交通银行股份有限公司",
        identifyNumber: "042-26881314",
        address: "江西省",
        bank: "平安银行",
        bankAccount: "123456789012345678",
        contacts: "周白玉",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "周白玉",
        maintainDate: "2022-08-29",
      },
      {
        supplierName: "中国冶金科工股份有限公司",
        identifyNumber: "019-65851198",
        address: "山西省",
        bank: "交通银行",
        bankAccount: "901234567890123456",
        contacts: "李雪芹",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "李雪芹",
        maintainDate: "2022-09-26",
      },
      {
        supplierName: "交通银行股份有限公司",
        identifyNumber: "042-26881314",
        address: "江西省",
        bank: "平安银行",
        bankAccount: "123456789012345678",
        contacts: "周白玉",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "周白玉",
        maintainDate: "2022-08-29",
      },
    ];
    total.value = tableData.value.length;
    loading.value = false;
  }, 500);
};
getList();
</script>
<style scoped>
.app-container{
  box-sizing: border-box;
}
.search-form {
  background-color: #fff;
  padding: 20px 20px 0 20px;
  margin-bottom: 20px;
  border-radius: 4px;
  box-shadow: var(--el-box-shadow-light);
}
.search-form :deep(.el-form-item) {
  margin-bottom: 16px;
  width: 100%;
}
/* å“åº”式布局 */
@media screen and (min-width: 768px) {
  .search-form :deep(.el-form-item) {
    width: 50%;
  }
}
@media screen and (min-width: 1200px) {
  .search-form :deep(.el-form-item) {
    width: 18%;
  }
}
.info-tabs {
  margin-bottom: 20px;
}
.table-toolbar {
  margin-bottom: 20px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
/* å“åº”式表格 */
@media screen and (max-width: 768px) {
  .table-toolbar {
    flex-direction: column;
  }
  .table-toolbar .el-button {
    width: 100%;
  }
}
/* è¡¨æ ¼å·¥å…·æ  */
.table-toolbar, .table-toolbar > * {
  margin: 0 0 0 0 !important;
}
.table-toolbar{
  margin-bottom: 20px !important;
}
</style>
src/views/basicInformation/indexs.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,541 @@
<template>
  <div class="app-container">
      <el-form :inline="true" :model="queryParams" class="search-form">
        <el-form-item label="搜索">
          <el-input
            v-model="queryParams.searchText"
            placeholder="请输入关键词"
            clearable
            :style="{ width: '100%' }"
          />
        </el-form-item>
        <el-form-item label="供应商名称">
          <el-input
            v-model="queryParams.supplierName"
            placeholder="请输入"
            clearable
            :style="{ width: '100%' }"
          />
        </el-form-item>
        <el-form-item label="统一人识别号">
          <el-input
            v-model="queryParams.identifyNumber"
            placeholder="请输入"
            clearable
            :style="{ width: '100%' }"
          />
        </el-form-item>
        <el-form-item label="经营地址">
          <el-input
            v-model="queryParams.address"
            placeholder="请输入"
            clearable
            :style="{ width: '100%' }"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleQuery">查询</el-button>
          <el-button @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>
    <el-card>
      <!-- æ ‡ç­¾é¡µ -->
      <el-tabs
        v-model="activeTab"
        class="info-tabs"
        @tab-click="handleTabClick"
      >
        <el-tab-pane
          v-for="tab in tabs"
          :key="tab.name"
          :label="tab.label"
          :name="tab.name"
        />
      </el-tabs>
      <!-- æ“ä½œæŒ‰é’®åŒº -->
      <el-row :gutter="24" class="table-toolbar">
        <el-button type="primary" :icon="Plus" @click="handleAdd"
          >新建</el-button
        >
        <el-button type="danger" :icon="Delete">删除</el-button>
        <el-button type="info" :icon="Download" @click="handleExport">导出</el-button>
      </el-row>
      <!-- è¡¨æ ¼ç»„ä»¶ -->
      <div>
        <data-table
          :loading="loading"
          :table-data="tableData"
          :columns="columns"
          @selection-change="handleSelectionChange"
          @edit="handleEdit"
          @delete="handleDeleteSuccess"
          :show-selection="true"
          :border="true"
          :maxHeight="440"
        />
      </div>
      <pagination
        v-if="total>0"
        :page-num="queryParams.pageNum"
        :page-size="queryParams.pageSize"
        :total="total"
        @pagination="handleQuery"
        :layout="'total, prev, pager, next, jumper'"
      />
      <Supplier
        v-if="tabName === 'supplier'"
        v-model:supplierDialogFormVisible="dialogFormVisible"
        :form="form"
        :title="title"
        @submit="handleSubmit"
        @beforeClose="handleBeforeClose"
        @update:dialogFormVisible="handleDialogFormVisible"
        :addOrEdit="addOrEdit"
      />
      <Customer
        v-if="tabName === 'customer'"
        v-model:customerDialogFormVisible="dialogFormVisible"
        :form="form"
        :title="title"
        @submit="handleSubmit"
        @beforeClose="handleBeforeClose"
      />
      <Coal
        v-if="tabName === 'coal'"
        v-model:coalDialogFormVisible="dialogFormVisible"
        :form="form"
        :title="title"
        @submit="handleSubmit"
      />
    </el-card>
  </div>
</template>
<script setup>
import { usePaginationApi } from "../../../hooks/usePaginationApi";
import { ref, reactive, onMounted } from "vue";
import { ElMessage } from "element-plus";
import { Plus, Edit, Delete, Download } from "@element-plus/icons-vue";
import DataTable from "@/components/Table/ETable.vue";
import Pagination from "@/components/Pagination";
import Supplier from "./mould/supplier.vue";
import Customer from "./mould/customer.vue";
import Coal from "./mould/coal.vue";
const { proxy } = getCurrentInstance()
const {
  columns
} = usePaginationApi(()=> {
  // åˆ†é¡µé€»è¾‘可以在这里处理
},{
  searchText: "",
  supplierName: "",
  identifyNumber: "",
  address: "",
  pageNum: 1,
  pageSize: 10,
},[
  { prop: "supplierName", label: "供应商名称", minWidth: 200 },
  { prop: "identifyNumber", label: "统一人识别号", minWidth: 120 },
  { prop: "address", label: "经营地址", minWidth: 150 },
  { prop: "bank", label: "开户行", minWidth: 120 },
  { prop: "bankAccount", label: "银行账号", minWidth: 150 },
  { prop: "contacts", label: "联系人", minWidth: 100 },
  { prop: "contactAddress", label: "联系地址", minWidth: 150 },
  { prop: "maintainer", label: "维护人", minWidth: 100 },
  { prop: "maintainDate", label: "维护日期", minWidth: 100 },
]);
// å¼¹çª—
const customerDialogFormVisible = ref(false);
const coalDialogFormVisible = ref(false);
const supplierDialogFormVisible = ref(false);
const dialogFormVisible = ref(false);
const form = ref({});
const title = ref("");
const copyForm = ref({});
// å½“前标签
const tabName = ref("supplier");
// çŠ¶æ€å˜é‡
const loading = ref(false);
const total = ref(200);
const activeTab = ref("supplier");
const selectedRows = ref([]);
// æŸ¥è¯¢å‚æ•°
const queryParams = reactive({
  searchText: "",
  supplierName: "",
  identifyNumber: "",
  address: "",
  pageNum: 1,
  pageSize: 10,
});
onMounted(() => {
  handleTabClick({ props: { name: "supplier" } });
});
// æ ‡ç­¾é¡µæ•°æ®
const tabs = reactive([
  { name: "supplier", label: "供应商信息" },
  { name: "customer", label: "客户信息" },
  { name: "coal", label: "煤种信息" },
]);
// æ˜¯å¦ç¼–辑
const addOrEdit = ref("add");
// è¡¨æ ¼æ•°æ®
const tableData = ref([]);
// æ–¹æ³•定义
const handleQuery = () => {
  loading.value = true;
  // è¿™é‡Œæ·»åŠ å®žé™…çš„æŸ¥è¯¢é€»è¾‘
  setTimeout(() => {
    loading.value = false;
  }, 500);
};
/* // supplier ä¾›åº”商数据
const supplierColumns = reactive([
  { prop: "supplierName", label: "供应商名称", minWidth: 200 },
  { prop: "identifyNumber", label: "统一人识别号", minWidth: 120 },
  { prop: "address", label: "经营地址", minWidth: 150 },
  { prop: "bank", label: "开户行", minWidth: 120 },
  { prop: "bankAccount", label: "银行账号", minWidth: 150 },
  { prop: "contacts", label: "联系人", minWidth: 100 },
  { prop: "contactAddress", label: "联系地址", minWidth: 150 },
  { prop: "maintainer", label: "维护人", minWidth: 100 },
  { prop: "maintainDate", label: "维护日期", minWidth: 100 },
]);
// customer å®¢æˆ·æ•°æ®
const customerColumns = reactive([
  { prop: "customerName", label: "客户名称", minWidth: 200 },
  { prop: "identifyNumber", label: "统一人识别号", minWidth: 120 },
  { prop: "address", label: "经营地址", minWidth: 150 },
  { prop: "bank", label: "开户行", minWidth: 120 },
  { prop: "bankAccount", label: "银行账号", minWidth: 150 },
  { prop: "contacts", label: "联系人", minWidth: 100 },
  { prop: "contactAddress", label: "联系地址", minWidth: 150 },
  { prop: "maintainer", label: "维护人", minWidth: 100 },
  { prop: "maintainDate", label: "维护日期", minWidth: 100 },
]);
// coal ç…¤ç§æ•°æ®
const coalColumns = reactive([
  { prop: "coalName", label: "煤种名称", minWidth: 200 },
  { prop: "maintainer", label: "维护人", minWidth: 120 },
  { prop: "maintenanceDate", label: "维护日期", minWidth: 150 },
]); */
// æ ‡ç­¾é¡µç‚¹å‡»
const handleTabClick = (tab) => {
  loading.value = true;
  tabName.value = tab.props.name;
  tableData.value = [];
  getList();
  switch (tabName.value) {
    case "supplier":
      dialogFormVisible.value = supplierDialogFormVisible.value;
      break;
    case "customer":
      columns.value = customerColumns;
      dialogFormVisible.value = customerDialogFormVisible.value;
      break;
    case "coal":
      columns.value = coalColumns;
      dialogFormVisible.value = coalDialogFormVisible.value;
      break;
  }
  setTimeout(() => {
    loading.value = false;
  }, 500);
};
// é‡ç½®æŸ¥è¯¢
const resetQuery = () => {
  Object.keys(queryParams).forEach((key) => {
    if (key !== "pageNum" && key !== "pageSize") {
      queryParams[key] = "";
    }
  });
  handleQuery();
};
// æ–°å¢ž
const handleAdd = () => {
  addOrEdit.value = "add";
  handleAddEdit(tabName.value);
};
// æ–°å¢žç¼–辑
const handleAddEdit = (tabName) => {
  addOrEdit.value == "add" ? (title.value = "新增") : (title.value = "编辑");
  if (tabName === "supplier") {
    dialogFormVisible.value = true;
    title.value = title.value + "供应商信息";
    openDialog();
  } else if (tabName === "customer") {
    dialogFormVisible.value = true;
    title.value = title.value + "客户信息";
    openDialog();
  } else if (tabName === "coal") {
    dialogFormVisible.value = true;
    title.value = title.value + "煤种信息";
    openDialog();
  }
};
// æ‰“开弹窗
const openDialog = () => {
  if (addOrEdit.value === "edit") {
    copyForm.value = JSON.parse(JSON.stringify(form.value));
    dialogFormVisible.value = true;
    return;
  }
  form.value = {};
  dialogFormVisible.value = true;
};
// æäº¤è¡¨å•
const handleSubmit = (val) => {
  // æ‹¿åˆ°æäº¤æ•°æ®
  dialogFormVisible.value = false;
  getList();
};
const handleDialogFormVisible = (value) => {
  dialogFormVisible.value = value;
};
// é€‰æ‹©è¡Œ
const handleSelectionChange = (selection) => {
  selectedRows.value = selection;
};
// ç¼–辑
const handleEdit = (row) => {
  if (row.supplierName) {
    form.value = JSON.parse(JSON.stringify(row));
    addOrEdit.value = "edit";
    handleAddEdit(tabName.value);
    return;
  }
  if (selectedRows.value.length === 1) {
    form.value = JSON.parse(JSON.stringify(selectedRows.value[0]));
    addOrEdit.value = "edit";
    handleAddEdit(tabName.value);
    return;
  } else {
    ElMessage.warning("请选择一条数据修改");
  }
};
const handleDeleteSuccess = (row) => {
  ElMessage.success("删除成功:" + row.supplierName);
};
// å…³é—­å¼¹çª—
const handleBeforeClose = () => {
  dialogFormVisible.value = false;
  form.value = {};
};
const handleExport = (row) => {
  proxy.download("system/post/export", {
    ...queryParams.value
  }, `post_${new Date().getTime()}.xlsx`)
  ElMessage.success("导出数据:" + row.supplierName);
};
const getList = () => {
  loading.value = true;
  setTimeout(() => {
    tableData.value = [
      {
        supplierName: "中国冶金科工股份有限公司",
        identifyNumber: "123412123123123111",
        address: "山西省",
        bank: "交通银行",
        bankAccount: "901234567890123456",
        contacts: "李雪芹",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "李雪芹",
        maintainDate: "2022-09-26",
        contactsPhone: "19345678901",
      },
      {
        supplierName: "中国冶金科工股份有限公司",
        identifyNumber: "123412123123123111",
        address: "山西省",
        bank: "交通银行",
        bankAccount: "901234567890123456",
        contacts: "李雪芹",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "李雪芹",
        maintainDate: "2022-09-26",
        contactsPhone: "19345678901",
      },
      {
        supplierName: "中国冶金科工股份有限公司",
        identifyNumber: "123412123123123111",
        address: "山西省",
        bank: "交通银行",
        bankAccount: "901234567890123456",
        contacts: "李雪芹",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "李雪芹",
        maintainDate: "2022-09-26",
        contactsPhone: "19345678901",
      },
      {
        supplierName: "交通银行股份有限公司",
        identifyNumber: "042-26881314",
        address: "江西省",
        bank: "平安银行",
        bankAccount: "123456789012345678",
        contacts: "周白玉",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "周白玉",
        maintainDate: "2022-08-29",
      },
      {
        supplierName: "中国冶金科工股份有限公司",
        identifyNumber: "019-65851198",
        address: "山西省",
        bank: "交通银行",
        bankAccount: "901234567890123456",
        contacts: "李雪芹",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "李雪芹",
        maintainDate: "2022-09-26",
      },
      {
        supplierName: "交通银行股份有限公司",
        identifyNumber: "042-26881314",
        address: "江西省",
        bank: "平安银行",
        bankAccount: "123456789012345678",
        contacts: "周白玉",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "周白玉",
        maintainDate: "2022-08-29",
      },
      {
        supplierName: "中国冶金科工股份有限公司",
        identifyNumber: "019-65851198",
        address: "山西省",
        bank: "交通银行",
        bankAccount: "901234567890123456",
        contacts: "李雪芹",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "李雪芹",
        maintainDate: "2022-09-26",
      },
      {
        supplierName: "交通银行股份有限公司",
        identifyNumber: "042-26881314",
        address: "江西省",
        bank: "平安银行",
        bankAccount: "123456789012345678",
        contacts: "周白玉",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "周白玉",
        maintainDate: "2022-08-29",
      },
      {
        supplierName: "中国冶金科工股份有限公司",
        identifyNumber: "019-65851198",
        address: "山西省",
        bank: "交通银行",
        bankAccount: "901234567890123456",
        contacts: "李雪芹",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "李雪芹",
        maintainDate: "2022-09-26",
      },
      {
        supplierName: "交通银行股份有限公司",
        identifyNumber: "042-26881314",
        address: "江西省",
        bank: "平安银行",
        bankAccount: "123456789012345678",
        contacts: "周白玉",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "周白玉",
        maintainDate: "2022-08-29",
      },
      {
        supplierName: "中国冶金科工股份有限公司",
        identifyNumber: "019-65851198",
        address: "山西省",
        bank: "交通银行",
        bankAccount: "901234567890123456",
        contacts: "李雪芹",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "李雪芹",
        maintainDate: "2022-09-26",
      },
      {
        supplierName: "交通银行股份有限公司",
        identifyNumber: "042-26881314",
        address: "江西省",
        bank: "平安银行",
        bankAccount: "123456789012345678",
        contacts: "周白玉",
        contactAddress: "XX省XX市XX区XXè·¯",
        maintainer: "周白玉",
        maintainDate: "2022-08-29",
      },
    ];
    total.value = tableData.value.length;
    loading.value = false;
  }, 500);
};
getList();
</script>
<style scoped>
.app-container{
  box-sizing: border-box;
}
.search-form {
  background-color: #fff;
  padding: 20px 20px 0 20px;
  margin-bottom: 20px;
  border-radius: 4px;
  box-shadow: var(--el-box-shadow-light);
}
.search-form :deep(.el-form-item) {
  margin-bottom: 16px;
  width: 100%;
}
/* å“åº”式布局 */
@media screen and (min-width: 768px) {
  .search-form :deep(.el-form-item) {
    width: 50%;
  }
}
@media screen and (min-width: 1200px) {
  .search-form :deep(.el-form-item) {
    width: 18%;
  }
}
.info-tabs {
  margin-bottom: 20px;
}
.table-toolbar {
  margin-bottom: 20px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
/* å“åº”式表格 */
@media screen and (max-width: 768px) {
  .table-toolbar {
    flex-direction: column;
  }
  .table-toolbar .el-button {
    width: 100%;
  }
}
/* è¡¨æ ¼å·¥å…·æ  */
.table-toolbar, .table-toolbar > * {
  margin: 0 0 0 0 !important;
}
.table-toolbar{
  margin-bottom: 20px !important;
}
</style>
src/views/basicInformation/mould/coal.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,155 @@
<template>
  <div>
    <el-dialog
      v-model="dialogVisible"
      :title="title"
      width="800"
      :close-on-click-modal="false"
      :before-close="handleClose"
    >
      <el-form
        ref="formRef"
        style="max-width: 600px; margin: 0 auto"
        :model="formData"
        :rules="rules"
        label-width="auto"
      >
        <el-form-item label="卡胡" prop="supplierName">
          <el-input
            v-model="formData.supplierName"
            placeholder="请输入供货商名称"
          />
        </el-form-item>
        <el-form-item label="纳税人识别号" prop="identifyNumber">
          <el-input
            v-model="formData.identifyNumber"
            placeholder="请输入纳税人识别号"
          />
        </el-form-item>
        <el-form-item label="经营地址" prop="address">
          <el-select v-model="formData.address" placeholder="请选择经营地址">
            <el-option label="Zone one" value="shanghai" />
            <el-option label="Zone two" value="beijing" />
          </el-select>
        </el-form-item>
        <el-form-item label="银行账户" prop="bankAccount">
          <el-input
            v-model="formData.bankAccount"
            placeholder="请输入银行账户"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="submitForm"> ç¡®å®š </el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>
<script setup>
import { ref, watch, defineProps } from "vue";
const props = defineProps({
  beforeClose: {
    type: Function,
    default: () => {},
  },
  form: {
    type: Object,
    default: () => ({}),
  },
  addOrEdit: {
    type: String,
    default: "add",
  },
  title: {
    type: String,
    default: "",
  },
});
const emit = defineEmits([
  "submit",
  "handleBeforeClose",
  "update:coalDialogFormVisible",
]);
// è¡¨å•引用
const formRef = ref(null);
// è¡¨å•数据
const formData = ref({ ...props.form });
// å¼¹çª—可见性
const dialogVisible = defineModel("coalDialogFormVisible", {
  required: true,
  type: Boolean,
});
// ç›‘听外部传入的表单数据变化
watch(
  () => props.form,
  (newVal) => {
    formData.value = { ...newVal };
  },
  { deep: true }
);
// ç›‘听内部弹窗状态变化
watch(
  () => dialogVisible.value,
  (newVal) => {
    emit("update:coalDialogFormVisible", newVal);
  }
);
// æäº¤è¡¨å•
const submitForm = async () => {
  if (!formRef.value) return;
  await formRef.value.validate((valid, fields) => {
    if (valid) {
      emit("submit", formData.value);
    }
  });
};
// å–消表单
const cancelForm = () => {
  emit("update:coalDialogFormVisible", false);
  formData.value = {};
};
// é‡ç½®è¡¨å•
const resetForm = () => {
  if (!formRef.value) return;
  formRef.value.resetFields();
};
// å…³é—­å¼¹çª—
const handleClose = () => {
  // è§¦å‘父组件的关闭函数
  emit("handleBeforeClose");
  emit("update:coalDialogFormVisible", false);
};
const rules = reactive({
  supplierName: [
    { required: true, message: "请输入供货商名称", trigger: "blur" },
  ],
  identifyNumber: [
    { required: true, message: "请正确输入纳税人识别号", trigger: "blur" },
    { min: 17, max: 20, message: "请输入17-20位纳税人识别号", trigger: "blur" },
  ],
  address: [
    {
      required: true,
      message: "请选择经营地址",
      trigger: "change",
    },
  ],
  bankAccount: [{ required: true, message: "请输入银行账户", trigger: "blur" }],
  bank: [{ required: true, message: "请输入开户行", trigger: "blur" }],
  contacts: [{ required: true, message: "请输入开户行", trigger: "blur" }],
  contactsPhone: [
    { required: true, message: "请输入联系人", trigger: "blur" },
    { min: 11, max: 11, message: "请输入11位联系人电话", trigger: "blur" },
  ],
});
</script>
<style lang="sass" scoped>
</style>
src/views/basicInformation/mould/customer.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,140 @@
<template>
    <div>
        <el-dialog
            v-model="dialogVisible"
            :title="title"
            width="800"
            :close-on-click-modal="false"
            :before-close="handleClose"
        >
            <el-form
                ref="formRef"
                style="max-width: 600px; margin: 0 auto"
                :model="formData"
                :rules="rules"
                label-width="auto"
            >
                <el-form-item label="卡胡" prop="supplierName">
                    <el-input
                        v-model="formData.supplierName"
                        placeholder="请输入供货商名称"
                    />
                </el-form-item>
                <el-form-item label="纳税人识别号" prop="identifyNumber">
                    <el-input
                        v-model="formData.identifyNumber"
                        placeholder="请输入纳税人识别号"
                    />
                </el-form-item>
                <el-form-item label="经营地址" prop="address">
                    <el-select v-model="formData.address" placeholder="请选择经营地址">
                        <el-option label="Zone one" value="shanghai" />
                        <el-option label="Zone two" value="beijing" />
                    </el-select>
                </el-form-item>
                <el-form-item label="银行账户" prop="bankAccount">
                    <el-input v-model="formData.bankAccount" placeholder="请输入银行账户" />
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="submitForm">
                        ç¡®å®š
                    </el-button>
                </el-form-item>
            </el-form>
        </el-dialog>
    </div>
</template>
<script setup>
import { ref, watch ,defineProps } from 'vue'
const props = defineProps({
    beforeClose: {
        type: Function,
        default: () => {}
    },
    form: {
        type: Object,
        default: () => ({})
    },
    addOrEdit: {
        type: String,
        default: 'add'
    },
    title: {
        type: String,
        default: ''
    },
})
const emit = defineEmits(['submit', 'handleBeforeClose','update:customerDialogFormVisible'])
// è¡¨å•引用
const formRef = ref(null)
// è¡¨å•数据
const formData = ref({ ...props.form })
// å¼¹çª—可见性
const dialogVisible = defineModel("customerDialogFormVisible",{required:true,type:Boolean})
// ç›‘听外部传入的表单数据变化
watch(() => props.form, (newVal) => {
    formData.value = { ...newVal }
}, { deep: true })
// ç›‘听内部弹窗状态变化
watch(() => dialogVisible.value, (newVal) => {
    emit('update:customerDialogFormVisible', newVal)
})
// æäº¤è¡¨å•
const submitForm = async () => {
    if (!formRef.value) return
    await formRef.value.validate((valid, fields) => {
        if (valid) {
            emit('submit', formData.value)
        }
    })
}
// å–消表单
const cancelForm = () => {
    emit('update:customerDialogFormVisible', false)
    formData.value = {}
}
// é‡ç½®è¡¨å•
const resetForm = () => {
    if (!formRef.value) return
    formRef.value.resetFields()
}
// å…³é—­å¼¹çª—
const handleClose = () => {
    // è§¦å‘父组件的关闭函数
    emit("handleBeforeClose")
    emit('update:customerDialogFormVisible', false)
}
const rules = reactive({
  supplierName: [
    { required: true, message: "请输入供货商名称", trigger: "blur" },
  ],
  identifyNumber: [
    { required: true, message: "请正确输入纳税人识别号", trigger: "blur" },
    { min: 17, max: 20, message: "请输入17-20位纳税人识别号", trigger: "blur" },
  ],
  address: [
    {
      required: true,
      message: "请选择经营地址",
      trigger: "change",
    },
  ],
  bankAccount: [{ required: true, message: "请输入银行账户", trigger: "blur" }],
  bank: [{ required: true, message: "请输入开户行", trigger: "blur" }],
  contacts: [{ required: true, message: "请输入开户行", trigger: "blur" }],
  contactsPhone: [
    { required: true, message: "请输入联系人", trigger: "blur" },
    { min: 11, max: 11, message: "请输入11位联系人电话", trigger: "blur" },
  ],
});
</script>
<style lang="sass" scoped>
</style>
src/views/basicInformation/mould/supplier.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,154 @@
<template>
    <div>
        <el-dialog
            v-model="dialogVisible"
            :title="title"
            width="800"
            :close-on-click-modal="false"
            :before-close="handleClose"
        >
            <el-form
                ref="formRef"
                style="max-width: 600px; margin: 0 auto"
                :model="formData"
                :rules="rules"
                label-width="auto"
            >
                <el-form-item label="客户名称" prop="supplierName">
                    <el-input
                        v-model="formData.supplierName"
                        placeholder="请输入供货商名称"
                    />
                </el-form-item>
                <el-form-item label="纳税人识别号" prop="identifyNumber">
                    <el-input
                        v-model="formData.identifyNumber"
                        placeholder="请输入纳税人识别号"
                    />
                </el-form-item>
                <el-form-item label="经营地址" prop="address">
                    <el-select v-model="formData.address" placeholder="请选择经营地址">
                        <el-option label="Zone one" value="shanghai" />
                        <el-option label="Zone two" value="beijing" />
                    </el-select>
                </el-form-item>
                <el-form-item label="银行账户" prop="bankAccount">
                    <el-input v-model="formData.bankAccount" placeholder="请输入银行账户" />
                </el-form-item>
                <el-form-item label="开户行" prop="bank">
                    <el-input v-model="formData.bank" placeholder="请输入开户行" />
                </el-form-item>
                <el-form-item label="联系人" prop="contacts">
                    <el-input v-model="formData.contacts" placeholder="请输入联系人" />
                </el-form-item>
                <el-form-item label="联系人电话" prop="contactsPhone">
                    <el-input
                        v-model="formData.contactsPhone"
                        placeholder="请输入联系人电话"
                    />
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="submitForm">
                        ç¡®å®š
                    </el-button>
                    <el-button v-if="addOrEdit === 'edit'" @click="resetForm">重置</el-button>
                    <el-button v-if="addOrEdit === 'add'" @click="cancelForm">取消</el-button>
                </el-form-item>
            </el-form>
        </el-dialog>
    </div>
</template>
<script setup>
import { ref, watch, defineProps } from 'vue'
const props = defineProps({
    beforeClose: {
        type: Function,
        default: () => {}
    },
    form: {
        type: Object,
        default: () => ({})
    },
    addOrEdit: {
        type: String,
        default: 'add'
    },
    title: {
        type: String,
        default: ''
    },
})
const emit = defineEmits(['submit', 'handleBeforeClose'])
// è¡¨å•引用
const formRef = ref(null)
// è¡¨å•数据
const formData = ref({ ...props.form })
// å¼¹çª—可见性
const dialogVisible = defineModel("supplierDialogFormVisible",{required:true,type:Boolean})
// ç›‘听外部传入的表单数据变化
watch(() => props.form, (newVal) => {
    formData.value = { ...newVal }
}, { deep: true })
// ç›‘听内部弹窗状态变化
watch(() => dialogVisible.value, (newVal) => {
    emit('update:supplierDialogFormVisible', newVal)
})
// æäº¤è¡¨å•
const submitForm = async () => {
    if (!formRef.value) return
    await formRef.value.validate((valid, fields) => {
        if (valid) {
            emit('submit', formData.value)
        }
    })
}
// å–消表单
const cancelForm = () => {
    emit('update:supplierDialogFormVisible', false)
    formData.value = {}
}
// é‡ç½®è¡¨å•
const resetForm = () => {
    if (!formRef.value) return
    formRef.value.resetFields()
}
// å…³é—­å¼¹çª—
const handleClose = () => {
    // è§¦å‘父组件的关闭函数
    emit("handleBeforeClose")
    emit('update:supplierDialogFormVisible', false)
}
const rules = reactive({
  supplierName: [
    { required: true, message: "请输入供货商名称", trigger: "blur" },
  ],
  identifyNumber: [
    { required: true, message: "请正确输入纳税人识别号", trigger: "blur" },
    { min: 17, max: 20, message: "请输入17-20位纳税人识别号", trigger: "blur" },
  ],
  address: [
    {
      required: true,
      message: "请选择经营地址",
      trigger: "change",
    },
  ],
  bankAccount: [{ required: true, message: "请输入银行账户", trigger: "blur" }],
  bank: [{ required: true, message: "请输入开户行", trigger: "blur" }],
  contacts: [{ required: true, message: "请输入开户行", trigger: "blur" }],
  contactsPhone: [
    { required: true, message: "请输入联系人", trigger: "blur" },
    { min: 11, max: 11, message: "请输入11位联系人电话", trigger: "blur" },
  ],
});
</script>
<style lang="sass" scoped>
</style>
src/views/procureMent/components/ProductionDialog.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,253 @@
<template>
  <div>
    <el-dialog
      v-model="dialogVisible"
      :title="title"
      width="600"
      :close-on-click-modal="false"
      @close="handleClose"
    >
      <el-form
        ref="formRef"
        :model="form"
        :rules="rules"
        label-width="auto"
        class="production-form"
        label-position="right"
        style="max-width: 400px; margin: 0 auto"
      >
        <el-form-item label="供应商名称" prop="supplierName">
          <el-input v-model="form.supplierName" placeholder="请输入" />
        </el-form-item>
        <el-form-item label="煤种" prop="category">
          <el-input v-model="form.category" placeholder="请输入" />
        </el-form-item>
        <el-form-item label="单位" prop="unit">
          <el-input v-model="form.unit" placeholder="请输入" />
        </el-form-item>
        <el-form-item label="采购数量" prop="purchaseAmount">
          <el-input v-model="form.purchaseAmount" placeholder="请输入" />
        </el-form-item>
        <el-form-item label="单价(税前)" prop="priceBeforeTax">
          <el-input v-model="form.priceBeforeTax" placeholder="请输入" />
        </el-form-item>
        <el-form-item label="总价(税前)" prop="totalBeforeTax">
          <el-input v-model="form.totalBeforeTax" placeholder="请输入" />
        </el-form-item>
        <el-form-item label="热值" prop="calorificValue">
          <el-input v-model="form.calorificValue" placeholder="请输入" />
        </el-form-item>
        <el-form-item label="登记人" prop="registrant">
          <el-input v-model="form.registrant" placeholder="请输入" />
        </el-form-item>
        <el-form-item label="登记日期" prop="registrationDate">
          <el-date-picker
            v-model="form.registrationDate"
            type="date"
            placeholder="YYYY-MM-DD"
            style="width: 100%"
            value-format="YYYY-MM-DD"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="handleSubmit">保存</el-button>
          <!-- é‡ç½®å’Œå–消 -->
          <el-button
            type="primary"
            @click="handleClose"
            v-if="title.includes('新增')"
            >取消</el-button
          >
          <el-button
            type="primary"
            @click="handleReset"
            v-if="title.includes('编辑')"
            >重置</el-button
          >
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script setup name="ProductionDialog">
import { ref, defineProps, watch } from "vue";
import { ElMessage } from "element-plus";
const props = defineProps({
  title: {
    type: String,
    default: "",
  },
});
const emit = defineEmits(["update:visible", "success"]);
const dialogVisible = defineModel("dialogFormVisible", {
  required: true,
  type: Boolean,
});
const form = defineModel("form", {
  required: true,
  type: Object,
});
const rules = {
  supplierName: [
    { required: true, message: "请输入供应商名称", trigger: "blur" },
  ],
  category: [{ required: true, message: "请输入煤种", trigger: "blur" }],
  unit: [{ required: true, message: "请输入单位", trigger: "blur" }],
  purchaseAmount: [
    { required: true, message: "请输入采购数量", trigger: "blur" },
  ],
  priceBeforeTax: [{ required: true, message: "请输入单价", trigger: "blur" }],
  totalBeforeTax: [{ required: true, message: "请输入总价", trigger: "blur" }],
  calorificValue: [{ required: true, message: "请输入热值", trigger: "blur" }],
  registrant: [{ required: true, message: "请输入登记人", trigger: "blur" }],
  registrationDate: [
    { required: true, message: "请选择登记日期", trigger: "change" },
  ],
};
// å…³é—­å¼¹çª—
const handleClose = () => {
  dialogVisible.value = false;
  console.log(form.value);
  // formRef.value?.resetFields()
  // Object.assign(form, {
  // })
};
const handleReset = () => {
  if (!formRef.value) return;
  formRef.value.resetFields();
  ElMessage.success("表单已重置");
};
// æŒç»­ç›‘听form.value的变化
watch(
  () => form.value,
  (val) => {
    console.log(val);
  }
);
const formRef = ref(null);
// æäº¤è¡¨å•
const handleSubmit = async () => {
  if (!formRef.value) return;
  await formRef.value.validate((valid) => {
    if (valid) {
      try {
        emit("success", { ...form.value });
        handleClose();
        ElMessage.success("保存成功");
      } catch (error) {
        console.error("保存失败:", error);
        ElMessage.error("保存失败");
      }
    }
  });
};
</script>
<style lang="less" scoped>
</style>
<!-- <template>
  <el-dialog
    v-model="dialogFormVisible"
    title="采购登记新增"
    width="500px"
    :close-on-click-modal="false"
    @close="handleClose"
  >
  </el-dialog>
</template>
<script setup>
import { ref, reactive, defineProps, defineEmits } from 'vue'
import { ElMessage } from 'element-plus'
const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  }
})
const emit = defineEmits(['update:visible', 'success'])
const dialogFormVisible = ref(false)
const formRef = ref(null)
// è¡¨å•数据
const form = reactive({
  supplierName: '',
  category: '',
  unit: '',
  purchaseAmount: '',
  priceBeforeTax: '',
  totalBeforeTax: '',
  calorificValue: '',
  registrant: '',
  registrationDate: ''
})
// è¡¨å•验证规则
// ç›‘听visible变化
watch(() => props.visible, (val) => {
  dialogFormVisible.value = val
})
// ç›‘听dialogFormVisible变化
watch(() => dialogFormVisible.value, (val) => {
  emit('update:visible', val)
})
// æäº¤è¡¨å•
const handleSubmit = async () => {
  if (!formRef.value) return
  await formRef.value.validate((valid) => {
    if (valid) {
      try {
        emit('success', { ...form })
        handleClose()
        ElMessage.success('保存成功')
      } catch (error) {
        console.error('保存失败:', error)
        ElMessage.error('保存失败')
      }
    }
  })
}
// å–消
const handleCancel = () => {
  handleClose()
}
</script>
<style scoped>
.production-form {
  padding: 20px;
}
.dialog-footer {
  display: flex;
  justify-content: center;
  gap: 20px;
}
:deep(.el-form-item__label) {
  font-weight: normal;
}
:deep(.el-input),
:deep(.el-date-picker) {
  width: 100%;
}
:deep(.el-dialog__body) {
  padding-top: 10px;
}
</style> -->
src/views/procureMent/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,308 @@
<template>
  <div class="app-container">
      <el-form :inline="true" :model="queryParams" class="search-form">
        <el-form-item label="搜索">
          <el-input
            v-model="queryParams.searchText"
            placeholder="请输入关键词"
            clearable
            :style="{ width: '100%' }"
          />
        </el-form-item>
        <el-form-item label="供应商名称">
          <el-input
            v-model="queryParams.supplierName"
            placeholder="请输入"
            clearable
            :style="{ width: '100%' }"
          />
        </el-form-item>
        <el-form-item label="统一人识别号">
          <el-input
            v-model="queryParams.identifyNumber"
            placeholder="请输入"
            clearable
            :style="{ width: '100%' }"
          />
        </el-form-item>
        <el-form-item label="经营地址">
          <el-input
            v-model="queryParams.address"
            placeholder="请输入"
            clearable
            :style="{ width: '100%' }"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleQuery">查询</el-button>
          <el-button @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>
    <el-card>
      <!-- æ“ä½œæŒ‰é’®åŒº -->
      <el-row :gutter="24" class="table-toolbar">
        <el-button type="primary" :icon="Plus" @click="handleAdd"
          >新建</el-button
        >
        <el-button type="danger" :icon="Delete" @click="handleDelete">删除</el-button>
        <el-button type="info" :icon="Download" @click="handleExport">导出</el-button>
      </el-row>
      <!-- è¡¨æ ¼ç»„ä»¶ -->
        <data-table
          :loading="loading"
          :table-data="tableData"
          :columns="columns"
          @selection-change="handleSelectionChange"
          @edit="handleEdit"
          @delete="handleDeleteSuccess"
          :show-selection="true"
          :border="true"
          :maxHeight="440"
        />
      <pagination
        v-if="total>0"
        :page-num="pageNum"
        :page-size="pageSize"
        :total="total"
        @pagination="handleQuery"
        :layout="'total, prev, pager, next, jumper'"
      />
    </el-card>
    <ProductionDialog
        v-if="total>0"
        v-model:dialogFormVisible="dialogFormVisible"
        :form="form"
        :title="title"
        @submit="handleSubmit"
        @success="handleSuccess"
      />
  </div>
</template>
<script setup>
import { ref, reactive, onMounted } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { Plus, Edit, Delete, Download } from "@element-plus/icons-vue";
import DataTable from "@/components/Table/ETable.vue";
import Pagination from "@/components/Pagination";
import ProductionDialog from "./components/ProductionDialog.vue";
const { proxy } = getCurrentInstance()
const dialogFormVisible = ref(false);
const form = ref({});
const title = ref("");
// çŠ¶æ€å˜é‡
const loading = ref(false);
const total = ref(0);
const pageNum = ref(1)
const pageSize = ref(10);
const selectedRows = ref([]);
// æŸ¥è¯¢å‚æ•°
const queryParams = reactive({
  searchText: "",
  supplierName: "",
  identifyNumber: "",
  address: "",
});
// æ˜¯å¦ç¼–辑
const addOrEdit = ref("add");
// è¡¨æ ¼æ•°æ®
const tableData = ref([]);
// æ–¹æ³•定义
const handleQuery = () => {
  loading.value = true;
  // è¿™é‡Œæ·»åŠ å®žé™…çš„æŸ¥è¯¢é€»è¾‘
  setTimeout(() => {
    loading.value = false;
  }, 500);
};
// supplier ä¾›åº”商数据
const columns = ref([
  { prop: "supplierName", label: "供应商名称", minWidth: 200 },
  { prop: "category", label: "煤种", minWidth: 120 },
  { prop: "unit", label: "单位", minWidth: 150 },
  { prop: "purchaseAmount", label: "采购数量", minWidth: 120 },
  { prop: "priceBeforeTax", label: "单价(税前)", minWidth: 150 },
  { prop: "totalBeforeTax", label: "总价(税前)", minWidth: 100 },
  { prop: "calorificValue", label: "热值", minWidth: 150 },
  { prop: "registrant", label: "登记人", minWidth: 100 },
  { prop: "registrationDate", label: "登记日期", minWidth: 100 },
]);
// é‡ç½®æŸ¥è¯¢
const resetQuery = () => {
  Object.keys(queryParams).forEach((key) => {
    if (key !== "pageNum" && key !== "pageSize") {
      queryParams[key] = "";
    }
  });
  handleQuery();
};
// æ–°å¢ž
const handleAdd = () => {
  addOrEdit.value = "add";
  handleAddEdit();
};
// æ–°å¢žç¼–辑
const handleAddEdit = () => {
  addOrEdit.value == "add" ? (title.value = "新增") : (title.value = "编辑");
    title.value = title.value + "采购信息";
    openDialog();
};
// æ‰“开弹窗
const openDialog = () => {
  if (addOrEdit.value === "edit") {
    dialogFormVisible.value = true;
    return;
  }
  form.value = {};
  dialogFormVisible.value = true;
};
// æäº¤è¡¨å•
const handleSubmit = () => {
  // æ‹¿åˆ°æäº¤æ•°æ®
  dialogFormVisible.value = false;
  getList();
};
// é€‰æ‹©è¡Œ
const handleSelectionChange = (selection) => {
  selectedRows.value = selection;
};
// è¡¨æ ¼ç¼–辑方法
const handleEdit = (row) => {
    form.value = JSON.parse(JSON.stringify(row));
    addOrEdit.value = "edit";
    handleAddEdit()
};
const handleDelete = () => {
  if (selectedRows.value.length === 0) {
    ElMessage.warning("请选择要删除的数据");
    return;
  }
  ElMessageBox.confirm(
    `确认删除选中的 ${selectedRows.value.length} æ¡æ•°æ®å—?`,
    "提示",
    {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning"
    }
  )
    .then(() => {
      // æ¨¡æ‹Ÿåˆ é™¤æ“ä½œ
      tableData.value = tableData.value.filter(
        (item) => !selectedRows.value.includes(item)
      );
      total.value = tableData.value.length;
      ElMessage.success("删除成功");
    })
    .catch(() => {
      ElMessage.info("已取消删除");
    });
}
const handleDeleteSuccess = (row) => {
  ElMessage.success("删除成功:" + row.supplierName);
};
// å¯¼å‡º
const handleExport = (row) => {
  proxy.download("system/post/export", {
    ...queryParams.value
  }, `post_${new Date().getTime()}.xlsx`)
  ElMessage.success("导出数据:" + row.supplierName);
};
// æˆåŠŸ
const handleSuccess = (val) => {
  console.log(val);
  tableData.value.push(val);
  // getList();
  total.value = tableData.value.length;
  ElMessage.success("操作成功");
};
const getList = () => {
  loading.value = true;
  setTimeout(() => {
    tableData.value = [
      {
        supplierName: "中国石油化工股份有限公司",
        category: "煤",
        unit: "吨",
        purchaseAmount: "1000",
        priceBeforeTax: "100",
        totalBeforeTax: "100000",
        calorificValue: "5000",
        registrant: "张三",
        registrationDate: "2025-01-01",
      },
      {
        supplierName: "中国中石化",
        category: "精品煤",
        unit: "千克",
        purchaseAmount: "1000",
        priceBeforeTax: "100",
        totalBeforeTax: "100000",
        calorificValue: "5000",
        registrant: "李四",
        registrationDate: "2025-01-01",
      }
    ]
    total.value = tableData.value.length;
    loading.value = false;
  }, 500);
};
getList();
</script>
<style scoped>
.app-container{
  box-sizing: border-box;
}
.search-form {
  background-color: #fff;
  padding: 20px 20px 0 20px;
  margin-bottom: 20px;
  border-radius: 4px;
  box-shadow: var(--el-box-shadow-light);
}
.search-form :deep(.el-form-item) {
  margin-bottom: 16px;
  width: 100%;
}
/* å“åº”式布局 */
@media screen and (min-width: 768px) {
  .search-form :deep(.el-form-item) {
    width: 50%;
  }
}
@media screen and (min-width: 1200px) {
  .search-form :deep(.el-form-item) {
    width: 18%;
  }
}
.table-toolbar {
  margin-bottom: 20px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
/* å“åº”式表格 */
@media screen and (max-width: 768px) {
  .table-toolbar {
    flex-direction: column;
  }
  .table-toolbar .el-button {
    width: 100%;
  }
}
/* è¡¨æ ¼å·¥å…·æ  */
.table-toolbar, .table-toolbar > * {
  margin: 0 0 0 0 !important;
}
.table-toolbar{
  margin-bottom: 20px !important;
}
</style>
src/views/system/user/index.vue
@@ -17,11 +17,8 @@
        <pane size="84">
          <el-col>
            <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
              <el-form-item label="用户名称" prop="userName">
                <el-input v-model="queryParams.userName" placeholder="请输入用户名称" clearable style="width: 240px" @keyup.enter="handleQuery" />
              </el-form-item>
              <el-form-item label="手机号码" prop="phonenumber">
                <el-input v-model="queryParams.phonenumber" placeholder="请输入手机号码" clearable style="width: 240px" @keyup.enter="handleQuery" />
              <el-form-item label="登录账号" prop="userName">
                <el-input v-model="queryParams.userName" placeholder="请输入" clearable style="width: 240px" @keyup.enter="handleQuery" />
              </el-form-item>
              <el-form-item label="状态" prop="status">
                <el-select v-model="queryParams.status" placeholder="用户状态" clearable style="width: 240px">
@@ -59,10 +56,9 @@
            <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
              <el-table-column type="selection" width="50" align="center" />
              <el-table-column label="用户编号" align="center" key="userId" prop="userId" v-if="columns[0].visible" />
              <el-table-column label="用户名称" align="center" key="userName" prop="userName" v-if="columns[1].visible" :show-overflow-tooltip="true" />
              <el-table-column label="用户昵称" align="center" key="nickName" prop="nickName" v-if="columns[2].visible" :show-overflow-tooltip="true" />
              <el-table-column label="登录账号" align="center" key="userName" prop="userName" v-if="columns[1].visible" :show-overflow-tooltip="true" />
              <el-table-column label="用户姓名" align="center" key="nickName" prop="nickName" v-if="columns[2].visible" :show-overflow-tooltip="true" />
              <el-table-column label="部门" align="center" key="deptName" prop="dept.deptName" v-if="columns[3].visible" :show-overflow-tooltip="true" />
              <el-table-column label="手机号码" align="center" key="phonenumber" prop="phonenumber" v-if="columns[4].visible" width="120" />
              <el-table-column label="状态" align="center" key="status" v-if="columns[5].visible">
                <template #default="scope">
                  <el-switch
@@ -106,8 +102,22 @@
      <el-form :model="form" :rules="rules" ref="userRef" label-width="80px">
        <el-row>
          <el-col :span="12">
            <el-form-item label="用户昵称" prop="nickName">
              <el-input v-model="form.nickName" placeholder="请输入用户昵称" maxlength="30" />
            <el-form-item label="登录账号" prop="userName">
              <el-input v-model="form.userName" placeholder="请输入手机号码" maxlength="30" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="用户姓名" prop="nickName">
              <el-input v-model="form.nickName" placeholder="请输入姓名" maxlength="30" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="角色" prop="roleIds">
              <el-select v-model="form.roleIds" multiple placeholder="请选择">
                <el-option v-for="item in roleOptions" :key="item.roleId" :label="item.roleName" :value="item.roleId" :disabled="item.status == 1"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
@@ -118,64 +128,15 @@
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="手机号码" prop="phonenumber">
              <el-input v-model="form.phonenumber" placeholder="请输入手机号码" maxlength="11" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="邮箱" prop="email">
              <el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item v-if="form.userId == undefined" label="用户名称" prop="userName">
              <el-input v-model="form.userName" placeholder="请输入用户名称" maxlength="30" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item v-if="form.userId == undefined" label="用户密码" prop="password">
              <el-input v-model="form.password" placeholder="请输入用户密码" type="password" maxlength="20" show-password />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="用户性别">
              <el-select v-model="form.sex" placeholder="请选择">
                <el-option v-for="dict in sys_user_sex" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="状态">
              <el-radio-group v-model="form.status">
                <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :value="dict.value">{{ dict.label }}</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="岗位">
              <el-select v-model="form.postIds" multiple placeholder="请选择">
                <el-option v-for="item in postOptions" :key="item.postId" :label="item.postName" :value="item.postId" :disabled="item.status == 1"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="角色">
              <el-select v-model="form.roleIds" multiple placeholder="请选择">
                <el-option v-for="item in roleOptions" :key="item.roleId" :label="item.roleName" :value="item.roleId" :disabled="item.status == 1"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="备注">
              <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
            <el-form-item v-if="title === '添加用户'" label="用户密码" prop="password">
              <el-input v-model="form.password" placeholder="请输入用户密码" type="password" maxlength="20" show-password/>
            </el-form-item>
          </el-col>
        </el-row>
@@ -259,8 +220,8 @@
// åˆ—显隐信息
const columns = ref([
  { key: 0, label: `用户编号`, visible: true },
  { key: 1, label: `用户名称`, visible: true },
  { key: 2, label: `用户昵称`, visible: true },
  { key: 1, label: `登录账号`, visible: true },
  { key: 2, label: `用户姓名`, visible: true },
  { key: 3, label: `部门`, visible: true },
  { key: 4, label: `手机号码`, visible: true },
  { key: 5, label: `状态`, visible: true },
@@ -273,16 +234,15 @@
    pageNum: 1,
    pageSize: 10,
    userName: undefined,
    phonenumber: undefined,
    status: undefined,
    deptId: undefined
  },
  rules: {
    userName: [{ required: true, message: "用户名称不能为空", trigger: "blur" }, { min: 2, max: 20, message: "用户名称长度必须介于 2 å’Œ 20 ä¹‹é—´", trigger: "blur" }],
    nickName: [{ required: true, message: "用户昵称不能为空", trigger: "blur" }],
    userName: [{ required: true, message: "登录账号不能为空", trigger: "blur" }, { pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请输入正确的手机号码", trigger: "blur" }],
    nickName: [{ required: true, message: "用户姓名不能为空", trigger: "blur" }],
    roleIds: [{ required: true, message: "角色不能为空", trigger: "change" }],
    deptId: [{ required: true, message: "部门不能为空", trigger: "change" }],
    password: [{ required: true, message: "用户密码不能为空", trigger: "blur" }, { min: 5, max: 20, message: "用户密码长度必须介于 5 å’Œ 20 ä¹‹é—´", trigger: "blur" }, { pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }],
    email: [{ type: "email", message: "请输入正确的邮箱地址", trigger: ["blur", "change"] }],
    phonenumber: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请输入正确的手机号码", trigger: "blur" }]
  }
})
@@ -466,13 +426,8 @@
    deptId: undefined,
    userName: undefined,
    nickName: undefined,
    password: undefined,
    phonenumber: undefined,
    email: undefined,
    sex: undefined,
    password: '123456',
    status: "0",
    remark: undefined,
    postIds: [],
    roleIds: []
  }
  proxy.resetForm("userRef")
@@ -492,7 +447,7 @@
    roleOptions.value = response.roles
    open.value = true
    title.value = "添加用户"
    form.value.password = initPassword.value
    form.value.password = '123456'
  })
}
@@ -504,11 +459,9 @@
    form.value = response.data
    postOptions.value = response.posts
    roleOptions.value = response.roles
    form.value.postIds = response.postIds
    form.value.roleIds = response.roleIds
    open.value = true
    title.value = "修改用户"
    form.password = ""
  })
}
src/views/tool/build/index.vue
@@ -307,7 +307,7 @@
</script>
<style lang='scss'>
$lighterBlue: #409EFF;
$lighterBlue: #165DFF;
.container {
  position: relative;