| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 |
- <template>
- <div class="station-page">
- <a-card :bordered="false">
- <a-form :model="queryParams" layout="inline">
- <a-form-item label="场站名称">
- <a-input v-model:value="queryParams.stationName" allow-clear placeholder="请输入场站名称" />
- </a-form-item>
- <a-form-item label="场站编码">
- <a-input v-model:value="queryParams.stationCode" allow-clear placeholder="请输入场站编码" />
- </a-form-item>
- <a-form-item label="场站类型">
- <a-select v-model:value="queryParams.stationType" allow-clear class="query-select" :options="stationTypeOptions" />
- </a-form-item>
- <a-form-item label="是否启用">
- <a-select v-model:value="queryParams.isEnable" allow-clear class="query-select" :options="enableOptions" />
- </a-form-item>
- <a-form-item>
- <a-space>
- <a-button type="primary" :loading="loading" @click="handleQuery"><BearJiaIcon icon="SearchOutlined"/>查询</a-button>
- <a-button @click="resetQuery">重置</a-button>
- </a-space>
- </a-form-item>
- </a-form>
- </a-card>
- <a-card ref="tableCardRef" :bordered="false" class="section">
- <TableToolbar
- :columns="columns"
- :selected-columns="selectedColumnKeys"
- :loading="loading"
- :export-config="exportConfig"
- @columnSettingsChange="handleColumnSettingsChange"
- @refresh="handleQuery"
- @fullscreen="handleFullscreen"
- @export="handleExport"
- @reset="handleTableReset"
- >
- <template #left>
- <a-button v-hasPermi="['config:station:add']" type="primary" @click="openForm()"><BearJiaIcon icon="plus-outlined"/>新增</a-button>
- <a-button v-hasPermi="['config:station:remove']" danger type="primary" :disabled="selectedRowKeys.length <= 0" @click="handleBatchDelete"><BearJiaIcon icon="delete-outlined"/>删除</a-button>
- <a-button v-hasPermi="['config:station:export']" @click="handleExport"><BearJiaIcon icon="export-outlined"/>导出</a-button>
- </template>
- </TableToolbar>
- <a-table
- :columns="displayColumns"
- :data-source="rows"
- :loading="loading"
- :pagination="pagination"
- row-key="id"
- :row-selection="rowSelection"
- :size="tableConfigStore.size"
- @change="handleTableChange"
- >
- <template #bodyCell="{ column, record }">
- <template v-if="column.key === 'stationType'">
- {{ stationTypeText(record.stationType) }}
- </template>
- <template v-else-if="column.key === 'isEnable'">
- <a-tag :color="record.isEnable === '1' ? 'success' : 'default'">{{ enableText(record.isEnable) }}</a-tag>
- </template>
- <template v-else-if="column.key === 'operation'">
- <TableActionBar :record="record" :has-view="false" :has-edit="true" :has-delete="true">
- <template #edit>
- <a v-hasPermi="['config:station:edit']" class="action-btn edit-btn" @click="openForm(record)"><BearJiaIcon icon="edit-outlined"/>修改</a>
- </template>
- <template #delete>
- <a-divider type="vertical"/>
- <a v-hasPermi="['config:station:remove']" class="action-btn delete-btn" @click="handleDeleteRecord(record)"><BearJiaIcon icon="delete-outlined"/>删除</a>
- </template>
- </TableActionBar>
- </template>
- </template>
- </a-table>
- </a-card>
- <a-modal v-model:open="formOpen" :title="form.id ? '编辑场站' : '新增场站'" width="820px" @ok="submitForm">
- <a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 7 }" :wrapper-col="{ span: 15 }">
- <a-row :gutter="16">
- <a-col :span="12">
- <a-form-item label="场站名称" name="stationName">
- <a-input v-model:value="form.stationName" allow-clear />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="场站编码" name="stationCode">
- <a-input v-model:value="form.stationCode" allow-clear />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="场站类型" name="stationType">
- <a-select v-model:value="form.stationType" allow-clear :options="stationTypeOptions" />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="是否启用" name="isEnable">
- <a-select v-model:value="form.isEnable" allow-clear :options="enableOptions" />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="装机容量(kW)" name="installedCapacity">
- <a-input-number v-model:value="form.installedCapacity" class="full-input" :min="0" />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="并网容量(kW)" name="gridConnectedCapacity">
- <a-input-number v-model:value="form.gridConnectedCapacity" class="full-input" :min="0" />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="经度" name="longitude">
- <a-input v-model:value="form.longitude" allow-clear />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="纬度" name="latitude">
- <a-input v-model:value="form.latitude" allow-clear />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="位置" name="position">
- <a-input v-model:value="form.position" allow-clear />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="投运时间" name="operationTime">
- <a-input v-model:value="form.operationTime" allow-clear placeholder="如 2026-01-01" />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="负责人" name="responsiblePersonName">
- <a-input v-model:value="form.responsiblePersonName" allow-clear />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="负责人电话" name="responsiblePersonPhone">
- <a-input v-model:value="form.responsiblePersonPhone" allow-clear />
- </a-form-item>
- </a-col>
- </a-row>
- </a-form>
- </a-modal>
- </div>
- </template>
- <script setup name="ConfigStation">
- import { computed, reactive, ref } from 'vue';
- import { message, Modal } from 'ant-design-vue';
- import BearJiaUtil from '@/utils/BearJiaUtil';
- import { addStation, delStation, getStation, listStation, updateStation } from '@/api/config/station';
- import TableActionBar from '@/components/TableActionBar/index.vue';
- import TableToolbar from '@/components/BearJiaProTable/TableToolbar.vue';
- import { useTableConfigStore } from '@/stores/tableConfig';
- import { BearJiaIcon } from '@/utils/BearJiaIcon.js';
- const loading = ref(false);
- const rows = ref([]);
- const formOpen = ref(false);
- const formRef = ref();
- const selectedRowKeys = ref([]);
- const tableCardRef = ref();
- const selectedColumnKeys = ref([]);
- const tableConfigStore = useTableConfigStore();
- const queryParams = reactive({
- pageNum: 1,
- pageSize: 10,
- stationName: undefined,
- stationCode: undefined,
- stationType: undefined,
- isEnable: undefined
- });
- const pagination = reactive({
- current: 1,
- pageSize: 10,
- total: 0,
- showSizeChanger: true
- });
- const form = reactive({});
- const rowSelection = computed(() => ({
- selectedRowKeys: selectedRowKeys.value,
- onChange: (keys) => { selectedRowKeys.value = keys; }
- }));
- const stationTypeOptions = [
- { label: '风电', value: 0 },
- { label: '光伏', value: 1 }
- ];
- const enableOptions = [
- { label: '停用', value: '0' },
- { label: '启用', value: '1' }
- ];
- const rules = {
- stationName: [{ required: true, message: '请输入场站名称', trigger: 'blur' }]
- };
- const columns = [
- { title: 'ID', dataIndex: 'id', width: 90 },
- { title: '场站名称', dataIndex: 'stationName', width: 180 },
- { title: '场站编码', dataIndex: 'stationCode', width: 180 },
- { title: '类型', dataIndex: 'stationType', key: 'stationType', width: 100 },
- { title: '装机容量(kW)', dataIndex: 'installedCapacity', width: 140 },
- { title: '并网容量(kW)', dataIndex: 'gridConnectedCapacity', width: 140 },
- { title: '位置', dataIndex: 'position', width: 180 },
- { title: '负责人', dataIndex: 'responsiblePersonName', width: 120 },
- { title: '电话', dataIndex: 'responsiblePersonPhone', width: 140 },
- { title: '启用', dataIndex: 'isEnable', key: 'isEnable', width: 90 },
- { title: '操作', key: 'operation', dataIndex: 'operation', width: 200, fixed: 'right' }
- ];
- const storageKey = 'station-config-columns-station';
- const readSavedColumns = () => {
- try {
- const saved = JSON.parse(localStorage.getItem(storageKey) || 'null');
- if (Array.isArray(saved) && saved.length > 0) {
- const valid = saved.filter((k) => columns.some((c) => c.dataIndex === k));
- if (valid.length > 0) return valid;
- }
- } catch (e) { /* 忽略存储解析错误 */ }
- return columns.map((c) => c.dataIndex);
- };
- selectedColumnKeys.value = readSavedColumns();
- const displayColumns = computed(() => columns.filter((col) => selectedColumnKeys.value.includes(col.dataIndex)));
- const exportConfig = { enabled: true };
- const stationTypeText = (value) => stationTypeOptions.find((item) => item.value === Number(value))?.label || '-';
- const enableText = (value) => enableOptions.find((item) => item.value === String(value))?.label || '-';
- const resetObject = (target, source = {}) => {
- Object.keys(target).forEach((key) => delete target[key]);
- Object.assign(target, source);
- };
- const handleQuery = async () => {
- loading.value = true;
- try {
- const res = await listStation(queryParams);
- rows.value = res?.rows || res?.data || [];
- pagination.total = res?.total || rows.value.length;
- pagination.current = queryParams.pageNum;
- pagination.pageSize = queryParams.pageSize;
- } finally {
- loading.value = false;
- }
- };
- const resetQuery = () => {
- queryParams.pageNum = 1;
- queryParams.stationName = undefined;
- queryParams.stationCode = undefined;
- queryParams.stationType = undefined;
- queryParams.isEnable = undefined;
- handleQuery();
- };
- const handleTableChange = (page) => {
- queryParams.pageNum = page.current;
- queryParams.pageSize = page.pageSize;
- handleQuery();
- };
- const openForm = async (record) => {
- if (record?.id) {
- const res = await getStation(record.id);
- const data = { ...res.data };
- if (data.stationType !== undefined && data.stationType !== null) {
- data.stationType = Number(data.stationType);
- }
- resetObject(form, data);
- } else {
- resetObject(form, { isEnable: '1', stationType: 0 });
- }
- formOpen.value = true;
- };
- const submitForm = async () => {
- await formRef.value?.validate();
- if (form.id) {
- await updateStation(form);
- } else {
- await addStation(form);
- }
- message.success('保存成功');
- formOpen.value = false;
- handleQuery();
- };
- const handleDeleteRecord = (record) => {
- Modal.confirm({
- title: '确认删除',
- content: '确认删除该场站?',
- onOk: async () => {
- await delStation(record.id);
- message.success('删除成功');
- handleQuery();
- }
- });
- };
- const handleBatchDelete = () => {
- if (selectedRowKeys.value.length <= 0) {
- message.warning('请至少选择一条数据');
- return;
- }
- Modal.confirm({
- title: '确认删除',
- content: `确认删除选中的 ${selectedRowKeys.value.length} 条数据?`,
- onOk: async () => {
- await delStation(selectedRowKeys.value);
- message.success('删除成功');
- selectedRowKeys.value = [];
- handleQuery();
- }
- });
- };
- const handleExport = () => {
- BearJiaUtil.download('config/station/export', queryParams, '场站信息.xlsx');
- };
- const handleColumnSettingsChange = (keys) => {
- selectedColumnKeys.value = keys;
- localStorage.setItem(storageKey, JSON.stringify(keys));
- };
- const handleFullscreen = (isFullscreen) => {
- const el = tableCardRef.value?.$el || tableCardRef.value;
- if (isFullscreen) {
- el?.requestFullscreen?.();
- } else {
- document.exitFullscreen?.();
- }
- };
- const handleTableReset = () => {
- selectedColumnKeys.value = columns.map((c) => c.dataIndex);
- localStorage.removeItem(storageKey);
- handleQuery();
- };
- handleQuery();
- </script>
- <style lang="less" scoped>
- .station-page {
- .section {
- margin-top: 12px;
- }
- .query-select {
- width: 140px;
- }
- .full-input {
- width: 100%;
- }
- }
- </style>
|