feat: 新增基础数据维护-判定规程维护界面和后端接口
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.qa.qm.controller; |
| | | |
| | | import java.util.List; |
| | | |
| | | import lombok.RequiredArgsConstructor; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import jakarta.validation.constraints.*; |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import org.dromara.qa.qm.domain.bo.QmStdBo; |
| | | import org.dromara.qa.qm.domain.vo.QmStdVo; |
| | | import org.dromara.qa.qm.service.IQmStdService; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.dromara.common.idempotent.annotation.RepeatSubmit; |
| | | import org.dromara.common.log.annotation.Log; |
| | | import org.dromara.common.web.core.BaseController; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.core.domain.R; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | import org.dromara.common.core.validate.EditGroup; |
| | | import org.dromara.common.log.enums.BusinessType; |
| | | import org.dromara.common.excel.utils.ExcelUtil; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | |
| | | /** |
| | | * å¤å®è§ç¨ |
| | | * |
| | | * @author zhuguifei |
| | | * @date 2026-03-11 |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/qm/std") |
| | | public class QmStdController extends BaseController { |
| | | |
| | | private final IQmStdService qmStdService; |
| | | |
| | | /** |
| | | * æ¥è¯¢å¤å®è§ç¨å表 |
| | | */ |
| | | @SaCheckPermission("qm:std:list") |
| | | @GetMapping("/list") |
| | | public TableDataInfo<QmStdVo> list(QmStdBo bo, PageQuery pageQuery) { |
| | | return qmStdService.queryPageList(bo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * 导åºå¤å®è§ç¨å表 |
| | | */ |
| | | @SaCheckPermission("qm:std:export") |
| | | @Log(title = "å¤å®è§ç¨", businessType = BusinessType.EXPORT) |
| | | @PostMapping("/export") |
| | | public void export(QmStdBo bo, HttpServletResponse response) { |
| | | List<QmStdVo> list = qmStdService.queryList(bo); |
| | | ExcelUtil.exportExcel(list, "å¤å®è§ç¨", QmStdVo.class, response); |
| | | } |
| | | |
| | | /** |
| | | * è·åå¤å®è§ç¨è¯¦ç»ä¿¡æ¯ |
| | | * |
| | | * @param id ä¸»é® |
| | | */ |
| | | @SaCheckPermission("qm:std:query") |
| | | @GetMapping("/{id}") |
| | | public R<QmStdVo> getInfo(@NotNull(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable String id) { |
| | | return R.ok(qmStdService.queryById(id)); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢å¤å®è§ç¨ |
| | | */ |
| | | @SaCheckPermission("qm:std:add") |
| | | @Log(title = "å¤å®è§ç¨", businessType = BusinessType.INSERT) |
| | | @RepeatSubmit() |
| | | @PostMapping() |
| | | public R<Void> add(@Validated(AddGroup.class) @RequestBody QmStdBo bo) { |
| | | return toAjax(qmStdService.insertByBo(bo)); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹å¤å®è§ç¨ |
| | | */ |
| | | @SaCheckPermission("qm:std:edit") |
| | | @Log(title = "å¤å®è§ç¨", businessType = BusinessType.UPDATE) |
| | | @RepeatSubmit() |
| | | @PutMapping() |
| | | public R<Void> edit(@Validated(EditGroup.class) @RequestBody QmStdBo bo) { |
| | | return toAjax(qmStdService.updateByBo(bo)); |
| | | } |
| | | |
| | | /** |
| | | * å é¤å¤å®è§ç¨ |
| | | * |
| | | * @param ids 主é®ä¸² |
| | | */ |
| | | @SaCheckPermission("qm:std:remove") |
| | | @Log(title = "å¤å®è§ç¨", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{ids}") |
| | | public R<Void> remove(@NotEmpty(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable String[] ids) { |
| | | return toAjax(qmStdService.deleteWithValidByIds(List.of(ids), true)); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.qa.qm.domain; |
| | | |
| | | import org.dromara.common.mybatis.core.domain.BaseEntity; |
| | | import com.baomidou.mybatisplus.annotation.*; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import java.util.Date; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | |
| | | import java.io.Serial; |
| | | |
| | | /** |
| | | * å¤å®è§ç¨å¯¹è±¡ qm_std |
| | | * |
| | | * @author zhuguifei |
| | | * @date 2026-03-11 |
| | | */ |
| | | @Data |
| | | @TableName("qm_std") |
| | | public class QmStd { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ç¼ç |
| | | */ |
| | | @TableId(value = "id") |
| | | private String id; |
| | | |
| | | /** |
| | | * è§ç¨ä»£ç |
| | | */ |
| | | private String stdCode; |
| | | |
| | | /** |
| | | * è§ç¨åç§° |
| | | */ |
| | | private String stdName; |
| | | |
| | | /** |
| | | * å建æ¶é´ |
| | | */ |
| | | private Date cdate; |
| | | |
| | | /** |
| | | * çæ¬å· |
| | | */ |
| | | private Long ver; |
| | | |
| | | /** |
| | | * å¯ç¨æ è¯ |
| | | */ |
| | | private Long enable; |
| | | |
| | | /** |
| | | * æ£éªé¡¹ç®code |
| | | */ |
| | | private String itemCod; |
| | | |
| | | /** |
| | | * æ£éªé¡¹ç®åç§° |
| | | */ |
| | | private String itemNam; |
| | | |
| | | /** |
| | | * å¤å®ç±»å 0-æå¨å¤å®,1-ä¸ä¸éå¤å®,2-å¹³åå¼å¤å®,3-SDå¼å¤å®,4-CVå¼å¤å®,5-è¶
æ æ°å¤å® |
| | | */ |
| | | private Long typ; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String stdDes; |
| | | |
| | | /** |
| | | * æ£éªçº§å« |
| | | */ |
| | | private Long checkLevel; |
| | | |
| | | /** |
| | | * ç±»å ï¼ 0-æå 1-è¾
æ |
| | | */ |
| | | private Long category; |
| | | |
| | | /** |
| | | * $column.columnComment |
| | | */ |
| | | private String matfltype; |
| | | |
| | | /** |
| | | * $column.columnComment |
| | | */ |
| | | private String matflname; |
| | | |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.qa.qm.domain.bo; |
| | | |
| | | import org.dromara.qa.qm.domain.QmStd; |
| | | import org.dromara.common.mybatis.core.domain.BaseEntity; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | import org.dromara.common.core.validate.EditGroup; |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import jakarta.validation.constraints.*; |
| | | import java.util.Date; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | |
| | | /** |
| | | * å¤å®è§ç¨ä¸å¡å¯¹è±¡ qm_std |
| | | * |
| | | * @author zhuguifei |
| | | * @date 2026-03-11 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @AutoMapper(target = QmStd.class, reverseConvertGenerate = false) |
| | | public class QmStdBo extends BaseEntity { |
| | | |
| | | /** |
| | | * ç¼ç |
| | | */ |
| | | @NotBlank(message = "ç¼ç ä¸è½ä¸ºç©º", groups = { EditGroup.class }) |
| | | private String id; |
| | | |
| | | /** |
| | | * è§ç¨ä»£ç |
| | | */ |
| | | private String stdCode; |
| | | |
| | | /** |
| | | * è§ç¨åç§° |
| | | */ |
| | | private String stdName; |
| | | |
| | | /** |
| | | * å建æ¶é´ |
| | | */ |
| | | private Date cdate; |
| | | |
| | | /** |
| | | * çæ¬å· |
| | | */ |
| | | private Long ver; |
| | | |
| | | /** |
| | | * å¯ç¨æ è¯ |
| | | */ |
| | | private Long enable; |
| | | |
| | | /** |
| | | * æ£éªé¡¹ç®code |
| | | */ |
| | | private String itemCod; |
| | | |
| | | /** |
| | | * æ£éªé¡¹ç®åç§° |
| | | */ |
| | | private String itemNam; |
| | | |
| | | /** |
| | | * å¤å®ç±»å 0-æå¨å¤å®,1-ä¸ä¸éå¤å®,2-å¹³åå¼å¤å®,3-SDå¼å¤å®,4-CVå¼å¤å®,5-è¶
æ æ°å¤å® |
| | | */ |
| | | private Long typ; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String stdDes; |
| | | |
| | | /** |
| | | * æ£éªçº§å« |
| | | */ |
| | | private Long checkLevel; |
| | | |
| | | /** |
| | | * ç±»å ï¼ 0-æå 1-è¾
æ |
| | | */ |
| | | private Long category; |
| | | |
| | | /** |
| | | * $column.columnComment |
| | | */ |
| | | private String matfltype; |
| | | |
| | | /** |
| | | * $column.columnComment |
| | | */ |
| | | private String matflname; |
| | | |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.qa.qm.domain.vo; |
| | | |
| | | import java.util.Date; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import org.dromara.qa.qm.domain.QmStd; |
| | | import cn.idev.excel.annotation.ExcelIgnoreUnannotated; |
| | | import cn.idev.excel.annotation.ExcelProperty; |
| | | import org.dromara.common.excel.annotation.ExcelDictFormat; |
| | | import org.dromara.common.excel.convert.ExcelDictConvert; |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | |
| | | |
| | | /** |
| | | * å¤å®è§ç¨è§å¾å¯¹è±¡ qm_std |
| | | * |
| | | * @author zhuguifei |
| | | * @date 2026-03-11 |
| | | */ |
| | | @Data |
| | | @ExcelIgnoreUnannotated |
| | | @AutoMapper(target = QmStd.class) |
| | | public class QmStdVo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ç¼ç |
| | | */ |
| | | @ExcelProperty(value = "ç¼ç ") |
| | | private String id; |
| | | |
| | | /** |
| | | * è§ç¨ä»£ç |
| | | */ |
| | | @ExcelProperty(value = "è§ç¨ä»£ç ") |
| | | private String stdCode; |
| | | |
| | | /** |
| | | * è§ç¨åç§° |
| | | */ |
| | | @ExcelProperty(value = "è§ç¨åç§°") |
| | | private String stdName; |
| | | |
| | | /** |
| | | * å建æ¶é´ |
| | | */ |
| | | @ExcelProperty(value = "å建æ¶é´") |
| | | private Date cdate; |
| | | |
| | | /** |
| | | * çæ¬å· |
| | | */ |
| | | @ExcelProperty(value = "çæ¬å·") |
| | | private Long ver; |
| | | |
| | | /** |
| | | * å¯ç¨æ è¯ |
| | | */ |
| | | @ExcelProperty(value = "å¯ç¨æ è¯") |
| | | private Long enable; |
| | | |
| | | /** |
| | | * æ£éªé¡¹ç®code |
| | | */ |
| | | @ExcelProperty(value = "æ£éªé¡¹ç®code") |
| | | private String itemCod; |
| | | |
| | | /** |
| | | * æ£éªé¡¹ç®åç§° |
| | | */ |
| | | @ExcelProperty(value = "æ£éªé¡¹ç®åç§°") |
| | | private String itemNam; |
| | | |
| | | /** |
| | | * å¤å®ç±»å 0-æå¨å¤å®,1-ä¸ä¸éå¤å®,2-å¹³åå¼å¤å®,3-SDå¼å¤å®,4-CVå¼å¤å®,5-è¶
æ æ°å¤å® |
| | | */ |
| | | @ExcelProperty(value = "å¤å®ç±»å 0-æå¨å¤å®,1-ä¸ä¸éå¤å®,2-å¹³åå¼å¤å®,3-SDå¼å¤å®,4-CVå¼å¤å®,5-è¶
æ æ°å¤å®") |
| | | private Long typ; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | @ExcelProperty(value = "夿³¨") |
| | | private String stdDes; |
| | | |
| | | /** |
| | | * æ£éªçº§å« |
| | | */ |
| | | @ExcelProperty(value = "æ£éªçº§å«") |
| | | private Long checkLevel; |
| | | |
| | | /** |
| | | * ç±»å ï¼ 0-æå 1-è¾
æ |
| | | */ |
| | | @ExcelProperty(value = "ç±»å ï¼ 0-æå 1-è¾
æ") |
| | | private Long category; |
| | | |
| | | /** |
| | | * $column.columnComment |
| | | */ |
| | | @ExcelProperty(value = "${comment}", converter = ExcelDictConvert.class) |
| | | @ExcelDictFormat(readConverterExp = "$column.readConverterExp()") |
| | | private String matfltype; |
| | | |
| | | /** |
| | | * $column.columnComment |
| | | */ |
| | | @ExcelProperty(value = "${comment}", converter = ExcelDictConvert.class) |
| | | @ExcelDictFormat(readConverterExp = "$column.readConverterExp()") |
| | | private String matflname; |
| | | |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.qa.qm.mapper; |
| | | |
| | | import org.dromara.qa.qm.domain.QmStd; |
| | | import org.dromara.qa.qm.domain.vo.QmStdVo; |
| | | import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; |
| | | |
| | | /** |
| | | * å¤å®è§ç¨Mapperæ¥å£ |
| | | * |
| | | * @author zhuguifei |
| | | * @date 2026-03-11 |
| | | */ |
| | | public interface QmStdMapper extends BaseMapperPlus<QmStd, QmStdVo> { |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.qa.qm.service; |
| | | |
| | | import org.dromara.qa.qm.domain.vo.QmStdVo; |
| | | import org.dromara.qa.qm.domain.bo.QmStdBo; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å¤å®è§ç¨Serviceæ¥å£ |
| | | * |
| | | * @author zhuguifei |
| | | * @date 2026-03-11 |
| | | */ |
| | | public interface IQmStdService { |
| | | |
| | | /** |
| | | * æ¥è¯¢å¤å®è§ç¨ |
| | | * |
| | | * @param id ä¸»é® |
| | | * @return å¤å®è§ç¨ |
| | | */ |
| | | QmStdVo queryById(String id); |
| | | |
| | | /** |
| | | * å页æ¥è¯¢å¤å®è§ç¨å表 |
| | | * |
| | | * @param bo æ¥è¯¢æ¡ä»¶ |
| | | * @param pageQuery å页忰 |
| | | * @return å¤å®è§ç¨å页å表 |
| | | */ |
| | | TableDataInfo<QmStdVo> queryPageList(QmStdBo bo, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¬¦åæ¡ä»¶çå¤å®è§ç¨å表 |
| | | * |
| | | * @param bo æ¥è¯¢æ¡ä»¶ |
| | | * @return å¤å®è§ç¨å表 |
| | | */ |
| | | List<QmStdVo> queryList(QmStdBo bo); |
| | | |
| | | /** |
| | | * æ°å¢å¤å®è§ç¨ |
| | | * |
| | | * @param bo å¤å®è§ç¨ |
| | | * @return æ¯å¦æ°å¢æå |
| | | */ |
| | | Boolean insertByBo(QmStdBo bo); |
| | | |
| | | /** |
| | | * ä¿®æ¹å¤å®è§ç¨ |
| | | * |
| | | * @param bo å¤å®è§ç¨ |
| | | * @return æ¯å¦ä¿®æ¹æå |
| | | */ |
| | | Boolean updateByBo(QmStdBo bo); |
| | | |
| | | /** |
| | | * æ ¡éªå¹¶æ¹éå é¤å¤å®è§ç¨ä¿¡æ¯ |
| | | * |
| | | * @param ids å¾
å é¤ç主é®éå |
| | | * @param isValid æ¯å¦è¿è¡æææ§æ ¡éª |
| | | * @return æ¯å¦å 餿å |
| | | */ |
| | | Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.qa.qm.service.impl; |
| | | |
| | | import org.dromara.common.core.utils.MapstructUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | | import org.dromara.qa.qm.domain.bo.QmStdBo; |
| | | import org.dromara.qa.qm.domain.vo.QmStdVo; |
| | | import org.dromara.qa.qm.domain.QmStd; |
| | | import org.dromara.qa.qm.mapper.QmStdMapper; |
| | | import org.dromara.qa.qm.service.IQmStdService; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Collection; |
| | | |
| | | /** |
| | | * å¤å®è§ç¨Serviceä¸å¡å±å¤ç |
| | | * |
| | | * @author zhuguifei |
| | | * @date 2026-03-11 |
| | | */ |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class QmStdServiceImpl implements IQmStdService { |
| | | |
| | | private final QmStdMapper baseMapper; |
| | | |
| | | /** |
| | | * æ¥è¯¢å¤å®è§ç¨ |
| | | * |
| | | * @param id ä¸»é® |
| | | * @return å¤å®è§ç¨ |
| | | */ |
| | | @Override |
| | | public QmStdVo queryById(String id){ |
| | | return baseMapper.selectVoById(id); |
| | | } |
| | | |
| | | /** |
| | | * å页æ¥è¯¢å¤å®è§ç¨å表 |
| | | * |
| | | * @param bo æ¥è¯¢æ¡ä»¶ |
| | | * @param pageQuery å页忰 |
| | | * @return å¤å®è§ç¨å页å表 |
| | | */ |
| | | @Override |
| | | public TableDataInfo<QmStdVo> queryPageList(QmStdBo bo, PageQuery pageQuery) { |
| | | LambdaQueryWrapper<QmStd> lqw = buildQueryWrapper(bo); |
| | | Page<QmStdVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); |
| | | return TableDataInfo.build(result); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¬¦åæ¡ä»¶çå¤å®è§ç¨å表 |
| | | * |
| | | * @param bo æ¥è¯¢æ¡ä»¶ |
| | | * @return å¤å®è§ç¨å表 |
| | | */ |
| | | @Override |
| | | public List<QmStdVo> queryList(QmStdBo bo) { |
| | | LambdaQueryWrapper<QmStd> lqw = buildQueryWrapper(bo); |
| | | return baseMapper.selectVoList(lqw); |
| | | } |
| | | |
| | | private LambdaQueryWrapper<QmStd> buildQueryWrapper(QmStdBo bo) { |
| | | Map<String, Object> params = bo.getParams(); |
| | | LambdaQueryWrapper<QmStd> lqw = Wrappers.lambdaQuery(); |
| | | lqw.orderByAsc(QmStd::getId); |
| | | lqw.like(StringUtils.isNotBlank(bo.getStdCode()), QmStd::getStdCode, bo.getStdCode()); |
| | | lqw.like(StringUtils.isNotBlank(bo.getStdName()), QmStd::getStdName, bo.getStdName()); |
| | | lqw.eq(bo.getTyp() != null, QmStd::getTyp, bo.getTyp()); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getStdDes()), QmStd::getStdDes, bo.getStdDes()); |
| | | lqw.eq(bo.getCheckLevel() != null, QmStd::getCheckLevel, bo.getCheckLevel()); |
| | | lqw.eq(bo.getCategory() != null, QmStd::getCategory, bo.getCategory()); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getMatfltype()), QmStd::getMatfltype, bo.getMatfltype()); |
| | | lqw.like(StringUtils.isNotBlank(bo.getMatflname()), QmStd::getMatflname, bo.getMatflname()); |
| | | return lqw; |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢å¤å®è§ç¨ |
| | | * |
| | | * @param bo å¤å®è§ç¨ |
| | | * @return æ¯å¦æ°å¢æå |
| | | */ |
| | | @Override |
| | | public Boolean insertByBo(QmStdBo bo) { |
| | | QmStd add = MapstructUtils.convert(bo, QmStd.class); |
| | | validEntityBeforeSave(add); |
| | | boolean flag = baseMapper.insert(add) > 0; |
| | | if (flag) { |
| | | bo.setId(add.getId()); |
| | | } |
| | | return flag; |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹å¤å®è§ç¨ |
| | | * |
| | | * @param bo å¤å®è§ç¨ |
| | | * @return æ¯å¦ä¿®æ¹æå |
| | | */ |
| | | @Override |
| | | public Boolean updateByBo(QmStdBo bo) { |
| | | QmStd update = MapstructUtils.convert(bo, QmStd.class); |
| | | validEntityBeforeSave(update); |
| | | return baseMapper.updateById(update) > 0; |
| | | } |
| | | |
| | | /** |
| | | * ä¿ååçæ°æ®æ ¡éª |
| | | */ |
| | | private void validEntityBeforeSave(QmStd entity){ |
| | | //TODO åä¸äºæ°æ®æ ¡éª,å¦å¯ä¸çº¦æ |
| | | } |
| | | |
| | | /** |
| | | * æ ¡éªå¹¶æ¹éå é¤å¤å®è§ç¨ä¿¡æ¯ |
| | | * |
| | | * @param ids å¾
å é¤ç主é®éå |
| | | * @param isValid æ¯å¦è¿è¡æææ§æ ¡éª |
| | | * @return æ¯å¦å 餿å |
| | | */ |
| | | @Override |
| | | public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) { |
| | | if(isValid){ |
| | | //TODO åä¸äºä¸å¡ä¸çæ ¡éª,夿æ¯å¦éè¦æ ¡éª |
| | | } |
| | | return baseMapper.deleteByIds(ids) > 0; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8" ?> |
| | | <!DOCTYPE mapper |
| | | PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
| | | "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="org.dromara.qa.qm.mapper.QmStdMapper"> |
| | | </mapper> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import { request } from '@/service/request'; |
| | | |
| | | /** è·åå¤å®è§ç¨å表 */ |
| | | export function fetchGetStdList (params?: Api.Qm.StdSearchParams) { |
| | | return request<Api.Qm.StdList>({ |
| | | url: '/qm/std/list', |
| | | method: 'get', |
| | | params |
| | | }); |
| | | } |
| | | /** æ°å¢å¤å®è§ç¨ */ |
| | | export function fetchCreateStd (data: Api.Qm.StdOperateParams) { |
| | | return request<boolean>({ |
| | | url: '/qm/std', |
| | | method: 'post', |
| | | data |
| | | }); |
| | | } |
| | | |
| | | /** ä¿®æ¹å¤å®è§ç¨ */ |
| | | export function fetchUpdateStd (data: Api.Qm.StdOperateParams) { |
| | | return request<boolean>({ |
| | | url: '/qm/std', |
| | | method: 'put', |
| | | data |
| | | }); |
| | | } |
| | | |
| | | /** æ¹éå é¤å¤å®è§ç¨ */ |
| | | export function fetchBatchDeleteStd (ids: CommonType.IdType[]) { |
| | | return request<boolean>({ |
| | | url: `/qm/std/${ids.join(',')}`, |
| | | method: 'delete' |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * Namespace Api |
| | | * |
| | | * All backend api type |
| | | */ |
| | | declare namespace Api { |
| | | /** |
| | | * namespace Qm |
| | | * |
| | | * backend api module: "Qm" |
| | | */ |
| | | namespace Qm { |
| | | /** std */ |
| | | type Std = Common.CommonRecord<{ |
| | | /** ç¼ç */ |
| | | id: CommonType.IdType; |
| | | /** è§ç¨ä»£ç */ |
| | | stdCode: string; |
| | | /** è§ç¨åç§° */ |
| | | stdName: string; |
| | | /** å建æ¶é´ */ |
| | | cdate: string; |
| | | /** çæ¬å· */ |
| | | ver: number; |
| | | /** å¯ç¨æ è¯ */ |
| | | enable: number; |
| | | /** æ£éªé¡¹ç®code */ |
| | | itemCod: string; |
| | | /** æ£éªé¡¹ç®åç§° */ |
| | | itemNam: string; |
| | | /** å¤å®ç±»å 0-æå¨å¤å®,1-ä¸ä¸éå¤å®,2-å¹³åå¼å¤å®,3-SDå¼å¤å®,4-CVå¼å¤å®,5-è¶
æ æ°å¤å® */ |
| | | typ: number; |
| | | /** 夿³¨ */ |
| | | stdDes: string; |
| | | /** æ£éªçº§å« */ |
| | | checkLevel: number; |
| | | /** ç±»å ï¼ 0-æå 1-è¾
æ */ |
| | | category: number; |
| | | /** $column.columnComment */ |
| | | matfltype: string; |
| | | /** $column.columnComment */ |
| | | matflname: string; |
| | | }>; |
| | | |
| | | /** std search params */ |
| | | type StdSearchParams = CommonType.RecordNullable< |
| | | Pick< |
| | | Api.Qm.Std, |
| | | | 'stdCode' |
| | | | 'stdName' |
| | | | 'typ' |
| | | | 'stdDes' |
| | | | 'checkLevel' |
| | | | 'category' |
| | | | 'matfltype' |
| | | | 'matflname' |
| | | > & |
| | | Api.Common.CommonSearchParams |
| | | >; |
| | | |
| | | /** std operate params */ |
| | | type StdOperateParams = CommonType.RecordNullable< |
| | | Pick< |
| | | Api.Qm.Std, |
| | | | 'id' |
| | | | 'stdCode' |
| | | | 'stdName' |
| | | | 'cdate' |
| | | | 'ver' |
| | | | 'enable' |
| | | | 'itemCod' |
| | | | 'itemNam' |
| | | | 'typ' |
| | | | 'stdDes' |
| | | | 'checkLevel' |
| | | | 'category' |
| | | | 'matfltype' |
| | | | 'matflname' |
| | | > |
| | | >; |
| | | |
| | | /** std list */ |
| | | type StdList = Api.Common.PaginatingQueryRecord<Std>; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script setup lang="ts"> |
| | | import { computed, ref, watch } from 'vue'; |
| | | import { useEcharts } from '@/hooks/common/echarts'; |
| | | |
| | | defineOptions({ |
| | | name: 'StoreSilkSankey' |
| | | }); |
| | | |
| | | interface StoreSilkDetailVo { |
| | | fsNum?: string; |
| | | siloNum?: string; |
| | | equNo?: string; |
| | | output?: number | null; |
| | | } |
| | | |
| | | interface Props { |
| | | rollerRecordList?: StoreSilkDetailVo[]; |
| | | packerRecordList?: StoreSilkDetailVo[]; |
| | | rows?: any[]; |
| | | } |
| | | |
| | | const props = withDefaults(defineProps<Props>(), { |
| | | rollerRecordList: () => [], |
| | | packerRecordList: () => [], |
| | | rows: () => [] |
| | | }); |
| | | |
| | | type SankeyType = 'roller' | 'packer'; |
| | | |
| | | const sankeyType = ref<SankeyType>('roller'); |
| | | |
| | | function normalizeNumber(val: unknown) { |
| | | const v = Number(val); |
| | | if (!Number.isFinite(v)) return null; |
| | | return v; |
| | | } |
| | | |
| | | function calcRollerBox(val: unknown) { |
| | | if (val === null || val === undefined) return null; |
| | | const v = Number(val) / 50; |
| | | if (!Number.isFinite(v)) return null; |
| | | return v; |
| | | } |
| | | |
| | | function calcPackerBox(val: unknown) { |
| | | if (val === null || val === undefined) return null; |
| | | const v = Number(val) / 10 / 250; |
| | | if (!Number.isFinite(v)) return null; |
| | | return v; |
| | | } |
| | | |
| | | function formatTime(val: unknown) { |
| | | if (!val) return ''; |
| | | const s = String(val); |
| | | return s.length > 19 ? s.slice(0, 19) : s; |
| | | } |
| | | |
| | | function buildChartData(list: StoreSilkDetailVo[], type: SankeyType) { |
| | | const nodeSet = new Set<string>(); |
| | | const linkMap = new Map<string, { source: string; target: string; value: number }>(); |
| | | const nodeInValue = new Map<string, number>(); |
| | | const nodeOutValue = new Map<string, number>(); |
| | | const nodeExtra = new Map<string, any>(); |
| | | const rows = Array.isArray(props.rows) ? props.rows : []; |
| | | |
| | | function addLink(source: string, target: string, value: number) { |
| | | if (value <= 0) return; |
| | | nodeSet.add(source); |
| | | nodeSet.add(target); |
| | | nodeInValue.set(target, (nodeInValue.get(target) ?? 0) + value); |
| | | nodeOutValue.set(source, (nodeOutValue.get(source) ?? 0) + value); |
| | | const key = `${source}__->__${target}`; |
| | | const existed = linkMap.get(key); |
| | | if (existed) { |
| | | existed.value += value; |
| | | return; |
| | | } |
| | | linkMap.set(key, { source, target, value }); |
| | | } |
| | | |
| | | for (const item of list) { |
| | | const val = normalizeNumber(item.output); |
| | | if (val === null) continue; |
| | | if (val <= 0) continue; |
| | | |
| | | const fsBase = `å䏿º ${item.fsNum || '-'}`; |
| | | const siloBase = `å¨ä¸æ ${item.siloNum || '-'}`; |
| | | const equ = item.equNo ? `${item.equNo}#${type === 'roller' ? 'å·æ¥æº' : 'å
è£
æº'}` : type === 'roller' ? 'å·æ¥æº' : 'å
è£
æº'; |
| | | const target = equ; |
| | | const fs = fsBase; |
| | | const silo = siloBase; |
| | | |
| | | addLink(fs, silo, val); |
| | | addLink(silo, target, val); |
| | | |
| | | const parentRow = rows.find((r: any) => { |
| | | const dList = type === 'roller' ? r?.rollerDetailList : r?.packerDetailList; |
| | | if (!Array.isArray(dList)) return false; |
| | | return dList.some((d: any) => d?.fsNum === item.fsNum && d?.siloNum === item.siloNum && d?.equNo === item.equNo); |
| | | }); |
| | | |
| | | if (parentRow) { |
| | | const materialname = String(parentRow.materialname ?? ''); |
| | | const batchcode = String(parentRow.batchcode ?? parentRow.batchCode ?? ''); |
| | | const jobinput = Number(parentRow.jobinput); |
| | | const distimebegin = formatTime(parentRow.distimebegin); |
| | | const distimeend = formatTime(parentRow.distimeend); |
| | | |
| | | nodeExtra.set(fs, { |
| | | kind: 'fs', |
| | | displayName: fsBase, |
| | | meta: { materialname, batchcode, jobinput } |
| | | }); |
| | | nodeExtra.set(silo, { |
| | | kind: 'silo', |
| | | displayName: siloBase, |
| | | meta: { distimebegin, distimeend } |
| | | }); |
| | | } |
| | | } |
| | | |
| | | const nodes = Array.from(nodeSet).map(name => { |
| | | const inV = nodeInValue.get(name) ?? 0; |
| | | const outV = nodeOutValue.get(name) ?? 0; |
| | | const value = inV > 0 ? inV : outV; |
| | | return { name, value, ...(nodeExtra.get(name) ?? {}) }; |
| | | }); |
| | | const links = Array.from(linkMap.values()); |
| | | |
| | | return { nodes, links }; |
| | | } |
| | | |
| | | const activeList = computed(() => { |
| | | return sankeyType.value === 'roller' ? props.rollerRecordList : props.packerRecordList; |
| | | }); |
| | | |
| | | watch( |
| | | () => [props.rollerRecordList, props.packerRecordList], |
| | | () => { |
| | | const rollerLen = Array.isArray(props.rollerRecordList) ? props.rollerRecordList.length : 0; |
| | | const packerLen = Array.isArray(props.packerRecordList) ? props.packerRecordList.length : 0; |
| | | |
| | | if (sankeyType.value === 'roller' && rollerLen === 0 && packerLen > 0) { |
| | | sankeyType.value = 'packer'; |
| | | return; |
| | | } |
| | | |
| | | if (sankeyType.value === 'packer' && packerLen === 0 && rollerLen > 0) { |
| | | sankeyType.value = 'roller'; |
| | | } |
| | | }, |
| | | { deep: true, immediate: true } |
| | | ); |
| | | |
| | | const hasData = computed(() => { |
| | | return Boolean(activeList.value && activeList.value.length > 0); |
| | | }); |
| | | |
| | | const { domRef, updateOptions } = useEcharts(() => { |
| | | const { nodes, links } = buildChartData(activeList.value, sankeyType.value); |
| | | |
| | | return { |
| | | tooltip: { |
| | | trigger: 'item' |
| | | }, |
| | | series: [ |
| | | { |
| | | type: 'sankey', |
| | | data: nodes, |
| | | links, |
| | | nodeAlign: 'justify', |
| | | layoutIterations: 32, |
| | | emphasis: { |
| | | focus: 'adjacency' |
| | | }, |
| | | lineStyle: { |
| | | color: 'source', |
| | | curveness: 0.5, |
| | | opacity: 0.35 |
| | | }, |
| | | label: { |
| | | position: 'right', |
| | | formatter: (params: any) => { |
| | | const name = String(params?.data?.name ?? ''); |
| | | const value = params?.data?.value; |
| | | const kind = params?.data?.kind; |
| | | const displayName = String(params?.data?.displayName ?? name); |
| | | const meta = params?.data?.meta; |
| | | |
| | | if (kind === 'fs') { |
| | | const materialLine = meta?.materialname ? `çå·ï¼${meta.materialname}` : ''; |
| | | const batchLine = meta?.batchcode ? `æ¹æ¬¡ï¼${meta.batchcode}` : ''; |
| | | const jobLine = |
| | | Number.isFinite(Number(meta?.jobinput)) ? `ææééï¼${Number(meta.jobinput).toFixed(2)}kg` : ''; |
| | | const lines: string[] = [displayName]; |
| | | lines.push(''); |
| | | if (materialLine) lines.push(materialLine); |
| | | if (batchLine) lines.push(batchLine); |
| | | if (jobLine) { |
| | | lines.push(''); |
| | | lines.push(jobLine); |
| | | } |
| | | return lines.join('\n'); |
| | | } |
| | | |
| | | if (kind === 'silo') { |
| | | const beginLine = meta?.distimebegin ? `å¼å§ï¼${meta.distimebegin}` : ''; |
| | | const endLine = meta?.distimeend ? `ç»æï¼${meta.distimeend}` : ''; |
| | | const valLine = |
| | | typeof value === 'number' && Number.isFinite(value) ? `产éï¼${value.toFixed(2)}ç®±` : ''; |
| | | const lines: string[] = [displayName]; |
| | | lines.push(''); |
| | | if (beginLine) lines.push(beginLine); |
| | | if (endLine) lines.push(endLine); |
| | | if (valLine) { |
| | | lines.push(''); |
| | | lines.push(valLine); |
| | | } |
| | | return lines.join('\n'); |
| | | } |
| | | const showValue = |
| | | name.startsWith('å¨ä¸æ ') || |
| | | name.endsWith('#å·æ¥æº') || |
| | | name.endsWith('#å
è£
æº') || |
| | | name === 'å·æ¥æº' || |
| | | name === 'å
è£
æº'; |
| | | |
| | | if (showValue && typeof value === 'number' && Number.isFinite(value)) { |
| | | return `${displayName}\n${value.toFixed(2)}ç®±`; |
| | | } |
| | | return displayName; |
| | | } |
| | | } |
| | | }, |
| | | ] |
| | | }; |
| | | }); |
| | | |
| | | watch( |
| | | () => [props.rollerRecordList, props.packerRecordList, sankeyType.value], |
| | | () => { |
| | | updateOptions(opts => { |
| | | const { nodes, links } = buildChartData(activeList.value, sankeyType.value); |
| | | opts.series[0].data = nodes as any; |
| | | (opts.series[0] as any).links = links; |
| | | return opts; |
| | | }); |
| | | }, |
| | | { deep: true, immediate: true } |
| | | ); |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="h-full flex-col-stretch"> |
| | | <div class="pb-8px"> |
| | | <NSpace :size="8"> |
| | | <NButton |
| | | size="small" |
| | | ghost |
| | | :type="sankeyType === 'roller' ? 'primary' : 'default'" |
| | | @click="sankeyType = 'roller'" |
| | | > |
| | | å·æ¥ |
| | | </NButton> |
| | | <NButton |
| | | size="small" |
| | | ghost |
| | | :type="sankeyType === 'packer' ? 'primary' : 'default'" |
| | | @click="sankeyType = 'packer'" |
| | | > |
| | | å
è£
|
| | | </NButton> |
| | | </NSpace> |
| | | </div> |
| | | <div v-if="!hasData" class="flex-center flex-1 text-gray-400"> |
| | | ææ {{ sankeyType === 'roller' ? 'å·æ¥' : 'å
è£
' }}æ¡åºå¾æ°æ® |
| | | </div> |
| | | <div v-else ref="domRef" class="flex-1 min-h-360px overflow-hidden"></div> |
| | | </div> |
| | | </template> |
| | | |
| | | <style scoped></style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script setup lang="tsx"> |
| | | import { ref } from 'vue'; |
| | | import { NDivider } from 'naive-ui'; |
| | | import dayjs from 'dayjs'; |
| | | import { fetchBatchDeleteStd, fetchGetStdList } from '@/service/api/qm/std'; |
| | | import { useAppStore } from '@/store/modules/app'; |
| | | import { useAuth } from '@/hooks/business/auth'; |
| | | import { useDownload } from '@/hooks/business/download'; |
| | | import { defaultTransform, useNaivePaginatedTable, useTableOperate } from '@/hooks/common/table'; |
| | | import { $t } from '@/locales'; |
| | | import ButtonIcon from '@/components/custom/button-icon.vue'; |
| | | import StdOperateDrawer from './modules/std-operate-drawer.vue'; |
| | | import StdSearch from './modules/std-search.vue'; |
| | | |
| | | defineOptions({ |
| | | name: 'StdList' |
| | | }); |
| | | |
| | | |
| | | const appStore = useAppStore(); |
| | | const { download } = useDownload(); |
| | | const { hasAuth } = useAuth(); |
| | | |
| | | const searchParams = ref<Api.Qm.StdSearchParams>({ |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | stdCode: null, |
| | | stdName: null, |
| | | typ: null, |
| | | stdDes: null, |
| | | checkLevel: null, |
| | | category: 0, |
| | | matfltype: null, |
| | | matflname: null, |
| | | params: {} |
| | | }); |
| | | |
| | | const { columns, columnChecks, data, getData, getDataByPage, loading, mobilePagination, scrollX } = |
| | | useNaivePaginatedTable({ |
| | | api: () => fetchGetStdList(searchParams.value), |
| | | transform: response => defaultTransform(response), |
| | | onPaginationParamsChange: params => { |
| | | searchParams.value.pageNum = params.page; |
| | | searchParams.value.pageSize = params.pageSize; |
| | | }, |
| | | columns: () => [ |
| | | { |
| | | type: 'selection', |
| | | align: 'center', |
| | | width: 48 |
| | | }, |
| | | { |
| | | key: 'index', |
| | | title: $t('common.index'), |
| | | align: 'center', |
| | | width: 64, |
| | | render: (_, index) => index + 1 |
| | | }, |
| | | |
| | | { |
| | | key: 'stdCode', |
| | | title: 'è§ç¨ä»£ç ', |
| | | align: 'center', |
| | | width: 200 |
| | | }, |
| | | { |
| | | key: 'stdName', |
| | | title: 'è§ç¨åç§°', |
| | | align: 'center', |
| | | width: 300 |
| | | }, |
| | | { |
| | | key: 'category', |
| | | title: 'ç©æç±»å', |
| | | align: 'center', |
| | | minWidth: 120, |
| | | render: row => { |
| | | const v = String(row?.category ?? ''); |
| | | return v === '0' ? 'æå' : v === '1' ? 'è¾
æ' : v; |
| | | } |
| | | }, |
| | | { |
| | | key: 'cdate', |
| | | title: 'å建æ¶é´', |
| | | align: 'center', |
| | | minWidth: 120, |
| | | render: row => (row.cdate ? dayjs(row.cdate).format('YYYY-MM-DD') : '') |
| | | }, |
| | | { |
| | | key: 'ver', |
| | | title: 'çæ¬å·', |
| | | align: 'center', |
| | | minWidth: 120 |
| | | }, |
| | | { |
| | | key: 'enable', |
| | | title: 'å¯ç¨æ è¯', |
| | | align: 'center', |
| | | minWidth: 120, |
| | | render: row => { |
| | | const v = String(row?.enable ?? ''); |
| | | return v === '0' ? 'åç¨' : v === '1' ? 'å¯ç¨' : v; |
| | | } |
| | | }, |
| | | { |
| | | key: 'operate', |
| | | title: $t('common.operate'), |
| | | align: 'center', |
| | | fixed: 'right', |
| | | width: 130, |
| | | render: row => { |
| | | const divider = () => { |
| | | if (!hasAuth('qm:std:edit') || !hasAuth('qm:std:remove')) { |
| | | return null; |
| | | } |
| | | return <NDivider vertical />; |
| | | }; |
| | | |
| | | const editBtn = () => { |
| | | if (!hasAuth('qm:std:edit')) { |
| | | return null; |
| | | } |
| | | return ( |
| | | <ButtonIcon |
| | | text |
| | | type="primary" |
| | | icon="material-symbols:drive-file-rename-outline-outline" |
| | | tooltipContent={$t('common.edit')} |
| | | onClick={() => edit(row.id)} |
| | | /> |
| | | ); |
| | | }; |
| | | |
| | | const deleteBtn = () => { |
| | | if (!hasAuth('qm:std:remove')) { |
| | | return null; |
| | | } |
| | | return ( |
| | | <ButtonIcon |
| | | text |
| | | type="error" |
| | | icon="material-symbols:delete-outline" |
| | | tooltipContent={$t('common.delete')} |
| | | popconfirmContent={$t('common.confirmDelete')} |
| | | onPositiveClick={() => handleDelete(row.id)} |
| | | /> |
| | | ); |
| | | }; |
| | | |
| | | return ( |
| | | <div class="flex-center gap-8px"> |
| | | {editBtn()} |
| | | {divider()} |
| | | {deleteBtn()} |
| | | </div> |
| | | ); |
| | | } |
| | | } |
| | | ] |
| | | }); |
| | | |
| | | const { drawerVisible, operateType, editingData, handleAdd, handleEdit, checkedRowKeys, onBatchDeleted, onDeleted } = |
| | | useTableOperate(data, 'id', getData); |
| | | |
| | | async function handleBatchDelete() { |
| | | // request |
| | | const { error } = await fetchBatchDeleteStd(checkedRowKeys.value); |
| | | if (error) return; |
| | | onBatchDeleted(); |
| | | } |
| | | |
| | | async function handleDelete(id: CommonType.IdType) { |
| | | // request |
| | | const { error } = await fetchBatchDeleteStd([id]); |
| | | if (error) return; |
| | | onDeleted(); |
| | | } |
| | | |
| | | function edit(id: CommonType.IdType) { |
| | | handleEdit(id); |
| | | } |
| | | |
| | | function handleExport() { |
| | | download('/qm/std/export', searchParams.value, `å¤å®è§ç¨_${new Date().getTime()}.xlsx`); |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto"> |
| | | <StdSearch v-model:model="searchParams" @search="getDataByPage" /> |
| | | <NCard title="å¤å®è§ç¨å表" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden"> |
| | | <template #header-extra> |
| | | <TableHeaderOperation |
| | | v-model:columns="columnChecks" |
| | | :disabled-delete="checkedRowKeys.length === 0" |
| | | :loading="loading" |
| | | :show-add="hasAuth('qm:std:add')" |
| | | :show-delete="hasAuth('qm:std:remove')" |
| | | :show-export="hasAuth('qm:std:export')" |
| | | @add="handleAdd" |
| | | @delete="handleBatchDelete" |
| | | @export="handleExport" |
| | | @refresh="getData" |
| | | /> |
| | | </template> |
| | | <NDataTable |
| | | v-model:checked-row-keys="checkedRowKeys" |
| | | :columns="columns" |
| | | :data="data" |
| | | size="small" |
| | | :flex-height="!appStore.isMobile" |
| | | :scroll-x="scrollX" |
| | | :loading="loading" |
| | | remote |
| | | :row-key="row => row.id" |
| | | :pagination="mobilePagination" |
| | | class="sm:h-full" |
| | | /> |
| | | <StdOperateDrawer |
| | | v-model:visible="drawerVisible" |
| | | :operate-type="operateType" |
| | | :row-data="editingData" |
| | | @submitted="getDataByPage" |
| | | /> |
| | | </NCard> |
| | | </div> |
| | | </template> |
| | | |
| | | <style scoped></style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script setup lang="ts"> |
| | | import { computed, ref, watch } from 'vue'; |
| | | import { jsonClone } from '@sa/utils'; |
| | | import { fetchCreateStd, fetchUpdateStd } from '@/service/api/qm/std'; |
| | | import { useFormRules, useNaiveForm } from '@/hooks/common/form'; |
| | | import { $t } from '@/locales'; |
| | | |
| | | defineOptions({ |
| | | name: 'StdOperateDrawer' |
| | | }); |
| | | |
| | | interface Props { |
| | | /** the type of operation */ |
| | | operateType: NaiveUI.TableOperateType; |
| | | /** the edit row data */ |
| | | rowData?: Api.Qm.Std | null; |
| | | } |
| | | |
| | | const props = defineProps<Props>(); |
| | | |
| | | interface Emits { |
| | | (e: 'submitted'): void; |
| | | } |
| | | |
| | | const emit = defineEmits<Emits>(); |
| | | |
| | | const visible = defineModel<boolean>('visible', { |
| | | default: false |
| | | }); |
| | | |
| | | const { formRef, validate, restoreValidation } = useNaiveForm(); |
| | | const { createRequiredRule } = useFormRules(); |
| | | |
| | | const title = computed(() => { |
| | | const titles: Record<NaiveUI.TableOperateType, string> = { |
| | | add: 'æ°å¢å¤å®è§ç¨', |
| | | edit: 'ç¼è¾å¤å®è§ç¨' |
| | | }; |
| | | return titles[props.operateType]; |
| | | }); |
| | | |
| | | type Model = Api.Qm.StdOperateParams; |
| | | |
| | | const model = ref<Model>(createDefaultModel()); |
| | | |
| | | function createDefaultModel(): Model { |
| | | return { |
| | | id: '', |
| | | stdCode: '', |
| | | stdName: '', |
| | | cdate: null, |
| | | ver: null, |
| | | enable: null, |
| | | itemCod: '', |
| | | itemNam: '', |
| | | typ: null, |
| | | stdDes: '', |
| | | checkLevel: null, |
| | | category: null, |
| | | matfltype: '', |
| | | matflname: '' |
| | | }; |
| | | } |
| | | |
| | | type RuleKey = Extract< |
| | | keyof Model, |
| | | | 'id' |
| | | >; |
| | | |
| | | const rules: Record<RuleKey, App.Global.FormRule> = { |
| | | id: createRequiredRule('ç¼ç ä¸è½ä¸ºç©º'), |
| | | }; |
| | | |
| | | function handleUpdateModelWhenEdit() { |
| | | model.value = createDefaultModel(); |
| | | |
| | | if (props.operateType === 'edit' && props.rowData) { |
| | | Object.assign(model.value, jsonClone(props.rowData)); |
| | | } |
| | | } |
| | | |
| | | function closeDrawer() { |
| | | visible.value = false; |
| | | } |
| | | |
| | | async function handleSubmit() { |
| | | await validate(); |
| | | |
| | | const { id, stdCode, stdName, cdate, ver, enable, itemCod, itemNam, typ, stdDes, checkLevel, category, matfltype, matflname } = model.value; |
| | | |
| | | // request |
| | | if (props.operateType === 'add') { |
| | | const { error } = await fetchCreateStd({ stdCode, stdName, cdate, ver, enable, itemCod, itemNam, typ, stdDes, checkLevel, category, matfltype, matflname }); |
| | | if (error) return; |
| | | } |
| | | |
| | | if (props.operateType === 'edit') { |
| | | const { error } = await fetchUpdateStd({ id, stdCode, stdName, cdate, ver, enable, itemCod, itemNam, typ, stdDes, checkLevel, category, matfltype, matflname }); |
| | | if (error) return; |
| | | } |
| | | |
| | | window.$message?.success($t('common.updateSuccess')); |
| | | closeDrawer(); |
| | | emit('submitted'); |
| | | } |
| | | |
| | | watch(visible, () => { |
| | | if (visible.value) { |
| | | handleUpdateModelWhenEdit(); |
| | | restoreValidation(); |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%"> |
| | | <NDrawerContent :title="title" :native-scrollbar="false" closable> |
| | | <NForm ref="formRef" :model="model" :rules="rules"> |
| | | <NFormItem label="è§ç¨ä»£ç " path="stdCode"> |
| | | <NInput v-model:value="model.stdCode" placeholder="请è¾å
¥è§ç¨ä»£ç " /> |
| | | </NFormItem> |
| | | <NFormItem label="è§ç¨åç§°" path="stdName"> |
| | | <NInput v-model:value="model.stdName" placeholder="请è¾å
¥è§ç¨åç§°" /> |
| | | </NFormItem> |
| | | <NFormItem label="å建æ¶é´" path="cdate"> |
| | | <NDatePicker |
| | | v-model:formatted-value="model.cdate" |
| | | type="datetime" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | clearable |
| | | /> |
| | | </NFormItem> |
| | | <NFormItem label="çæ¬å·" path="ver"> |
| | | <NInput v-model:value="model.ver" placeholder="请è¾å
¥çæ¬å·" /> |
| | | </NFormItem> |
| | | <NFormItem label="å¯ç¨æ è¯" path="enable"> |
| | | <NInput v-model:value="model.enable" placeholder="请è¾å
¥å¯ç¨æ è¯" /> |
| | | </NFormItem> |
| | | <NFormItem label="æ£éªé¡¹ç®code" path="itemCod"> |
| | | <NInput v-model:value="model.itemCod" placeholder="请è¾å
¥æ£éªé¡¹ç®code" /> |
| | | </NFormItem> |
| | | <NFormItem label="æ£éªé¡¹ç®åç§°" path="itemNam"> |
| | | <NInput v-model:value="model.itemNam" placeholder="请è¾å
¥æ£éªé¡¹ç®åç§°" /> |
| | | </NFormItem> |
| | | <NFormItem label="å¤å®ç±»å 0-æå¨å¤å®,1-ä¸ä¸éå¤å®,2-å¹³åå¼å¤å®,3-SDå¼å¤å®,4-CVå¼å¤å®,5-è¶
æ æ°å¤å®" path="typ"> |
| | | <NInput v-model:value="model.typ" placeholder="请è¾å
¥å¤å®ç±»å 0-æå¨å¤å®,1-ä¸ä¸éå¤å®,2-å¹³åå¼å¤å®,3-SDå¼å¤å®,4-CVå¼å¤å®,5-è¶
æ æ°å¤å®" /> |
| | | </NFormItem> |
| | | <NFormItem label="夿³¨" path="stdDes"> |
| | | <NInput v-model:value="model.stdDes" placeholder="请è¾å
¥å¤æ³¨" /> |
| | | </NFormItem> |
| | | <NFormItem label="æ£éªçº§å«" path="checkLevel"> |
| | | <NInput v-model:value="model.checkLevel" placeholder="请è¾å
¥æ£éªçº§å«" /> |
| | | </NFormItem> |
| | | <NFormItem label="ç±»å ï¼ 0-æå 1-è¾
æ" path="category"> |
| | | <NInput v-model:value="model.category" placeholder="请è¾å
¥ç±»å ï¼ 0-æå 1-è¾
æ" /> |
| | | </NFormItem> |
| | | <NFormItem label="$column.columnComment" path="matfltype"> |
| | | <NSelect |
| | | v-model:value="model.matfltype" |
| | | placeholder="è¯·éæ©$column.columnComment" |
| | | :options="[{ value: '0', label: 'è¯·éæ©åå
¸çæ' }]" |
| | | clearable |
| | | /> |
| | | </NFormItem> |
| | | <NFormItem label="$column.columnComment" path="matflname"> |
| | | <NInput v-model:value="model.matflname" placeholder="请è¾å
¥$column.columnComment" /> |
| | | </NFormItem> |
| | | </NForm> |
| | | <template #footer> |
| | | <NSpace :size="16"> |
| | | <NButton @click="closeDrawer">{{ $t('common.cancel') }}</NButton> |
| | | <NButton type="primary" @click="handleSubmit">{{ $t('common.confirm') }}</NButton> |
| | | </NSpace> |
| | | </template> |
| | | </NDrawerContent> |
| | | </NDrawer> |
| | | </template> |
| | | |
| | | <style scoped></style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script setup lang="ts"> |
| | | import { toRaw } from 'vue'; |
| | | import { jsonClone } from '@sa/utils'; |
| | | import { useNaiveForm } from '@/hooks/common/form'; |
| | | import { $t } from '@/locales'; |
| | | |
| | | defineOptions({ |
| | | name: 'StdSearch' |
| | | }); |
| | | |
| | | interface Emits { |
| | | (e: 'search'): void; |
| | | } |
| | | |
| | | const emit = defineEmits<Emits>(); |
| | | |
| | | const { formRef, validate, restoreValidation } = useNaiveForm(); |
| | | |
| | | const model = defineModel<Api.Qm.StdSearchParams>('model', { required: true }); |
| | | |
| | | const defaultModel = jsonClone(toRaw(model.value)); |
| | | |
| | | // å¤å®ç±»åé项ï¼0-æå¨å¤å® 1-ä¸ä¸éå¤å® 2-å¹³åå¼å¤å® 3-SDå¼å¤å® 4-CVå¼å¤å® 5-è¶
æ æ°å¤å® |
| | | const typOptions = [ |
| | | { label: 'æå¨å¤å®', value: 0 }, |
| | | { label: 'ä¸ä¸éå¤å®', value: 1 }, |
| | | { label: 'å¹³åå¼å¤å®', value: 2 }, |
| | | { label: 'SDå¼å¤å®', value: 3 }, |
| | | { label: 'CVå¼å¤å®', value: 4 }, |
| | | { label: 'è¶
æ æ°å¤å®', value: 5 } |
| | | ]; |
| | | |
| | | // ç©æç±»åé项ï¼0-æå 1-è¾
æ |
| | | const categoryOptions = [ |
| | | { label: 'æå', value: 0 }, |
| | | { label: 'è¾
æ', value: 1 } |
| | | ]; |
| | | |
| | | function resetModel() { |
| | | Object.assign(model.value, defaultModel); |
| | | } |
| | | |
| | | async function reset() { |
| | | await restoreValidation(); |
| | | resetModel(); |
| | | emit('search'); |
| | | } |
| | | |
| | | async function search() { |
| | | await validate(); |
| | | emit('search'); |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <NCard :bordered="false" size="small" class="card-wrapper"> |
| | | <NCollapse> |
| | | <NCollapseItem :title="$t('common.search')" name="qm-std-search"> |
| | | <NForm ref="formRef" :model="model" label-placement="left" :label-width="80"> |
| | | <NGrid responsive="screen" item-responsive> |
| | | <NFormItemGi span="24 s:12 m:6" label="è§ç¨ä»£ç " label-width="auto" path="stdCode" class="pr-24px"> |
| | | <NInput v-model:value="model.stdCode" placeholder="请è¾å
¥è§ç¨ä»£ç " /> |
| | | </NFormItemGi> |
| | | <NFormItemGi span="24 s:12 m:6" label="è§ç¨åç§°" label-width="auto" path="stdName" class="pr-24px"> |
| | | <NInput v-model:value="model.stdName" placeholder="请è¾å
¥è§ç¨åç§°" /> |
| | | </NFormItemGi> |
| | | <NFormItemGi span="24 s:12 m:6" label="å¤å®ç±»å" label-width="auto" path="typ" class="pr-24px"> |
| | | <NSelect v-model:value="model.typ" :options="typOptions" placeholder="è¯·éæ©å¤å®ç±»å" clearable /> |
| | | </NFormItemGi> |
| | | <NFormItemGi span="24 s:12 m:6" label="ç©æç±»å" label-width="auto" path="category" class="pr-24px"> |
| | | <NSelect v-model:value="model.category" :options="categoryOptions" placeholder="è¯·éæ©ç©æç±»å" clearable /> |
| | | </NFormItemGi> |
| | | <NFormItemGi :show-feedback="false" span="24" class="pr-24px"> |
| | | <NSpace class="w-full" justify="end"> |
| | | <NButton @click="reset"> |
| | | <template #icon> |
| | | <icon-ic-round-refresh class="text-icon" /> |
| | | </template> |
| | | {{ $t('common.reset') }} |
| | | </NButton> |
| | | <NButton type="primary" ghost @click="search"> |
| | | <template #icon> |
| | | <icon-ic-round-search class="text-icon" /> |
| | | </template> |
| | | {{ $t('common.search') }} |
| | | </NButton> |
| | | </NSpace> |
| | | </NFormItemGi> |
| | | </NGrid> |
| | | </NForm> |
| | | </NCollapseItem> |
| | | </NCollapse> |
| | | </NCard> |
| | | </template> |
| | | |
| | | <style scoped></style> |