原材料车间剩余量

This commit is contained in:
2026-05-15 15:10:25 +08:00
parent b4b550a3de
commit 5678ab82ba
9 changed files with 478 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
-- XSLMES 原材料车间剩余量菜单与权限
-- 说明
-- 1) 若已存在 /xslmes 父级菜单则复用该父级
-- 2) 若不存在则自动创建 XSLMES管理 一级菜单
-- 3) 默认授权 admin 角色role_id=f6817f48af4fb3af11b9e8bf182f618b
SET NAMES utf8mb4;
SET @xsl_parent_id = (
SELECT id
FROM sys_permission
WHERE url = '/xslmes' AND menu_type = 0
ORDER BY create_time ASC
LIMIT 1
);
SET @xsl_parent_id = IFNULL(@xsl_parent_id, '1860000000000099001');
-- 一级菜单XSLMES管理不存在时创建存在时更新为目录菜单格式
INSERT INTO sys_permission(
id, parent_id, name, url, component, component_name, menu_type, perms, perms_type, sort_no,
is_route, is_leaf, hidden, status, del_flag, always_show, keep_alive, internal_or_external, create_by, create_time
)
VALUES (
@xsl_parent_id, NULL, 'XSLMES管理', '/xslmes', 'layouts/RouteView', 'XslMesRoot', 0, NULL, '1', 80,
0, 0, 0, '1', 0, 1, 0, 0, 'admin', NOW()
)
ON DUPLICATE KEY UPDATE
name = VALUES(name),
url = VALUES(url),
component = VALUES(component),
component_name = VALUES(component_name),
menu_type = VALUES(menu_type),
perms = VALUES(perms),
perms_type = VALUES(perms_type),
sort_no = VALUES(sort_no),
is_route = VALUES(is_route),
is_leaf = VALUES(is_leaf),
hidden = VALUES(hidden),
status = VALUES(status),
del_flag = VALUES(del_flag),
always_show = VALUES(always_show),
keep_alive = VALUES(keep_alive),
internal_or_external = VALUES(internal_or_external);
-- 二级菜单原材料车间剩余量
INSERT INTO sys_permission(
id, parent_id, name, url, component, component_name, menu_type, perms, perms_type, sort_no,
is_route, is_leaf, hidden, status, del_flag, keep_alive, internal_or_external, create_by, create_time
)
VALUES (
'1860000000000099011', @xsl_parent_id, '原材料车间剩余量',
'/xslmes/mesXslRawMaterialWorkshopRemainList',
'xslmes/mesXslRawMaterialWorkshopRemain/MesXslRawMaterialWorkshopRemainList',
'MesXslRawMaterialWorkshopRemainList', 1, NULL, '1', 21,
1, 1, 0, '1', 0, 1, 0, 'admin', NOW()
)
ON DUPLICATE KEY UPDATE
parent_id = VALUES(parent_id),
name = VALUES(name),
url = VALUES(url),
component = VALUES(component),
component_name = VALUES(component_name),
menu_type = VALUES(menu_type),
perms = VALUES(perms),
perms_type = VALUES(perms_type),
sort_no = VALUES(sort_no),
is_route = VALUES(is_route),
is_leaf = VALUES(is_leaf),
hidden = VALUES(hidden),
status = VALUES(status),
del_flag = VALUES(del_flag),
keep_alive = VALUES(keep_alive),
internal_or_external = VALUES(internal_or_external);
-- 按钮权限
INSERT INTO sys_permission(id, parent_id, name, menu_type, perms, perms_type, status, del_flag, create_by, create_time) VALUES
('1860000000000099012', '1860000000000099011', '编辑', 2, 'xslmes:mes_xsl_raw_material_workshop_remain:edit', '1', '1', 0, 'admin', NOW()),
('1860000000000099013', '1860000000000099011', '导出', 2, 'xslmes:mes_xsl_raw_material_workshop_remain:exportXls', '1', '1', 0, 'admin', NOW())
ON DUPLICATE KEY UPDATE
parent_id = VALUES(parent_id),
name = VALUES(name),
menu_type = VALUES(menu_type),
perms = VALUES(perms),
perms_type = VALUES(perms_type),
status = VALUES(status),
del_flag = VALUES(del_flag);
-- admin 角色授权
INSERT INTO sys_role_permission(id, role_id, permission_id, operate_date, operate_ip)
SELECT REPLACE(UUID(), '-', ''), 'f6817f48af4fb3af11b9e8bf182f618b', p.id, NOW(), '127.0.0.1'
FROM sys_permission p
WHERE p.id IN ('1860000000000099011', '1860000000000099012', '1860000000000099013')
AND NOT EXISTS (
SELECT 1
FROM sys_role_permission rp
WHERE rp.role_id = 'f6817f48af4fb3af11b9e8bf182f618b'
AND rp.permission_id = p.id
);

View File

@@ -0,0 +1,84 @@
package org.jeecg.modules.xslmes.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialWorkshopRemain;
import org.jeecg.modules.xslmes.service.IMesXslRawMaterialWorkshopRemainService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
/**
* 原材料车间剩余量
*/
@Tag(name = "原材料车间剩余量")
@RestController
@RequestMapping("/xslmes/mesXslRawMaterialWorkshopRemain")
@Slf4j
public class MesXslRawMaterialWorkshopRemainController
extends JeecgController<MesXslRawMaterialWorkshopRemain, IMesXslRawMaterialWorkshopRemainService> {
@Autowired
private IMesXslRawMaterialWorkshopRemainService mesXslRawMaterialWorkshopRemainService;
@Operation(summary = "原材料车间剩余量-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<MesXslRawMaterialWorkshopRemain>> queryPageList(
MesXslRawMaterialWorkshopRemain query,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<MesXslRawMaterialWorkshopRemain> queryWrapper =
QueryGenerator.initQueryWrapper(query, req.getParameterMap());
Page<MesXslRawMaterialWorkshopRemain> page = new Page<>(pageNo, pageSize);
return Result.OK(mesXslRawMaterialWorkshopRemainService.page(page, queryWrapper));
}
@AutoLog(value = "原材料车间剩余量-批量设置优先使用")
@Operation(summary = "原材料车间剩余量-批量设置优先使用")
@RequiresPermissions("xslmes:mes_xsl_raw_material_workshop_remain:edit")
@PutMapping(value = "/batchUpdatePriority")
public Result<String> batchUpdatePriority(
@RequestParam(name = "ids") String ids,
@RequestParam(name = "priorityPickup") String priorityPickup) {
List<String> idList =
Arrays.stream(ids.split(","))
.map(String::trim)
.filter(StringUtils::isNotBlank)
.toList();
if (idList.isEmpty()) {
return Result.error("请先选择记录");
}
if (!"0".equals(priorityPickup) && !"1".equals(priorityPickup)) {
return Result.error("priorityPickup 仅支持 0 或 1");
}
UpdateWrapper<MesXslRawMaterialWorkshopRemain> uw = new UpdateWrapper<>();
uw.in("id", idList).set("priority_pickup", priorityPickup);
mesXslRawMaterialWorkshopRemainService.update(uw);
return Result.OK("批量更新成功!");
}
@RequiresPermissions("xslmes:mes_xsl_raw_material_workshop_remain:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, MesXslRawMaterialWorkshopRemain query) {
return super.exportXls(request, query, MesXslRawMaterialWorkshopRemain.class, "原材料车间剩余量");
}
}

View File

@@ -0,0 +1,82 @@
package org.jeecg.modules.xslmes.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import java.math.BigDecimal;
import java.util.Date;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecg.common.system.base.entity.JeecgEntity;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
/**
* 原材料车间剩余量
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("mes_xsl_raw_material_card")
@Schema(description = "原材料车间剩余量")
public class MesXslRawMaterialWorkshopRemain extends JeecgEntity {
private static final long serialVersionUID = 1L;
@Excel(name = "条码", width = 20)
@Schema(description = "条码")
private String barcode;
@Excel(name = "批次号", width = 20)
@Schema(description = "批次号")
private String batchNo;
@Excel(name = "入场日期", width = 15, format = "yyyy-MM-dd")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
@Schema(description = "入场日期")
private Date entryDate;
@Excel(name = "物料名称", width = 20)
@Schema(description = "物料名称")
private String materialName;
@Excel(name = "供应商", width = 20)
@Schema(description = "供应商")
private String supplierName;
@Excel(name = "保质期", width = 15)
@Schema(description = "保质期")
private String shelfLife;
@Excel(name = "总重", width = 12)
@Schema(description = "总重")
private BigDecimal totalWeight;
@Excel(name = "剩余重量", width = 12)
@Schema(description = "剩余重量")
private BigDecimal remainingWeight;
@Excel(name = "剩余数量", width = 12)
@Schema(description = "剩余数量")
private Integer remainingQuantity;
@Excel(name = "检测结果", width = 12, dicCode = "xslmes_test_result")
@Dict(dicCode = "xslmes_test_result")
@Schema(description = "检测结果")
private String testResult;
@Excel(name = "状态", width = 10, dicCode = "xslmes_card_status")
@Dict(dicCode = "xslmes_card_status")
@Schema(description = "状态")
private String status;
@Excel(name = "优先使用", width = 10, dicCode = "yn")
@Dict(dicCode = "yn")
@TableField("priority_pickup")
@Schema(description = "优先使用(yn:1是 0否)")
private String priorityPickup;
}

View File

@@ -0,0 +1,12 @@
package org.jeecg.modules.xslmes.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialWorkshopRemain;
/**
* 原材料车间剩余量 Mapper
*/
@Mapper
public interface MesXslRawMaterialWorkshopRemainMapper extends BaseMapper<MesXslRawMaterialWorkshopRemain> {
}

View File

@@ -0,0 +1,10 @@
package org.jeecg.modules.xslmes.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialWorkshopRemain;
/**
* 原材料车间剩余量
*/
public interface IMesXslRawMaterialWorkshopRemainService extends IService<MesXslRawMaterialWorkshopRemain> {
}

View File

@@ -0,0 +1,16 @@
package org.jeecg.modules.xslmes.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialWorkshopRemain;
import org.jeecg.modules.xslmes.mapper.MesXslRawMaterialWorkshopRemainMapper;
import org.jeecg.modules.xslmes.service.IMesXslRawMaterialWorkshopRemainService;
import org.springframework.stereotype.Service;
/**
* 原材料车间剩余量
*/
@Service
public class MesXslRawMaterialWorkshopRemainServiceImpl
extends ServiceImpl<MesXslRawMaterialWorkshopRemainMapper, MesXslRawMaterialWorkshopRemain>
implements IMesXslRawMaterialWorkshopRemainService {
}

View File

@@ -0,0 +1,20 @@
import { defHttp } from '/@/utils/http/axios';
enum Api {
list = '/xslmes/mesXslRawMaterialWorkshopRemain/list',
exportXls = '/xslmes/mesXslRawMaterialWorkshopRemain/exportXls',
batchUpdatePriority = '/xslmes/mesXslRawMaterialWorkshopRemain/batchUpdatePriority',
}
export const getExportUrl = Api.exportXls;
export const list = (params) => defHttp.get({ url: Api.list, params });
export const batchUpdatePriority = (ids: string[], priorityPickup: '0' | '1') =>
defHttp.put(
{
url: Api.batchUpdatePriority,
params: { ids: ids.join(','), priorityPickup },
},
{ joinParamsToUrl: true },
);

View File

@@ -0,0 +1,72 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
import { render } from '/@/utils/common/renderUtils';
export const columns: BasicColumn[] = [
{ title: '条码', align: 'center', dataIndex: 'barcode', width: 180 },
{ title: '批次号', align: 'center', dataIndex: 'batchNo', width: 160 },
{
title: '入场日期',
align: 'center',
dataIndex: 'entryDate',
width: 120,
customRender: ({ text }) => (!text ? '' : text.length > 10 ? text.substring(0, 10) : text),
},
{ title: '物料名称', align: 'center', dataIndex: 'materialName', width: 160, ellipsis: true },
{ title: '供应商', align: 'center', dataIndex: 'supplierName', width: 160, ellipsis: true },
{ title: '保质期', align: 'center', dataIndex: 'shelfLife', width: 120 },
{ title: '总重', align: 'center', dataIndex: 'totalWeight', width: 110 },
{ title: '剩余重量', align: 'center', dataIndex: 'remainingWeight', width: 110 },
{ title: '剩余数量', align: 'center', dataIndex: 'remainingQuantity', width: 110 },
{ title: '检测结果', align: 'center', dataIndex: 'testResult_dictText', width: 110 },
{ title: '状态', align: 'center', dataIndex: 'status_dictText', width: 100 },
{
title: '优先使用',
align: 'center',
dataIndex: 'priorityPickup',
width: 100,
customRender: ({ text }) => render.renderSwitch(text, [{ text: '是', value: '1' }, { text: '否', value: '0' }]),
},
];
export const searchFormSchema: FormSchema[] = [
{ label: '条码', field: 'barcode', component: 'JInput', colProps: { span: 6 } },
{ label: '批次号', field: 'batchNo', component: 'JInput', colProps: { span: 6 } },
{ label: '物料名称', field: 'materialName', component: 'JInput', colProps: { span: 6 } },
{ label: '供应商', field: 'supplierName', component: 'JInput', colProps: { span: 6 } },
{
label: '入场日期',
field: 'entryDate',
component: 'RangePicker',
componentProps: { showTime: false, valueFormat: 'YYYY-MM-DD' },
colProps: { span: 8 },
},
{
label: '检测结果',
field: 'testResult',
component: 'JDictSelectTag',
componentProps: { dictCode: 'xslmes_test_result' },
colProps: { span: 6 },
},
{
label: '状态',
field: 'status',
component: 'JDictSelectTag',
componentProps: { dictCode: 'xslmes_card_status' },
colProps: { span: 6 },
},
];
export const superQuerySchema = {
barcode: { title: '条码', order: 0, view: 'text' },
batchNo: { title: '批次号', order: 1, view: 'text' },
entryDate: { title: '入场日期', order: 2, view: 'date' },
materialName: { title: '物料名称', order: 3, view: 'text' },
supplierName: { title: '供应商', order: 4, view: 'text' },
shelfLife: { title: '保质期', order: 5, view: 'text' },
totalWeight: { title: '总重', order: 6, view: 'number' },
remainingWeight: { title: '剩余重量', order: 7, view: 'number' },
remainingQuantity: { title: '剩余数量', order: 8, view: 'number' },
testResult: { title: '检测结果', order: 9, view: 'list', dictCode: 'xslmes_test_result' },
status: { title: '状态', order: 10, view: 'list', dictCode: 'xslmes_card_status' },
priorityPickup: { title: '优先使用', order: 11, view: 'list', dictCode: 'yn' },
};

View File

@@ -0,0 +1,84 @@
<template>
<div>
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<template #tableTitle>
<a-button
type="primary"
ghost
v-auth="'xslmes:mes_xsl_raw_material_workshop_remain:edit'"
:disabled="selectedRowKeys.length === 0"
@click="() => handleBatchPriorityUpdate('1')"
>
设为优先使用
</a-button>
<a-button
danger
ghost
v-auth="'xslmes:mes_xsl_raw_material_workshop_remain:edit'"
:disabled="selectedRowKeys.length === 0"
@click="() => handleBatchPriorityUpdate('0')"
>
取消优先使用
</a-button>
<a-button type="primary" v-auth="'xslmes:mes_xsl_raw_material_workshop_remain:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls">
导出
</a-button>
<super-query :config="superQueryConfig" @search="handleSuperQuery" />
</template>
</BasicTable>
</div>
</template>
<script lang="ts" name="xslmes-mesXslRawMaterialWorkshopRemain" setup>
import { reactive } from 'vue';
import { BasicTable } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { useMessage } from '/@/hooks/web/useMessage';
import { columns, searchFormSchema, superQuerySchema } from './MesXslRawMaterialWorkshopRemain.data';
import { batchUpdatePriority, list, getExportUrl } from './MesXslRawMaterialWorkshopRemain.api';
const { createMessage } = useMessage();
const queryParam = reactive<any>({});
const { tableContext, onExportXls } = useListPage({
tableProps: {
title: '原材料车间剩余量',
api: list,
columns,
canResize: true,
formConfig: {
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: true,
fieldMapToTime: [['entryDate', ['entryDate_begin', 'entryDate_end'], 'YYYY-MM-DD']],
},
beforeFetch: (params) => Object.assign(params, queryParam),
},
exportConfig: {
name: '原材料车间剩余量',
url: getExportUrl,
params: queryParam,
},
});
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
const superQueryConfig = reactive(superQuerySchema);
function handleSuperQuery(params) {
Object.keys(params).forEach((k) => {
queryParam[k] = params[k];
});
reload();
}
async function handleBatchPriorityUpdate(priorityPickup: '0' | '1') {
if (!selectedRowKeys.value.length) {
createMessage.warning('请先勾选记录');
return;
}
await batchUpdatePriority(selectedRowKeys.value as string[], priorityPickup);
createMessage.success(priorityPickup === '1' ? '已设为优先使用' : '已取消优先使用');
selectedRowKeys.value = [];
reload();
}
</script>