This commit is contained in:
褚泓程 2025-01-17 12:32:44 +08:00
parent aa5e175c77
commit 2d38600dbb
8 changed files with 2941 additions and 0 deletions

44
src/api/system/goods.js Normal file
View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询【请填写功能名称】列表
export function listGoods(query) {
return request({
url: '/system/goods/list',
method: 'get',
params: query
})
}
// 查询【请填写功能名称】详细
export function getGoods(goodsId) {
return request({
url: '/system/goods/' + goodsId,
method: 'get'
})
}
// 新增【请填写功能名称】
export function addGoods(data) {
return request({
url: '/system/goods',
method: 'post',
data: data
})
}
// 修改【请填写功能名称】
export function updateGoods(data) {
return request({
url: '/system/goods',
method: 'put',
data: data
})
}
// 删除【请填写功能名称】
export function delGoods(goodsId) {
return request({
url: '/system/goods/' + goodsId,
method: 'delete'
})
}

44
src/api/system/led.js Normal file
View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询【请填写功能名称】列表
export function listConfig(query) {
return request({
url: '/system/led/list',
method: 'get',
params: query
})
}
// 查询【请填写功能名称】详细
export function getConfig(ledId) {
return request({
url: '/system/led/' + ledId,
method: 'get'
})
}
// 新增【请填写功能名称】
export function addConfig(data) {
return request({
url: '/system/led',
method: 'post',
data: data
})
}
// 修改【请填写功能名称】
export function updateConfig(data) {
return request({
url: '/system/led',
method: 'put',
data: data
})
}
// 删除【请填写功能名称】
export function delConfig(ledId) {
return request({
url: '/system/led/' + ledId,
method: 'delete'
})
}

View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询【请填写功能名称】列表
export function listLocation(query) {
return request({
url: '/system/location/list',
method: 'get',
params: query
})
}
// 查询【请填写功能名称】详细
export function getLocation(locationId) {
return request({
url: '/system/location/' + locationId,
method: 'get'
})
}
// 新增【请填写功能名称】
export function addLocation(data) {
return request({
url: '/system/location',
method: 'post',
data: data
})
}
// 修改【请填写功能名称】
export function updateLocation(data) {
return request({
url: '/system/location',
method: 'put',
data: data
})
}
// 删除【请填写功能名称】
export function delLocation(locationId) {
return request({
url: '/system/location/' + locationId,
method: 'delete'
})
}

44
src/api/system/stand.js Normal file
View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询【请填写功能名称】列表
export function listStand(query) {
return request({
url: '/system/stand/list',
method: 'get',
params: query
})
}
// 查询【请填写功能名称】详细
export function getStand(standId) {
return request({
url: '/system/stand/' + standId,
method: 'get'
})
}
// 新增【请填写功能名称】
export function addStand(data) {
return request({
url: '/system/stand',
method: 'post',
data: data
})
}
// 修改【请填写功能名称】
export function updateStand(data) {
return request({
url: '/system/stand',
method: 'put',
data: data
})
}
// 删除【请填写功能名称】
export function delStand(standId) {
return request({
url: '/system/stand/' + standId,
method: 'delete'
})
}

View File

@ -0,0 +1,672 @@
<template>
<div class="task-management">
<!-- 配置抽屉 -->
<el-drawer
title="页面配置"
:visible.sync="configDrawer"
direction="rtl"
size="300px"
>
<div class="drawer-content">
<h3 class="drawer-section-title">显示字段</h3>
<el-checkbox-group v-model="visibleColumns" class="column-checkboxes">
<el-checkbox
v-for="col in allColumns"
:key="col.prop"
:label="col.prop"
>
{{ col.label }}
</el-checkbox>
</el-checkbox-group>
<h3 class="drawer-section-title">表格密度</h3>
<el-radio-group v-model="tableSize" class="density-radio">
<el-radio-button label="medium">默认</el-radio-button>
<el-radio-button label="small">紧凑</el-radio-button>
<el-radio-button label="mini">超紧凑</el-radio-button>
</el-radio-group>
</div>
</el-drawer>
<!-- 搜索区域 -->
<div class="search-container" :class="{ collapsed: !showSearch }">
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="84px" :size="formSize">
<div class="search-form-content" :class="{ 'is-advanced': isAdvanced }">
<template v-if="isAdvanced">
<el-form-item label="物料编号" prop="goodsId">
<el-input
v-model="queryParams.goodsId"
placeholder="请输入物料编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="物料名称" prop="goodsName">
<el-input
v-model="queryParams.goodsName"
placeholder="请输入物料名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="单位" prop="goodsUnit">
<el-input
v-model="queryParams.goodsUnit"
placeholder="请输入单位"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="物料类型" prop="goodsType">
<el-input
v-model="queryParams.goodsType"
placeholder="请输入物料类型"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="通用容器类型" prop="normalVehicleType">
<el-input
v-model="queryParams.normalVehicleType"
placeholder="请输入通用容器类型"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="物料状态" prop="goodsStatus">
<el-input
v-model="queryParams.goodsStatus"
placeholder="请输入物料状态"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="最近更新用户" prop="lastUpdateUser">
<el-input
v-model="queryParams.lastUpdateUser"
placeholder="请输入最近更新用户"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
</template>
</div>
<div class="search-form-footer">
<div class="left">
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
<el-button
type="text"
@click="toggleAdvanced"
class="advanced-toggle"
>
{{ isAdvanced ? '收起' : '展开' }}
<i :class="['el-icon-arrow-' + (isAdvanced ? 'up' : 'down')]"></i>
</el-button>
</div>
<div class="right">
<el-button
icon="el-icon-s-operation"
@click="toggleSearch"
circle
size="mini"
></el-button>
</div>
</div>
</el-form>
</div>
<!-- 工具栏 -->
<div class="toolbar-container">
<div class="left">
<el-button-group>
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:goods:add']"
>新增</el-button>
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:goods:edit']"
>修改</el-button>
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:goods:remove']"
>删除</el-button>
</el-button-group>
</div>
<div class="right">
<el-tooltip content="导出数据" placement="top">
<el-button
type="warning"
icon="el-icon-download"
@click="handleExport"
v-hasPermi="['system:goods:export']"
>导出</el-button>
</el-tooltip>
<el-tooltip content="导入数据" placement="top">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleImport"
v-hasPermi="['system:goods:import']"
>导入</el-button>
</el-tooltip>
<el-tooltip content="列设置" placement="top">
<el-button
icon="el-icon-setting"
@click="configDrawer = true"
circle
></el-button>
</el-tooltip>
<el-tooltip content="刷新" placement="top">
<el-button
icon="el-icon-refresh"
@click="getList"
circle
></el-button>
</el-tooltip>
</div>
</div>
<!-- 表格 -->
<div class="table-container">
<el-table
v-loading="loading"
:data="messageList"
@selection-change="handleSelectionChange"
border
stripe
highlight-current-row
@sort-change="handleSortChange"
:size="tableSize"
:max-height="tableHeight"
>
<el-table-column type="selection" width="55" align="center" fixed="left"/>
<template v-for="col in tableColumns">
<el-table-column
:key="col.prop"
:label="col.label"
:prop="col.prop"
:width="col.width"
:min-width="col.minWidth"
align="center"
:sortable="col.sortable"
:show-overflow-tooltip="col.tooltip"
v-if="isColumnVisible(col.prop)"
>
<template slot-scope="scope">
<template v-if="col.type === 'dict'">
<dict-tag :options="dict.type[col.dict]" :value="scope.row[col.prop]"/>
</template>
<template v-if="col.prop === 'sts'">
<dict-tag :options="dict.type.kc_sts" :value="scope.row.sts"/>
</template>
<template v-else-if="col.type === 'number'">
<span class="number-column">{{ scope.row[col.prop] }}</span>
</template>
<template v-else-if="col.type === 'datetime'">
<span>{{ parseTime(scope.row[col.prop]) }}</span>
</template>
<template v-else>
{{ scope.row[col.prop] }}
</template>
</template>
</el-table-column>
</template>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
<!-- 弹窗 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body destroy-on-close>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="物料名称" prop="goodsName">
<el-input v-model="form.goodsName" placeholder="请输入物料名称" />
</el-form-item>
<el-form-item label="单位" prop="goodsUnit">
<el-input v-model="form.goodsUnit" placeholder="请输入单位" />
</el-form-item>
<el-form-item label="物料类型" prop="goodsType">
<el-input v-model="form.goodsType" placeholder="请输入物料类型" />
</el-form-item>
<el-form-item label="通用容器类型" prop="normalVehicleType">
<el-input v-model="form.normalVehicleType" placeholder="请输入通用容器类型" />
</el-form-item>
<el-form-item label="物料状态" prop="goodsStatus">
<el-input v-model="form.goodsStatus" placeholder="请输入物料状态" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="最近更新用户" prop="lastUpdateUser">
<el-input v-model="form.lastUpdateUser" placeholder="请输入最近更新用户" />
</el-form-item>
<el-form-item label="最近更新时间" prop="lastUpdateTime">
<el-date-picker clearable
v-model="form.lastUpdateTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择最近更新时间">
</el-date-picker>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<!-- 导入 -->
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
<el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess" :auto-upload="false" drag>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div class="el-upload__tip text-center" slot="tip">
<span>仅允许导入xlsxlsx格式文件</span>
<el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFileForm"> </el-button>
<el-button @click="upload.open = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
// import {addMessage, updateMessage} from "@/api/system/message";
import {getToken} from "@/utils/auth";
import {addGoods, delGoods, getGoods, listGoods, updateGoods} from "@/api/system/goods";
export default {
name: "goods",
dicts: ['kc_sts','site_type'],
data() {
return {
upload: {
open: false,
title: '上传文件',
headers: { Authorization: 'Bearer ' + getToken() },
url: process.env.VUE_APP_BASE_API + '/system/site/importData', // URL
isUploading: false
},
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
isAdvanced: true,
//
showSearch: true,
//
total: 0,
//
messageList: [],
//
title: "",
//
open: false,
//
daterangeCreateTime: [],
//
configDrawer: false,
//
tableSize: 'small',
//
formSize: 'small',
//
tableHeight: window.innerHeight - 300,
//
visibleColumns: [],
//
allColumns: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
goodsId: null,
goodsName: null,
goodsUnit: null,
goodsType: null,
normalVehicleType: null,
goodsStatus: null,
lastUpdateUser: null,
lastUpdateTime: null
},
//
form: {},
//
rules: {
goodsUnit: [
{ required: true, message: "单位,不能为空不能为空", trigger: "blur" }
],
goodsStatus: [
{ required: true, message: "物料状态,不可为空不能为空", trigger: "blur" }
],
}
};
},
computed: {
//
tableColumns() {
return this.allColumns.filter(col => this.isColumnVisible(col.prop));
}
},
created() {
this.getList();
this.initTableHeight();
window.addEventListener('resize', this.handleResize);
},
beforeDestroy() {
window.removeEventListener('resize', this.handleResize);
},
methods: {
//
initTableHeight() {
this.tableHeight = window.innerHeight - 300;
},
//
handleResize() {
this.tableHeight = window.innerHeight - 300;
},
//
isColumnVisible(prop) {
return this.visibleColumns.includes(prop);
},
//
toggleSearch() {
this.showSearch = !this.showSearch;
},
/**
列表 */
getList() {
this.loading = true;
this.queryParams.params = {};
if (null != this.daterangeCreateTime && '' != this.daterangeCreateTime) {
this.queryParams.params["beginCreateTime"] = this.daterangeCreateTime[0];
this.queryParams.params["endCreateTime"] = this.daterangeCreateTime[1];
}
listGoods(this.queryParams).then(response => {
this.allColumns = response.columns
console.log('All columns:', this.allColumns);
this.allColumns.forEach((column) => {
this.visibleColumns.push(column.prop)
});
this.messageList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
goodsId: null,
goodsName: null,
goodsUnit: null,
goodsType: null,
normalVehicleType: null,
goodsStatus: null,
remark: null,
lastUpdateUser: null,
lastUpdateTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.daterangeCreateTime = [];
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.goodsId)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加物料信息";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const materialCode = this.ids
getGoods(materialCode).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改物料信息";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.goodsId != null) {
updateGoods(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addGoods(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const materialCodes = row.goodsId || this.ids;
this.$modal.confirm('是否确认删除物料编号为"' + materialCodes + '"的数据项?').then(function () {
return delGoods(materialCodes);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
});
},
/** 导出按钮操作 */
handleExport() {
this.download('system/goods/export', {
...this.queryParams
}, `goods_${new Date().getTime()}.xlsx`)
},
handleImport() {
this.upload.title = '导入';
this.upload.open = true;
},
/** 下载模板操作 */
importTemplate() {
this.download('/system/goods/importTemplate', {}, `bas_goods_${new Date().getTime()}.xlsx`);
},
//
handleFileUploadProgress(event, file, fileList) {
this.upload.isUploading = true;
},
//
handleFileSuccess(response, file, fileList) {
this.upload.open = false;
this.upload.isUploading = false;
this.$refs.upload.clearFiles();
this.$alert(
"<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
response.msg +
'</div>',
'导入结果',
{ dangerouslyUseHTMLString: true },
);
this.getList();
},
//
submitFileForm() {
this.$refs.upload.submit();
},
/** 排序触发事件 */
handleSortChange({ prop, order }) {
this.queryParams.orderByColumn = prop;
this.queryParams.isAsc = order === 'ascending' ? 'asc' : 'desc';
this.getList();
},
/** 切换高级搜索 */
toggleAdvanced() {
this.isAdvanced = !this.isAdvanced;
},
}
};
</script>
<style lang="scss" scoped>
.task-management {
padding: 16px;
background: #f5f7fa;
min-height: calc(100vh - 84px);
.search-container {
background: #fff;
border-radius: 4px;
padding: 24px;
margin-bottom: 16px;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
transition: all 0.3s ease;
&.collapsed {
padding: 0;
height: 0;
overflow: hidden;
margin-bottom: 8px;
}
.search-form-content {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 16px;
transition: all 0.3s;
}
.search-form-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 16px;
border-top: 1px solid #ebeef5;
}
}
.toolbar-container {
background: #fff;
padding: 8px 16px;
border-radius: 4px;
margin-bottom: 16px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
.left {
display: flex;
gap: 8px;
}
.right {
display: flex;
gap: 8px;
}
}
.table-container {
background: #fff;
padding: 16px;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
.el-table {
//
.number-column {
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
color: #409eff;
}
}
}
.pagination-container {
margin-top: 16px;
display: flex;
justify-content: flex-end;
}
//
.drawer-content {
padding: 20px;
.drawer-section-title {
font-size: 16px;
font-weight: 500;
color: #303133;
margin: 0 0 16px;
&:not(:first-child) {
margin-top: 24px;
}
}
.column-checkboxes {
display: flex;
flex-direction: column;
gap: 12px;
}
.density-radio {
width: 100%;
.el-radio-button {
margin-right: 8px;
}
}
}
}
</style>

View File

@ -0,0 +1,652 @@
<template>
<div class="task-management">
<!-- 配置抽屉 -->
<el-drawer
title="页面配置"
:visible.sync="configDrawer"
direction="rtl"
size="300px"
>
<div class="drawer-content">
<h3 class="drawer-section-title">显示字段</h3>
<el-checkbox-group v-model="visibleColumns" class="column-checkboxes">
<el-checkbox
v-for="col in allColumns"
:key="col.prop"
:label="col.prop"
>
{{ col.label }}
</el-checkbox>
</el-checkbox-group>
<h3 class="drawer-section-title">表格密度</h3>
<el-radio-group v-model="tableSize" class="density-radio">
<el-radio-button label="medium">默认</el-radio-button>
<el-radio-button label="small">紧凑</el-radio-button>
<el-radio-button label="mini">超紧凑</el-radio-button>
</el-radio-group>
</div>
</el-drawer>
<!-- 搜索区域 -->
<div class="search-container" :class="{ collapsed: !showSearch }">
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="84px" :size="formSize">
<div class="search-form-content" :class="{ 'is-advanced': isAdvanced }">
<template v-if="isAdvanced">
<!-- <el-form-item label="站台名称" prop="standName">-->
<!-- <el-input-->
<!-- v-model="queryParams.standName"-->
<!-- placeholder="请输入站台名称"-->
<!-- clearable-->
<!-- @keyup.enter.native="handleQuery"-->
<!-- />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="站台区域" prop="standArea">-->
<!-- <el-input-->
<!-- v-model="queryParams.standArea"-->
<!-- placeholder="请输入站台区域"-->
<!-- clearable-->
<!-- @keyup.enter.native="handleQuery"-->
<!-- />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="站台属性" prop="standProperty">-->
<!-- <el-input-->
<!-- v-model="queryParams.standProperty"-->
<!-- placeholder="请输入站台属性"-->
<!-- clearable-->
<!-- @keyup.enter.native="handleQuery"-->
<!-- />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="是否锁定" prop="isLock">-->
<!-- <el-input-->
<!-- v-model="queryParams.isLock"-->
<!-- placeholder="请输入是否锁定"-->
<!-- clearable-->
<!-- @keyup.enter.native="handleQuery"-->
<!-- />-->
<!-- </el-form-item>-->
</template>
</div>
<div class="search-form-footer">
<div class="left">
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
<el-button
type="text"
@click="toggleAdvanced"
class="advanced-toggle"
>
{{ isAdvanced ? '收起' : '展开' }}
<i :class="['el-icon-arrow-' + (isAdvanced ? 'up' : 'down')]"></i>
</el-button>
</div>
<div class="right">
<el-button
icon="el-icon-s-operation"
@click="toggleSearch"
circle
size="mini"
></el-button>
</div>
</div>
</el-form>
</div>
<!-- 工具栏 -->
<div class="toolbar-container">
<div class="left">
<el-button-group>
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:led:add']"
>新增</el-button>
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:led:edit']"
>修改</el-button>
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:led:remove']"
>删除</el-button>
</el-button-group>
</div>
<div class="right">
<el-tooltip content="导出数据" placement="top">
<el-button
type="warning"
icon="el-icon-download"
@click="handleExport"
v-hasPermi="['system:led:export']"
>导出</el-button>
</el-tooltip>
<el-tooltip content="导入数据" placement="top">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleImport"
v-hasPermi="['system:led:import']"
>导入</el-button>
</el-tooltip>
<el-tooltip content="列设置" placement="top">
<el-button
icon="el-icon-setting"
@click="configDrawer = true"
circle
></el-button>
</el-tooltip>
<el-tooltip content="刷新" placement="top">
<el-button
icon="el-icon-refresh"
@click="getList"
circle
></el-button>
</el-tooltip>
</div>
</div>
<!-- 表格 -->
<div class="table-container">
<el-table
v-loading="loading"
:data="messageList"
@selection-change="handleSelectionChange"
border
stripe
highlight-current-row
@sort-change="handleSortChange"
:size="tableSize"
:max-height="tableHeight"
>
<el-table-column type="selection" width="55" align="center" fixed="left"/>
<template v-for="col in tableColumns">
<el-table-column
:key="col.prop"
:label="col.label"
:prop="col.prop"
:width="col.width"
:min-width="col.minWidth"
align="center"
:sortable="col.sortable"
:show-overflow-tooltip="col.tooltip"
v-if="isColumnVisible(col.prop)"
>
<template slot-scope="scope">
<template v-if="col.type === 'dict'">
<dict-tag :options="dict.type[col.dict]" :value="scope.row[col.prop]"/>
</template>
<template v-if="col.prop === 'sts'">
<dict-tag :options="dict.type.kc_sts" :value="scope.row.sts"/>
</template>
<template v-else-if="col.type === 'number'">
<span class="number-column">{{ scope.row[col.prop] }}</span>
</template>
<template v-else-if="col.type === 'datetime'">
<span>{{ parseTime(scope.row[col.prop]) }}</span>
</template>
<template v-else>
{{ scope.row[col.prop] }}
</template>
</template>
</el-table-column>
</template>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
<!-- 弹窗 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body destroy-on-close>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<!-- <el-form-item label="站台名称" prop="standName">-->
<!-- <el-input v-model="form.standName" placeholder="请输入站台名称" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="站台区域" prop="standArea">-->
<!-- <el-input v-model="form.standArea" placeholder="请输入站台区域" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="站台类型" prop="standType">-->
<!-- <el-select v-model="form.standType" placeholder="请选择站台类型">-->
<!-- <el-option-->
<!-- v-for="dict in dict.type.site_type"-->
<!-- :key="dict.value"-->
<!-- :label="dict.label"-->
<!-- :value="dict.value"-->
<!-- ></el-option>-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="站台状态" prop="standStatus">-->
<!-- <el-select v-model="form.standStatus" placeholder="请选择站台状态">-->
<!-- <el-option-->
<!-- v-for="dict in dict.type.site_status"-->
<!-- :key="dict.value"-->
<!-- :label="dict.label"-->
<!-- :value="dict.value"-->
<!-- ></el-option>-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="站台属性" prop="standProperty">-->
<!-- <el-input v-model="form.standProperty" placeholder="请输入站台属性" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="是否锁定" prop="isLock">-->
<!-- <el-input v-model="form.isLock" placeholder="请输入是否锁定" />-->
<!-- </el-form-item>-->
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<!-- 导入 -->
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
<el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess" :auto-upload="false" drag>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div class="el-upload__tip text-center" slot="tip">
<span>仅允许导入xlsxlsx格式文件</span>
<el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFileForm"> </el-button>
<el-button @click="upload.open = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {listConfig, getConfig, addConfig, updateConfig, delConfig,} from "@/api/system/led";
// import {addMessage, updateMessage} from "@/api/system/message";
import {getToken} from "@/utils/auth";
export default {
name: "led",
dicts: ['kc_sts','site_type'],
data() {
return {
upload: {
open: false,
title: '上传文件',
headers: { Authorization: 'Bearer ' + getToken() },
url: process.env.VUE_APP_BASE_API + '/system/led/importData', // URL
isUploading: false
},
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
isAdvanced: true,
//
showSearch: true,
//
total: 0,
//
messageList: [],
//
title: "",
//
open: false,
//
daterangeCreateTime: [],
//
configDrawer: false,
//
tableSize: 'small',
//
formSize: 'small',
//
tableHeight: window.innerHeight - 300,
//
visibleColumns: [],
//
allColumns: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
},
//
form: {},
//
rules: {
// standName: [
// { required: true, message: ",", trigger: "blur" }
// ],
// standArea: [
// { required: true, message: "", trigger: "blur" }
// ],
// standType: [
// { required: true, message: "", trigger: "change" }
// ],
// standStatus: [
// { required: true, message: "", trigger: "change" }
// ],
// standProperty: [
// { required: true, message: "", trigger: "change" }
// ],
// isLock: [
// { required: true, message: "", trigger: "change" }
// ],
}
};
},
computed: {
//
tableColumns() {
return this.allColumns.filter(col => this.isColumnVisible(col.prop));
}
},
created() {
this.getList();
this.initTableHeight();
window.addEventListener('resize', this.handleResize);
},
beforeDestroy() {
window.removeEventListener('resize', this.handleResize);
},
methods: {
//
initTableHeight() {
this.tableHeight = window.innerHeight - 300;
},
//
handleResize() {
this.tableHeight = window.innerHeight - 300;
},
//
isColumnVisible(prop) {
return this.visibleColumns.includes(prop);
},
//
toggleSearch() {
this.showSearch = !this.showSearch;
},
/**
列表 */
getList() {
this.loading = true;
this.queryParams.params = {};
if (null != this.daterangeCreateTime && '' != this.daterangeCreateTime) {
this.queryParams.params["beginCreateTime"] = this.daterangeCreateTime[0];
this.queryParams.params["endCreateTime"] = this.daterangeCreateTime[1];
}
listConfig(this.queryParams).then(response => {
this.allColumns = response.columns
console.log('All columns:', this.allColumns);
this.allColumns.forEach((column) => {
this.visibleColumns.push(column.prop)
});
this.messageList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
// standName: null,
// standType: null,
// standArea: null,
// standProperty: null,
// standStatus: null,
// isLock: null,
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.daterangeCreateTime = [];
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.ledId)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加LED显示";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const materialCode = this.ids
getConfig(materialCode).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改LED显示";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.materialCode != null) {
updateConfig(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addConfig(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const materialCodes = row.ledId || this.ids;
this.$modal.confirm('是否确认删除id编号为"' + materialCodes + '"的数据项?').then(function () {
return delConfig(materialCodes);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
});
},
/** 导出按钮操作 */
handleExport() {
this.download('system/led/export', {
...this.queryParams
}, `led_${new Date().getTime()}.xlsx`)
},
handleImport() {
this.upload.title = '导入';
this.upload.open = true;
},
/** 下载模板操作 */
importTemplate() {
this.download('/system/led/importTemplate', {}, `bas_led_${new Date().getTime()}.xlsx`);
},
//
handleFileUploadProgress(event, file, fileList) {
this.upload.isUploading = true;
},
//
handleFileSuccess(response, file, fileList) {
this.upload.open = false;
this.upload.isUploading = false;
this.$refs.upload.clearFiles();
this.$alert(
"<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
response.msg +
'</div>',
'导入结果',
{ dangerouslyUseHTMLString: true },
);
this.getList();
},
//
submitFileForm() {
this.$refs.upload.submit();
},
/** 排序触发事件 */
handleSortChange({ prop, order }) {
this.queryParams.orderByColumn = prop;
this.queryParams.isAsc = order === 'ascending' ? 'asc' : 'desc';
this.getList();
},
/** 切换高级搜索 */
toggleAdvanced() {
this.isAdvanced = !this.isAdvanced;
},
}
};
</script>
<style lang="scss" scoped>
.task-management {
padding: 16px;
background: #f5f7fa;
min-height: calc(100vh - 84px);
.search-container {
background: #fff;
border-radius: 4px;
padding: 24px;
margin-bottom: 16px;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
transition: all 0.3s ease;
&.collapsed {
padding: 0;
height: 0;
overflow: hidden;
margin-bottom: 8px;
}
.search-form-content {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 16px;
transition: all 0.3s;
}
.search-form-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 16px;
border-top: 1px solid #ebeef5;
}
}
.toolbar-container {
background: #fff;
padding: 8px 16px;
border-radius: 4px;
margin-bottom: 16px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
.left {
display: flex;
gap: 8px;
}
.right {
display: flex;
gap: 8px;
}
}
.table-container {
background: #fff;
padding: 16px;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
.el-table {
//
.number-column {
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
color: #409eff;
}
}
}
.pagination-container {
margin-top: 16px;
display: flex;
justify-content: flex-end;
}
//
.drawer-content {
padding: 20px;
.drawer-section-title {
font-size: 16px;
font-weight: 500;
color: #303133;
margin: 0 0 16px;
&:not(:first-child) {
margin-top: 24px;
}
}
.column-checkboxes {
display: flex;
flex-direction: column;
gap: 12px;
}
.density-radio {
width: 100%;
.el-radio-button {
margin-right: 8px;
}
}
}
}
</style>

View File

@ -0,0 +1,784 @@
<template>
<div class="task-management">
<!-- 配置抽屉 -->
<el-drawer
title="页面配置"
:visible.sync="configDrawer"
direction="rtl"
size="300px"
>
<div class="drawer-content">
<h3 class="drawer-section-title">显示字段</h3>
<el-checkbox-group v-model="visibleColumns" class="column-checkboxes">
<el-checkbox
v-for="col in allColumns"
:key="col.prop"
:label="col.prop"
>
{{ col.label }}
</el-checkbox>
</el-checkbox-group>
<h3 class="drawer-section-title">表格密度</h3>
<el-radio-group v-model="tableSize" class="density-radio">
<el-radio-button label="medium">默认</el-radio-button>
<el-radio-button label="small">紧凑</el-radio-button>
<el-radio-button label="mini">超紧凑</el-radio-button>
</el-radio-group>
</div>
</el-drawer>
<!-- 搜索区域 -->
<div class="search-container" :class="{ collapsed: !showSearch }">
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="84px" :size="formSize">
<div class="search-form-content" :class="{ 'is-advanced': isAdvanced }">
<template v-if="isAdvanced">
<el-form-item label="库位号" prop="locationId">
<el-input
v-model="queryParams.locationId"
placeholder="请输入库位号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="库位类型" prop="locationType">
<el-input
v-model="queryParams.locationType"
placeholder="请输入库位类型"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="库位状态" prop="locationStatus">
<el-input
v-model="queryParams.locationStatus"
placeholder="请输入库位状态"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="外部库位号" prop="outerId">
<el-input
v-model="queryParams.outerId"
placeholder="请输入外部库位号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="库区号" prop="areaId">
<el-input
v-model="queryParams.areaId"
placeholder="请输入库区号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="巷道号" prop="tunnelId">
<el-input
v-model="queryParams.tunnelId"
placeholder="请输入巷道号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="设备号" prop="equipmentId">
<el-input
v-model="queryParams.equipmentId"
placeholder="请输入设备号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="排" prop="wRow">
<el-input
v-model="queryParams.wRow"
placeholder="请输入排"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="列" prop="wCol">
<el-input
v-model="queryParams.wCol"
placeholder="请输入列"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="层" prop="wLayer">
<el-input
v-model="queryParams.wLayer"
placeholder="请输入层"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="深度" prop="wDepth">
<el-input
v-model="queryParams.wDepth"
placeholder="请输入深度"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="是否锁定" prop="isLock">
<el-input
v-model="queryParams.isLock"
placeholder="请输入是否锁定"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="载具号" prop="vehicleId">
<el-input
v-model="queryParams.vehicleId"
placeholder="请输入载具号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="是否正在工作" prop="isWorking">
<el-input
v-model="queryParams.isWorking"
placeholder="请输入是否正在工作"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
</template>
</div>
<div class="search-form-footer">
<div class="left">
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
<el-button
type="text"
@click="toggleAdvanced"
class="advanced-toggle"
>
{{ isAdvanced ? '收起' : '展开' }}
<i :class="['el-icon-arrow-' + (isAdvanced ? 'up' : 'down')]"></i>
</el-button>
</div>
<div class="right">
<el-button
icon="el-icon-s-operation"
@click="toggleSearch"
circle
size="mini"
></el-button>
</div>
</div>
</el-form>
</div>
<!-- 工具栏 -->
<div class="toolbar-container">
<div class="left">
<el-button-group>
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:location:add']"
>新增</el-button>
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:location:edit']"
>修改</el-button>
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:location:remove']"
>删除</el-button>
</el-button-group>
</div>
<div class="right">
<el-tooltip content="导出数据" placement="top">
<el-button
type="warning"
icon="el-icon-download"
@click="handleExport"
v-hasPermi="['system:location:export']"
>导出</el-button>
</el-tooltip>
<el-tooltip content="导入数据" placement="top">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleImport"
v-hasPermi="['system:location:import']"
>导入</el-button>
</el-tooltip>
<el-tooltip content="列设置" placement="top">
<el-button
icon="el-icon-setting"
@click="configDrawer = true"
circle
></el-button>
</el-tooltip>
<el-tooltip content="刷新" placement="top">
<el-button
icon="el-icon-refresh"
@click="getList"
circle
></el-button>
</el-tooltip>
</div>
</div>
<!-- 表格 -->
<div class="table-container">
<el-table
v-loading="loading"
:data="messageList"
@selection-change="handleSelectionChange"
border
stripe
highlight-current-row
@sort-change="handleSortChange"
:size="tableSize"
:max-height="tableHeight"
>
<el-table-column type="selection" width="55" align="center" fixed="left"/>
<template v-for="col in tableColumns">
<el-table-column
:key="col.prop"
:label="col.label"
:prop="col.prop"
:width="col.width"
:min-width="col.minWidth"
align="center"
:sortable="col.sortable"
:show-overflow-tooltip="col.tooltip"
v-if="isColumnVisible(col.prop)"
>
<template slot-scope="scope">
<template v-if="col.type === 'dict'">
<dict-tag :options="dict.type[col.dict]" :value="scope.row[col.prop]"/>
</template>
<template v-if="col.prop === 'sts'">
<dict-tag :options="dict.type.kc_sts" :value="scope.row.sts"/>
</template>
<template v-else-if="col.type === 'number'">
<span class="number-column">{{ scope.row[col.prop] }}</span>
</template>
<template v-else-if="col.type === 'datetime'">
<span>{{ parseTime(scope.row[col.prop]) }}</span>
</template>
<template v-else>
{{ scope.row[col.prop] }}
</template>
</template>
</el-table-column>
</template>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
<!-- 弹窗 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body destroy-on-close>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="库位号" prop="locationId">
<el-input v-model="form.locationId" placeholder="请输入库位号" />
</el-form-item>
<el-form-item label="库位类型" prop="locationType">
<el-input v-model="form.locationType" placeholder="请输入库位类型" />
</el-form-item>
<el-form-item label="库位状态" prop="locationStatus">
<el-input v-model="form.locationStatus" placeholder="请输入库位状态" />
</el-form-item>
<el-form-item label="外部库位号" prop="outerId">
<el-input v-model="form.outerId" placeholder="请输入外部库位号" />
</el-form-item>
<el-form-item label="库区号" prop="areaId">
<el-input v-model="form.areaId" placeholder="请输入库区号" />
</el-form-item>
<el-form-item label="巷道号" prop="tunnelId">
<el-input v-model="form.tunnelId" placeholder="请输入巷道号" />
</el-form-item>
<el-form-item label="设备号" prop="equipmentId">
<el-input v-model="form.equipmentId" placeholder="请输入设备号" />
</el-form-item>
<el-form-item label="排" prop="wRow">
<el-input v-model="form.wRow" placeholder="请输入排" />
</el-form-item>
<el-form-item label="列" prop="wCol">
<el-input v-model="form.wCol" placeholder="请输入列" />
</el-form-item>
<el-form-item label="层" prop="wLayer">
<el-input v-model="form.wLayer" placeholder="请输入层" />
</el-form-item>
<el-form-item label="深度" prop="wDepth">
<el-input v-model="form.wDepth" placeholder="请输入深度" />
</el-form-item>
<el-form-item label="是否锁定" prop="isLock">
<el-input v-model="form.isLock" placeholder="请输入是否锁定" />
</el-form-item>
<el-form-item label="载具号" prop="vehicleId">
<el-input v-model="form.vehicleId" placeholder="请输入载具号" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="是否正在工作" prop="isWorking">
<el-input v-model="form.isWorking" placeholder="请输入是否正在工作" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<!-- 导入 -->
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
<el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess" :auto-upload="false" drag>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div class="el-upload__tip text-center" slot="tip">
<span>仅允许导入xlsxlsx格式文件</span>
<el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFileForm"> </el-button>
<el-button @click="upload.open = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {listLocation, getLocation, addLocation, updateLocation, delLocation} from "@/api/system/location";
// import {addMessage, updateMessage} from "@/api/system/message";
import {getToken} from "@/utils/auth";
export default {
name: "location",
dicts: ['kc_sts','site_type'],
data() {
return {
upload: {
open: false,
title: '上传文件',
headers: { Authorization: 'Bearer ' + getToken() },
url: process.env.VUE_APP_BASE_API + '/system/location/importData', // URL
isUploading: false
},
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
isAdvanced: true,
//
showSearch: true,
//
total: 0,
//
messageList: [],
//
title: "",
//
open: false,
//
daterangeCreateTime: [],
//
configDrawer: false,
//
tableSize: 'small',
//
formSize: 'small',
//
tableHeight: window.innerHeight - 300,
//
visibleColumns: [],
//
allColumns: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
locationType: null,
locationStatus: null,
outerId: null,
areaId: null,
tunnelId: null,
equipmentId: null,
wRow: null,
wCol: null,
wLayer: null,
wDepth: null,
isLock: null,
vehicleId: null,
isWorking: null
},
//
form: {},
//
rules: {
locationId: [
{ required: true, message: "库位号不能为空", trigger: "change" }
],
locationType: [
{ required: true, message: "库位类型不能为空", trigger: "change" }
],
locationStatus: [
{ required: true, message: "库位状态不能为空", trigger: "change" }
],
areaId: [
{ required: true, message: "库区号不能为空", trigger: "blur" }
],
tunnelId: [
{ required: true, message: "巷道号不能为空", trigger: "blur" }
],
equipmentId: [
{ required: true, message: "设备号不能为空", trigger: "blur" }
],
wRow: [
{ required: true, message: "排不能为空", trigger: "blur" }
],
wCol: [
{ required: true, message: "列不能为空", trigger: "blur" }
],
wLayer: [
{ required: true, message: "层不能为空", trigger: "blur" }
],
wDepth: [
{ required: true, message: "深度不能为空", trigger: "blur" }
],
isLock: [
{ required: true, message: "是否锁定不能为空", trigger: "blur" }
],
isWorking: [
{ required: true, message: "是否正在工作不能为空", trigger: "blur" }
]
}
};
},
computed: {
//
tableColumns() {
return this.allColumns.filter(col => this.isColumnVisible(col.prop));
}
},
created() {
this.getList();
this.initTableHeight();
window.addEventListener('resize', this.handleResize);
},
beforeDestroy() {
window.removeEventListener('resize', this.handleResize);
},
methods: {
//
initTableHeight() {
this.tableHeight = window.innerHeight - 300;
},
//
handleResize() {
this.tableHeight = window.innerHeight - 300;
},
//
isColumnVisible(prop) {
return this.visibleColumns.includes(prop);
},
//
toggleSearch() {
this.showSearch = !this.showSearch;
},
/**
列表 */
getList() {
this.loading = true;
this.queryParams.params = {};
if (null != this.daterangeCreateTime && '' != this.daterangeCreateTime) {
this.queryParams.params["beginCreateTime"] = this.daterangeCreateTime[0];
this.queryParams.params["endCreateTime"] = this.daterangeCreateTime[1];
}
listLocation(this.queryParams).then(response => {
this.allColumns = response.columns
console.log('All columns:', this.allColumns);
this.allColumns.forEach((column) => {
this.visibleColumns.push(column.prop)
});
this.messageList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
locationId: null,
locationType: null,
locationStatus: null,
outerId: null,
areaId: null,
tunnelId: null,
equipmentId: null,
wRow: null,
wCol: null,
wLayer: null,
wDepth: null,
isLock: null,
vehicleId: null,
remark: null,
isWorking: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.daterangeCreateTime = [];
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.locationId)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加库位";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const materialCode = this.ids
getLocation(materialCode).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改库位";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.materialCode != null) {
updateLocation(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addLocation(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const materialCodes = row.locationId || this.ids;
this.$modal.confirm('是否确认删除库位号为"' + materialCodes + '"的数据项?').then(function () {
return delLocation(materialCodes);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
});
},
/** 导出按钮操作 */
handleExport() {
this.download('system/location/export', {
...this.queryParams
}, `location_${new Date().getTime()}.xlsx`)
},
handleImport() {
this.upload.title = '导入';
this.upload.open = true;
},
/** 下载模板操作 */
importTemplate() {
this.download('/system/location/importTemplate', {}, `bas_location_${new Date().getTime()}.xlsx`);
},
//
handleFileUploadProgress(event, file, fileList) {
this.upload.isUploading = true;
},
//
handleFileSuccess(response, file, fileList) {
this.upload.open = false;
this.upload.isUploading = false;
this.$refs.upload.clearFiles();
this.$alert(
"<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
response.msg +
'</div>',
'导入结果',
{ dangerouslyUseHTMLString: true },
);
this.getList();
},
//
submitFileForm() {
this.$refs.upload.submit();
},
/** 排序触发事件 */
handleSortChange({ prop, order }) {
this.queryParams.orderByColumn = prop;
this.queryParams.isAsc = order === 'ascending' ? 'asc' : 'desc';
this.getList();
},
/** 切换高级搜索 */
toggleAdvanced() {
this.isAdvanced = !this.isAdvanced;
},
}
};
</script>
<style lang="scss" scoped>
.task-management {
padding: 16px;
background: #f5f7fa;
min-height: calc(100vh - 84px);
.search-container {
background: #fff;
border-radius: 4px;
padding: 24px;
margin-bottom: 16px;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
transition: all 0.3s ease;
&.collapsed {
padding: 0;
height: 0;
overflow: hidden;
margin-bottom: 8px;
}
.search-form-content {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 16px;
transition: all 0.3s;
}
.search-form-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 16px;
border-top: 1px solid #ebeef5;
}
}
.toolbar-container {
background: #fff;
padding: 8px 16px;
border-radius: 4px;
margin-bottom: 16px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
.left {
display: flex;
gap: 8px;
}
.right {
display: flex;
gap: 8px;
}
}
.table-container {
background: #fff;
padding: 16px;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
.el-table {
//
.number-column {
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
color: #409eff;
}
}
}
.pagination-container {
margin-top: 16px;
display: flex;
justify-content: flex-end;
}
//
.drawer-content {
padding: 20px;
.drawer-section-title {
font-size: 16px;
font-weight: 500;
color: #303133;
margin: 0 0 16px;
&:not(:first-child) {
margin-top: 24px;
}
}
.column-checkboxes {
display: flex;
flex-direction: column;
gap: 12px;
}
.density-radio {
width: 100%;
.el-radio-button {
margin-right: 8px;
}
}
}
}
</style>

View File

@ -0,0 +1,657 @@
<template>
<div class="task-management">
<!-- 配置抽屉 -->
<el-drawer
title="页面配置"
:visible.sync="configDrawer"
direction="rtl"
size="300px"
>
<div class="drawer-content">
<h3 class="drawer-section-title">显示字段</h3>
<el-checkbox-group v-model="visibleColumns" class="column-checkboxes">
<el-checkbox
v-for="col in allColumns"
:key="col.prop"
:label="col.prop"
>
{{ col.label }}
</el-checkbox>
</el-checkbox-group>
<h3 class="drawer-section-title">表格密度</h3>
<el-radio-group v-model="tableSize" class="density-radio">
<el-radio-button label="medium">默认</el-radio-button>
<el-radio-button label="small">紧凑</el-radio-button>
<el-radio-button label="mini">超紧凑</el-radio-button>
</el-radio-group>
</div>
</el-drawer>
<!-- 搜索区域 -->
<div class="search-container" :class="{ collapsed: !showSearch }">
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="84px" :size="formSize">
<div class="search-form-content" :class="{ 'is-advanced': isAdvanced }">
<template v-if="isAdvanced">
<el-form-item label="站台名称" prop="standName">
<el-input
v-model="queryParams.standName"
placeholder="请输入站台名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="站台区域" prop="standArea">
<el-input
v-model="queryParams.standArea"
placeholder="请输入站台区域"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="站台属性" prop="standProperty">
<el-input
v-model="queryParams.standProperty"
placeholder="请输入站台属性"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="是否锁定" prop="isLock">
<el-input
v-model="queryParams.isLock"
placeholder="请输入是否锁定"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
</template>
</div>
<div class="search-form-footer">
<div class="left">
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
<el-button
type="text"
@click="toggleAdvanced"
class="advanced-toggle"
>
{{ isAdvanced ? '收起' : '展开' }}
<i :class="['el-icon-arrow-' + (isAdvanced ? 'up' : 'down')]"></i>
</el-button>
</div>
<div class="right">
<el-button
icon="el-icon-s-operation"
@click="toggleSearch"
circle
size="mini"
></el-button>
</div>
</div>
</el-form>
</div>
<!-- 工具栏 -->
<div class="toolbar-container">
<div class="left">
<el-button-group>
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:site:add']"
>新增</el-button>
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:site:edit']"
>修改</el-button>
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:site:remove']"
>删除</el-button>
</el-button-group>
</div>
<div class="right">
<el-tooltip content="导出数据" placement="top">
<el-button
type="warning"
icon="el-icon-download"
@click="handleExport"
v-hasPermi="['system:site:export']"
>导出</el-button>
</el-tooltip>
<el-tooltip content="导入数据" placement="top">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleImport"
v-hasPermi="['system:location:import']"
>导入</el-button>
</el-tooltip>
<el-tooltip content="列设置" placement="top">
<el-button
icon="el-icon-setting"
@click="configDrawer = true"
circle
></el-button>
</el-tooltip>
<el-tooltip content="刷新" placement="top">
<el-button
icon="el-icon-refresh"
@click="getList"
circle
></el-button>
</el-tooltip>
</div>
</div>
<!-- 表格 -->
<div class="table-container">
<el-table
v-loading="loading"
:data="messageList"
@selection-change="handleSelectionChange"
border
stripe
highlight-current-row
@sort-change="handleSortChange"
:size="tableSize"
:max-height="tableHeight"
>
<el-table-column type="selection" width="55" align="center" fixed="left"/>
<template v-for="col in tableColumns">
<el-table-column
:key="col.prop"
:label="col.label"
:prop="col.prop"
:width="col.width"
:min-width="col.minWidth"
align="center"
:sortable="col.sortable"
:show-overflow-tooltip="col.tooltip"
v-if="isColumnVisible(col.prop)"
>
<template slot-scope="scope">
<template v-if="col.type === 'dict'">
<dict-tag :options="dict.type[col.dict]" :value="scope.row[col.prop]"/>
</template>
<template v-if="col.prop === 'sts'">
<dict-tag :options="dict.type.kc_sts" :value="scope.row.sts"/>
</template>
<template v-else-if="col.type === 'number'">
<span class="number-column">{{ scope.row[col.prop] }}</span>
</template>
<template v-else-if="col.type === 'datetime'">
<span>{{ parseTime(scope.row[col.prop]) }}</span>
</template>
<template v-else>
{{ scope.row[col.prop] }}
</template>
</template>
</el-table-column>
</template>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
<!-- 弹窗 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body destroy-on-close>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="站台名称" prop="standName">
<el-input v-model="form.standName" placeholder="请输入站台名称" />
</el-form-item>
<el-form-item label="站台区域" prop="standArea">
<el-input v-model="form.standArea" placeholder="请输入站台区域" />
</el-form-item>
<el-form-item label="站台类型" prop="standType">
<el-select v-model="form.standType" placeholder="请选择站台类型">
<el-option
v-for="dict in dict.type.site_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="站台状态" prop="standStatus">
<el-select v-model="form.standStatus" placeholder="请选择站台状态">
<el-option
v-for="dict in dict.type.site_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="站台属性" prop="standProperty">
<el-input v-model="form.standProperty" placeholder="请输入站台属性" />
</el-form-item>
<el-form-item label="是否锁定" prop="isLock">
<el-input v-model="form.isLock" placeholder="请输入是否锁定" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<!-- 导入 -->
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
<el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess" :auto-upload="false" drag>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div class="el-upload__tip text-center" slot="tip">
<span>仅允许导入xlsxlsx格式文件</span>
<el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFileForm"> </el-button>
<el-button @click="upload.open = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {listStand, getStand, delStand, addStand, updateStand} from "@/api/system/stand";
// import {addMessage, updateMessage} from "@/api/system/message";
import {getToken} from "@/utils/auth";
export default {
name: "stand",
dicts: ['kc_sts','site_type'],
data() {
return {
upload: {
open: false,
title: '上传文件',
headers: { Authorization: 'Bearer ' + getToken() },
url: process.env.VUE_APP_BASE_API + '/system/site/importData', // URL
isUploading: false
},
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
isAdvanced: true,
//
showSearch: true,
//
total: 0,
//
messageList: [],
//
title: "",
//
open: false,
//
daterangeCreateTime: [],
//
configDrawer: false,
//
tableSize: 'small',
//
formSize: 'small',
//
tableHeight: window.innerHeight - 300,
//
visibleColumns: [],
//
allColumns: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
standName: null,
standType: null,
standArea: null,
standProperty: null,
standStatus: null,
isLock: null,
},
//
form: {},
//
rules: {
standName: [
{ required: true, message: "站台名称,不能为空不能为空", trigger: "blur" }
],
standArea: [
{ required: true, message: "站台区域,不可为空不能为空", trigger: "blur" }
],
standType: [
{ required: true, message: "站台类型,不能为空不能为空", trigger: "change" }
],
standStatus: [
{ required: true, message: "站台状态,不能为空不能为空", trigger: "change" }
],
standProperty: [
{ required: true, message: "站台属性,不能为空不能为空", trigger: "change" }
],
isLock: [
{ required: true, message: "是否锁定,不能为空不能为空", trigger: "change" }
],
}
};
},
computed: {
//
tableColumns() {
return this.allColumns.filter(col => this.isColumnVisible(col.prop));
}
},
created() {
this.getList();
this.initTableHeight();
window.addEventListener('resize', this.handleResize);
},
beforeDestroy() {
window.removeEventListener('resize', this.handleResize);
},
methods: {
//
initTableHeight() {
this.tableHeight = window.innerHeight - 300;
},
//
handleResize() {
this.tableHeight = window.innerHeight - 300;
},
//
isColumnVisible(prop) {
return this.visibleColumns.includes(prop);
},
//
toggleSearch() {
this.showSearch = !this.showSearch;
},
/**
列表 */
getList() {
this.loading = true;
this.queryParams.params = {};
if (null != this.daterangeCreateTime && '' != this.daterangeCreateTime) {
this.queryParams.params["beginCreateTime"] = this.daterangeCreateTime[0];
this.queryParams.params["endCreateTime"] = this.daterangeCreateTime[1];
}
listStand(this.queryParams).then(response => {
this.allColumns = response.columns
console.log('All columns:', this.allColumns);
this.allColumns.forEach((column) => {
this.visibleColumns.push(column.prop)
});
this.messageList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
standName: null,
standType: null,
standArea: null,
standProperty: null,
standStatus: null,
isLock: null,
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.daterangeCreateTime = [];
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加站点";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const materialCode = this.ids
getStand(materialCode).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改站点";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.materialCode != null) {
updateStand(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addStand(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const materialCodes = row.materialCode || this.ids;
this.$modal.confirm('是否确认删除id编号为"' + materialCodes + '"的数据项?').then(function () {
return delStand(materialCodes);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
});
},
/** 导出按钮操作 */
handleExport() {
this.download('system/site/export', {
...this.queryParams
}, `material_${new Date().getTime()}.xlsx`)
},
handleImport() {
this.upload.title = '导入';
this.upload.open = true;
},
/** 下载模板操作 */
importTemplate() {
this.download('/system/site/importTemplate', {}, `bas_site_${new Date().getTime()}.xlsx`);
},
//
handleFileUploadProgress(event, file, fileList) {
this.upload.isUploading = true;
},
//
handleFileSuccess(response, file, fileList) {
this.upload.open = false;
this.upload.isUploading = false;
this.$refs.upload.clearFiles();
this.$alert(
"<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
response.msg +
'</div>',
'导入结果',
{ dangerouslyUseHTMLString: true },
);
this.getList();
},
//
submitFileForm() {
this.$refs.upload.submit();
},
/** 排序触发事件 */
handleSortChange({ prop, order }) {
this.queryParams.orderByColumn = prop;
this.queryParams.isAsc = order === 'ascending' ? 'asc' : 'desc';
this.getList();
},
/** 切换高级搜索 */
toggleAdvanced() {
this.isAdvanced = !this.isAdvanced;
},
}
};
</script>
<style lang="scss" scoped>
.task-management {
padding: 16px;
background: #f5f7fa;
min-height: calc(100vh - 84px);
.search-container {
background: #fff;
border-radius: 4px;
padding: 24px;
margin-bottom: 16px;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
transition: all 0.3s ease;
&.collapsed {
padding: 0;
height: 0;
overflow: hidden;
margin-bottom: 8px;
}
.search-form-content {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 16px;
transition: all 0.3s;
}
.search-form-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 16px;
border-top: 1px solid #ebeef5;
}
}
.toolbar-container {
background: #fff;
padding: 8px 16px;
border-radius: 4px;
margin-bottom: 16px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
.left {
display: flex;
gap: 8px;
}
.right {
display: flex;
gap: 8px;
}
}
.table-container {
background: #fff;
padding: 16px;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
.el-table {
//
.number-column {
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
color: #409eff;
}
}
}
.pagination-container {
margin-top: 16px;
display: flex;
justify-content: flex-end;
}
//
.drawer-content {
padding: 20px;
.drawer-section-title {
font-size: 16px;
font-weight: 500;
color: #303133;
margin: 0 0 16px;
&:not(:first-child) {
margin-top: 24px;
}
}
.column-checkboxes {
display: flex;
flex-direction: column;
gap: 12px;
}
.density-radio {
width: 100%;
.el-radio-button {
margin-right: 8px;
}
}
}
}
</style>