单价管理

This commit is contained in:
磷叶 2024-10-17 18:04:59 +08:00
parent b54473940b
commit 143198c9b5
19 changed files with 1219 additions and 58 deletions

View File

@ -0,0 +1,41 @@
package com.ruoyi.common.core.domain;
import lombok.Data;
/**
* 业务校验结果
* @author wjh
* 2024/4/16
*/
@Data
public class ValidateResult {
private int code;
private String msg;
public boolean isSuccess() {
return this.code == 200;
}
public boolean isError() {
return !isSuccess();
}
private ValidateResult(int code, String msg) {
this.code = code;
this.msg = msg;
}
public static ValidateResult success() {
return new ValidateResult(200, "success");
}
public static ValidateResult error(String msg) {
return new ValidateResult(500, msg);
}
public static ValidateResult error(int code, String msg) {
return new ValidateResult(code, msg);
}
}

View File

@ -9,7 +9,7 @@ import java.util.Set;
/**
* 登录用户身份权限
*
*
* @author ruoyi
*/
public class LoginUser implements UserDetails
@ -132,6 +132,10 @@ public class LoginUser implements UserDetails
return user.getUserName();
}
public String getNickName() {
return user.getNickName();
}
/**
* 账户是否未过期,过期无法验证
*/
@ -144,7 +148,7 @@ public class LoginUser implements UserDetails
/**
* 指定用户是否解锁,锁定的用户无法进行身份验证
*
*
* @return
*/
@JSONField(serialize = false)
@ -156,7 +160,7 @@ public class LoginUser implements UserDetails
/**
* 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
*
*
* @return
*/
@JSONField(serialize = false)
@ -168,7 +172,7 @@ public class LoginUser implements UserDetails
/**
* 是否可用 ,禁用的用户不能身份验证
*
*
* @return
*/
@JSONField(serialize = false)

View File

@ -0,0 +1,17 @@
package com.ruoyi.common.core.validate;
import javax.validation.groups.Default;
/**
* Spring validate group
* @author
* 2024/3/6
*/
public interface ValidGroup {
// 新增
interface Create extends Default {}
// 修改
interface Update extends Default {}
}

View File

@ -15,7 +15,7 @@ import com.ruoyi.common.exception.ServiceException;
/**
* 安全服务工具类
*
*
* @author ruoyi
*/
public class SecurityUtils
@ -54,14 +54,21 @@ public class SecurityUtils
/**
* 获取用户账户
**/
public static String getUsername()
{
try
{
public static String getUsername() {
try {
return getLoginUser().getUsername();
} catch (Exception e) {
throw new ServiceException("获取用户账户异常", HttpStatus.UNAUTHORIZED);
}
catch (Exception e)
{
}
/**
* 获取用户名称
**/
public static String getNickName() {
try {
return getLoginUser().getNickName();
} catch (Exception e) {
throw new ServiceException("获取用户账户异常", HttpStatus.UNAUTHORIZED);
}
}
@ -116,7 +123,7 @@ public class SecurityUtils
/**
* 是否为管理员
*
*
* @param userId 用户ID
* @return 结果
*/
@ -127,7 +134,7 @@ public class SecurityUtils
/**
* 验证用户是否具备某权限
*
*
* @param permission 权限字符串
* @return 用户是否具备某权限
*/
@ -138,7 +145,7 @@ public class SecurityUtils
/**
* 判断是否包含权限
*
*
* @param authorities 权限列表
* @param permission 权限字符串
* @return 用户是否具备某权限
@ -151,7 +158,7 @@ public class SecurityUtils
/**
* 验证用户是否拥有某个角色
*
*
* @param role 角色标识
* @return 用户是否具备某角色
*/
@ -164,7 +171,7 @@ public class SecurityUtils
/**
* 判断是否包含角色
*
*
* @param roles 角色列表
* @param role 角色
* @return 用户是否具备某角色权限

View File

@ -0,0 +1,43 @@
package com.ruoyi.common.utils;
import com.ruoyi.common.core.domain.ValidateResult;
import com.ruoyi.common.exception.ServiceException;
/**
* @author
* 2024/3/4
*/
public class ServiceUtil {
/**
* 判断是否满足条件满足则抛出异常
* @param flag 条件
* @param msg 异常说明
*/
public static void assertion(boolean flag, String msg) {
assertion(flag, msg, 500);
}
/**
* 判断是否满足条件满足则抛出异常
* @param flag 条件
* @param msg 异常说明
* @param code 业务代码
*/
public static void assertion(boolean flag, String msg, int code) {
if (flag) {
throw new ServiceException(msg, code);
}
}
public static void assertion(ValidateResult result) {
if (result.isError()) {
throw new ServiceException(result.getMsg(), result.getCode());
}
}
public static void assertion(boolean flag, String format, Object ...args) {
if (flag) {
throw new ServiceException(String.format(format, args), 500);
}
}
}

View File

@ -75,20 +75,9 @@
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['${moduleName}:${businessName}:add']"
v-has-permi="['${moduleName}:${businessName}:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['${moduleName}:${businessName}:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
@ -97,7 +86,7 @@
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['${moduleName}:${businessName}:remove']"
v-has-permi="['${moduleName}:${businessName}:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
@ -107,7 +96,7 @@
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['${moduleName}:${businessName}:export']"
v-has-permi="['${moduleName}:${businessName}:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
@ -167,14 +156,14 @@
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['${moduleName}:${businessName}:edit']"
v-has-permi="['${moduleName}:${businessName}:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['${moduleName}:${businessName}:remove']"
v-has-permi="['${moduleName}:${businessName}:remove']"
>删除</el-button>
</template>
</el-table-column>
@ -189,8 +178,9 @@
/>
<!-- 添加或修改${functionName}对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body :close-on-click-modal="false">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-row>
#foreach($column in $columns)
#set($field=$column.javaField)
#if($column.insert && !$column.pk)
@ -203,23 +193,23 @@
#end
#set($dictType=$column.dictType)
#if($column.htmlType == "input")
<el-form-item label="${comment}" prop="${field}">
<form-col :span="span" label="${comment}" prop="${field}">
<el-input v-model="form.${field}" placeholder="请输入${comment}" />
</el-form-item>
</form-col>
#elseif($column.htmlType == "imageUpload")
<el-form-item label="${comment}" prop="${field}">
<form-col :span="span" label="${comment}" prop="${field}">
<image-upload v-model="form.${field}"/>
</el-form-item>
</form-col>
#elseif($column.htmlType == "fileUpload")
<el-form-item label="${comment}" prop="${field}">
<form-col :span="span" label="${comment}" prop="${field}">
<file-upload v-model="form.${field}"/>
</el-form-item>
</form-col>
#elseif($column.htmlType == "editor")
<el-form-item label="${comment}">
<form-col :span="span" label="${comment}">
<editor v-model="form.${field}" :min-height="192"/>
</el-form-item>
</form-col>
#elseif($column.htmlType == "select" && "" != $dictType)
<el-form-item label="${comment}" prop="${field}">
<form-col :span="span" label="${comment}" prop="${field}">
<el-select v-model="form.${field}" placeholder="请选择${comment}">
<el-option
v-for="dict in dict.type.${dictType}"
@ -232,15 +222,15 @@
#end
></el-option>
</el-select>
</el-form-item>
</form-col>
#elseif($column.htmlType == "select" && $dictType)
<el-form-item label="${comment}" prop="${field}">
<form-col :span="span" label="${comment}" prop="${field}">
<el-select v-model="form.${field}" placeholder="请选择${comment}">
<el-option label="请选择字典生成" value="" />
</el-select>
</el-form-item>
</form-col>
#elseif($column.htmlType == "checkbox" && "" != $dictType)
<el-form-item label="${comment}" prop="${field}">
<form-col :span="span" label="${comment}" prop="${field}">
<el-checkbox-group v-model="form.${field}">
<el-checkbox
v-for="dict in dict.type.${dictType}"
@ -249,15 +239,15 @@
{{dict.label}}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
</form-col>
#elseif($column.htmlType == "checkbox" && $dictType)
<el-form-item label="${comment}" prop="${field}">
<form-col :span="span" label="${comment}" prop="${field}">
<el-checkbox-group v-model="form.${field}">
<el-checkbox>请选择字典生成</el-checkbox>
</el-checkbox-group>
</el-form-item>
</form-col>
#elseif($column.htmlType == "radio" && "" != $dictType)
<el-form-item label="${comment}" prop="${field}">
<form-col :span="span" label="${comment}" prop="${field}">
<el-radio-group v-model="form.${field}">
<el-radio
v-for="dict in dict.type.${dictType}"
@ -269,30 +259,31 @@
#end
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
</form-col>
#elseif($column.htmlType == "radio" && $dictType)
<el-form-item label="${comment}" prop="${field}">
<form-col :span="span" label="${comment}" prop="${field}">
<el-radio-group v-model="form.${field}">
<el-radio label="1">请选择字典生成</el-radio>
</el-radio-group>
</el-form-item>
</form-col>
#elseif($column.htmlType == "datetime")
<el-form-item label="${comment}" prop="${field}">
<form-col :span="span" label="${comment}" prop="${field}">
<el-date-picker clearable
v-model="form.${field}"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择${comment}">
</el-date-picker>
</el-form-item>
</form-col>
#elseif($column.htmlType == "textarea")
<el-form-item label="${comment}" prop="${field}">
<form-col :span="span" label="${comment}" prop="${field}">
<el-input v-model="form.${field}" type="textarea" placeholder="请输入内容" />
</el-form-item>
</form-col>
#end
#end
#end
#end
</el-row>
#if($table.sub)
<el-divider content-position="center">${subTable.functionName}信息</el-divider>
<el-row :gutter="10" class="mb8">
@ -364,6 +355,7 @@
<script>
import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from "@/api/${moduleName}/${businessName}";
import { $showColumns } from '@/utils/mixins';
import FormCol from "@/components/FormCol/index.vue";
// 默认排序字段
const defaultSort = {
@ -377,6 +369,7 @@ export default {
#if(${dicts} != '')
dicts: [${dicts}],
#end
components: {FormCol},
data() {
return {
// 字段列表
@ -385,7 +378,7 @@ export default {
#if($column.pk)
{key: '${column.javaField}', visible: true, label: '${column.columnComment}', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
#elseif($column.list && $column.htmlType == "datetime")
{key: '${column.javaField}', visible: true, label: '${column.columnComment}', minWidth: "120", sortable: false, overflow: false, align: 'center', width: null},
{key: '${column.javaField}', visible: true, label: '${column.columnComment}', minWidth: null, sortable: false, overflow: false, align: 'center', width: "100"},
#elseif($column.list && "" != $javaField)
{key: '${column.javaField}', visible: true, label: '${column.columnComment}', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
#end

View File

@ -57,6 +57,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#end
#end
#end
${query.params.dataScope}
</sql>
<select id="select${ClassName}List" parameterType="${ClassName}Query" resultMap="${ClassName}Result">

View File

@ -0,0 +1,118 @@
package com.ruoyi.web.yh.price.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.core.validate.ValidGroup;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.web.yh.price.domain.dto.PriceVerifyDTO;
import com.ruoyi.web.yh.price.service.PriceConverter;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.web.yh.price.domain.Price;
import com.ruoyi.web.yh.price.domain.PriceVO;
import com.ruoyi.web.yh.price.domain.PriceQuery;
import com.ruoyi.web.yh.price.service.PriceService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* 单价Controller
*
* @author ruoyi
* @date 2024-10-17
*/
@RestController
@RequestMapping("/yh/price")
public class PriceController extends BaseController
{
@Autowired
private PriceService priceService;
@Autowired
private PriceConverter priceConverter;
@PreAuthorize("@ss.hasPermi('yh:price:list')")
@GetMapping("/list")
@DataScope(deptAlias = "sd")
public TableDataInfo list(PriceQuery query)
{
startPage();
startOrderBy();
List<PriceVO> list = priceService.selectPriceList(query);
return getDataTable(list);
}
@PreAuthorize("@ss.hasPermi('yh:price:export')")
@Log(title = "单价", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@DataScope(deptAlias = "sd")
public void export(HttpServletResponse response, PriceQuery query)
{
List<PriceVO> list = priceService.selectPriceList(query);
ExcelUtil<PriceVO> util = new ExcelUtil<PriceVO>(PriceVO.class);
util.exportExcel(response, list, "单价数据");
}
@PreAuthorize("@ss.hasPermi('yh:price:query')")
@GetMapping(value = "/{priceId}")
public AjaxResult getInfo(@PathVariable("priceId") Long priceId)
{
return success(priceService.selectPriceByPriceId(priceId));
}
@PreAuthorize("@ss.hasPermi('yh:price:add')")
@Log(title = "单价新增", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody @Validated(ValidGroup.Create.class) Price data)
{
Price po = priceConverter.toPoByCreate(data);
return toAjax(priceService.insertPrice(po));
}
@PreAuthorize("@ss.hasPermi('yh:price:edit')")
@Log(title = "单价修改", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody @Validated(ValidGroup.Update.class) Price data)
{
Price po = priceConverter.toPoByUpdate(data);
return toAjax(priceService.updatePrice(po));
}
@PreAuthorize("@ss.hasPermi('yh:price:submit')")
@Log(title = "单价提交", businessType = BusinessType.UPDATE)
@PutMapping("/{priceId}/submit")
public AjaxResult submit(@PathVariable Long priceId) {
return toAjax(priceService.submit(priceId));
}
@PreAuthorize("@ss.hasPermi('yh:price:cancel')")
@Log(title = "单价取消提交", businessType = BusinessType.UPDATE)
@PutMapping("/{priceId}/cancel")
public AjaxResult cancel(@PathVariable Long priceId) {
return toAjax(priceService.cancel(priceId));
}
@PreAuthorize("@ss.hasPermi('yh:price:verify')")
@Log(title = "单价审核", businessType = BusinessType.UPDATE)
@PutMapping("/verify")
public AjaxResult submit(@RequestBody @Validated PriceVerifyDTO dto) {
dto.setVerifyUser(SecurityUtils.getLoginUser().getUser());
return toAjax(priceService.verify(dto));
}
@PreAuthorize("@ss.hasPermi('yh:price:disable')")
@Log(title = "单价禁用", businessType = BusinessType.OTHER)
@PutMapping("/{priceId}/disable")
public AjaxResult disable(@PathVariable Long priceId) {
return toAjax(priceService.disable(priceId));
}
}

View File

@ -0,0 +1,122 @@
package com.ruoyi.web.yh.price.domain;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.core.validate.ValidGroup;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
/**
* 单价对象 bst_price
*
* @author ruoyi
* @date 2024-10-17
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class Price extends BaseEntity
{
private static final long serialVersionUID = 1L;
private Long priceId;
@Excel(name = "部门ID")
@ApiModelProperty("部门ID")
@NotNull(message = "部门不允许为空", groups = ValidGroup.Create.class)
private Long deptId;
@Excel(name = "状态")
@ApiModelProperty("状态")
private String status;
@Excel(name = "类别")
@ApiModelProperty("类别")
@Size(max = 200, message = "类别不允许超过200个字符")
private String category;
@Excel(name = "大小")
@ApiModelProperty("大小")
@Size(max = 200, message = "大小不允许超过200个字符")
private String size;
@Excel(name = "工序名称")
@ApiModelProperty("工序名称")
@Size(max = 200, message = "工序名称不允许超过200个字符")
private String name;
@Excel(name = "子工序名称")
@ApiModelProperty("子工序名称")
@Size(max = 200, message = "子工序名称不允许超过200个字符")
private String subName;
@Excel(name = "图案")
@ApiModelProperty("图案")
@Size(max = 200, message = "图案不允许超过200个字符")
private String pattern;
@Excel(name = "规格")
@ApiModelProperty("规格")
@Size(max = 200, message = "规格不允许超过200个字符")
private String spec;
@Excel(name = "单价")
@ApiModelProperty("单价")
@NotNull(message = "单价不允许为空", groups = ValidGroup.Create.class)
@Min(value = 0, message = "单价不允许小于0元")
private BigDecimal price;
@Excel(name = "单位")
@ApiModelProperty("单位")
@Size(max = 50, message = "单位不允许超过50个字符")
private String unit;
@Excel(name = "分类")
@ApiModelProperty("分类")
@Size(max = 200, message = "分类不允许超过200个字符")
private String classify;
@Excel(name = "创建人ID")
@ApiModelProperty("创建人ID")
private Long createId;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "审核时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty("审核时间")
private LocalDateTime verifyTime;
@Excel(name = "审核人ID")
@ApiModelProperty("审核人ID")
private Long verifyId;
@Excel(name = "审核人名称")
@ApiModelProperty("审核人名称")
private String verifyBy;
@Excel(name = "更新人ID")
@ApiModelProperty("更新人ID")
private Long updateId;
@Excel(name = "是否禁用")
@ApiModelProperty("是否禁用")
private Boolean disabled;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "禁用时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty("禁用时间")
private LocalDateTime disabledTime;
@Excel(name = "生产数量(个)")
@ApiModelProperty("生产数量(个)")
@Min(value = 0, message = "生产数量不允许小于0个")
private BigDecimal quantity;
}

View File

@ -0,0 +1,20 @@
package com.ruoyi.web.yh.price.domain;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
/**
* @author wjh
* 2024/10/17
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class PriceQuery extends PriceVO {
@ApiModelProperty("状态列表")
private List<String> statusList;
}

View File

@ -0,0 +1,18 @@
package com.ruoyi.web.yh.price.domain;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author wjh
* 2024/10/17
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class PriceVO extends Price {
@ApiModelProperty("部门名称")
private String deptName;
}

View File

@ -0,0 +1,27 @@
package com.ruoyi.web.yh.price.domain.dto;
import com.ruoyi.common.core.domain.entity.SysUser;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* 单价审核DTO
* @author wjh
* 2024/10/17
*/
@Data
public class PriceVerifyDTO {
@ApiModelProperty("单价ID")
@NotNull(message = "单价ID不允许为空")
private Long priceId;
@ApiModelProperty("是否通过")
@NotNull(message = "是否通过不允许为空")
private Boolean pass;
@ApiModelProperty("审核人")
private SysUser verifyUser;
}

View File

@ -0,0 +1,65 @@
package com.ruoyi.web.yh.price.domain.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author wjh
* 2024/10/17
*/
@Getter
@AllArgsConstructor
public enum PriceStatus {
WAIT_SUBMIT("1", "未提交"),
WAIT_VERIFY("2", "待审核"),
PASS("3", "已通过"),
REJECT("4", "未通过");
private final String status;
private final String msg;
public static List<String> asList(PriceStatus ...statuses) {
return Arrays.stream(statuses).map(PriceStatus::getStatus).collect(Collectors.toList());
}
/**
* 允许修改的状态
*/
public static List<String> canEdit() {
return asList(WAIT_SUBMIT);
}
/**
* 允许提交的状态
*/
public static List<String> canSubmit() {
return asList(WAIT_SUBMIT);
}
/**
* 允许取消的状态
*/
public static List<String> canCancel() {
return asList(WAIT_VERIFY);
}
/**
* 允许审核的状态
*/
public static List<String> canVerify() {
return asList(WAIT_VERIFY);
}
/**
* 允许禁用的状态
*/
public static List<String> canDisable() {
return asList(PASS);
}
}

View File

@ -0,0 +1,69 @@
package com.ruoyi.web.yh.price.mapper;
import java.util.List;
import com.ruoyi.web.yh.price.domain.Price;
import com.ruoyi.web.yh.price.domain.PriceVO;
import com.ruoyi.web.yh.price.domain.PriceQuery;
import org.apache.ibatis.annotations.Param;
/**
* 单价Mapper接口
*
* @author ruoyi
* @date 2024-10-17
*/
public interface PriceMapper
{
/**
* 查询单价
*
* @param priceId 单价主键
* @return 单价
*/
public PriceVO selectPriceByPriceId(Long priceId);
/**
* 查询单价列表
*
* @param query 单价
* @return 单价集合
*/
public List<PriceVO> selectPriceList(@Param("query")PriceQuery query);
/**
* 新增单价
*
* @param price 单价
* @return 结果
*/
public int insertPrice(Price price);
/**
* 修改单价
*
* @param price 单价
* @return 结果
*/
public int updatePrice(@Param("data") Price price);
/**
* 删除单价
*
* @param priceId 单价主键
* @return 结果
*/
public int deletePriceByPriceId(Long priceId);
/**
* 批量删除单价
*
* @param priceIds 需要删除的数据主键集合
* @return 结果
*/
public int deletePriceByPriceIds(Long[] priceIds);
/**
* 条件更新
*/
int updateByQuery(@Param("data") Price data, @Param("query") PriceQuery query);
}

View File

@ -0,0 +1,197 @@
<?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="com.ruoyi.web.yh.price.mapper.PriceMapper">
<resultMap type="PriceVO" id="PriceResult" autoMapping="true">
</resultMap>
<sql id="selectPriceVo">
select
bp.price_id,
bp.dept_id,
bp.status,
bp.category,
bp.size,
bp.name,
bp.sub_name,
bp.pattern,
bp.spec,
bp.price,
bp.unit,
bp.remark,
bp.classify,
bp.create_time,
bp.create_id,
bp.create_by,
bp.verify_time,
bp.verify_id,
bp.verify_by,
bp.update_time,
bp.update_id,
bp.update_by,
bp.disabled,
bp.disabled_time,
bp.quantity,
sd.dept_name as dept_name
from bst_price bp
left join sys_dept sd on sd.dept_id = bp.dept_id
</sql>
<sql id="searchCondition">
<if test="query.priceId != null "> and bp.price_id = #{query.priceId}</if>
<if test="query.deptId != null "> and bp.dept_id = #{query.deptId}</if>
<if test="query.status != null and query.status != ''"> and bp.status = #{query.status}</if>
<if test="query.category != null and query.category != ''"> and bp.category like concat('%', #{query.category}, '%')</if>
<if test="query.size != null and query.size != ''"> and bp.size like concat('%', #{query.size}, '%')</if>
<if test="query.name != null and query.name != ''"> and bp.name like concat('%', #{query.name}, '%')</if>
<if test="query.subName != null and query.subName != ''"> and bp.sub_name like concat('%', #{query.subName}, '%')</if>
<if test="query.pattern != null and query.pattern != ''"> and bp.pattern like concat('%', #{query.pattern}, '%')</if>
<if test="query.spec != null and query.spec != ''"> and bp.spec like concat('%', #{query.spec}, '%')</if>
<if test="query.unit != null and query.unit != ''"> and bp.unit like concat('%', #{query.unit}, '%')</if>
<if test="query.remark != null and query.remark != ''"> and bp.remark like concat('%', #{query.remark}, '%')</if>
<if test="query.classify != null and query.classify != ''"> and bp.classify like concat('%', #{query.classify}, '%')</if>
<if test="query.createId != null "> and bp.create_id = #{query.createId}</if>
<if test="query.createBy != null and query.createBy != ''"> and bp.create_by like concat('%', #{query.createBy}, '%')</if>
<if test="query.verifyId != null "> and bp.verify_id = #{query.verifyId}</if>
<if test="query.verifyBy != null and query.verifyBy != ''"> and bp.verify_by like concat('%', #{query.verifyBy}, '%')</if>
<if test="query.updateId != null "> and bp.update_id = #{query.updateId}</if>
<if test="query.updateBy != null and query.updateBy != ''"> and bp.update_by like concat('%', #{query.updateBy}, '%')</if>
<if test="query.disabled != null "> and bp.disabled = #{query.disabled}</if>
<if test="query.statusList != null and query.statusList.size() > 0">
and bp.status in
<foreach item="item" collection="query.statusList" open="(" separator="," close=")">
#{item}
</foreach>
</if>
${query.params.dataScope}
</sql>
<select id="selectPriceList" parameterType="PriceQuery" resultMap="PriceResult">
<include refid="selectPriceVo"/>
<where>
<include refid="searchCondition"/>
</where>
</select>
<select id="selectPriceByPriceId" parameterType="Long" resultMap="PriceResult">
<include refid="selectPriceVo"/>
where bp.price_id = #{priceId}
</select>
<insert id="insertPrice" parameterType="Price" useGeneratedKeys="true" keyProperty="priceId">
<selectKey resultType="Long" order="AFTER" keyProperty="priceId">
SELECT LAST_INSERT_ID();
</selectKey>
insert into bst_price
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="deptId != null">dept_id,</if>
<if test="status != null and status != ''">`status`,</if>
<if test="category != null">category,</if>
<if test="size != null">size,</if>
<if test="name != null">`name`,</if>
<if test="subName != null">sub_name,</if>
<if test="pattern != null">pattern,</if>
<if test="spec != null">spec,</if>
<if test="price != null">price,</if>
<if test="unit != null and unit != ''">unit,</if>
<if test="remark != null">remark,</if>
<if test="classify != null">classify,</if>
<if test="createTime != null">create_time,</if>
<if test="createId != null">create_id,</if>
<if test="createBy != null and createBy != ''">create_by,</if>
<if test="verifyTime != null">verify_time,</if>
<if test="verifyId != null">verify_id,</if>
<if test="verifyBy != null">verify_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="updateId != null">update_id,</if>
<if test="updateBy != null">update_by,</if>
<if test="disabled != null">disabled,</if>
<if test="disabledTime != null">disabled_time,</if>
<if test="quantity != null">quantity,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="deptId != null">#{deptId},</if>
<if test="status != null and status != ''">#{status},</if>
<if test="category != null">#{category},</if>
<if test="size != null">#{size},</if>
<if test="name != null">#{name},</if>
<if test="subName != null">#{subName},</if>
<if test="pattern != null">#{pattern},</if>
<if test="spec != null">#{spec},</if>
<if test="price != null">#{price},</if>
<if test="unit != null and unit != ''">#{unit},</if>
<if test="remark != null">#{remark},</if>
<if test="classify != null">#{classify},</if>
<if test="createTime != null">#{createTime},</if>
<if test="createId != null">#{createId},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if>
<if test="verifyTime != null">#{verifyTime},</if>
<if test="verifyId != null">#{verifyId},</if>
<if test="verifyBy != null">#{verifyBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="updateId != null">#{updateId},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="disabled != null">#{disabled},</if>
<if test="disabledTime != null">#{disabledTime},</if>
<if test="quantity != null">#{quantity},</if>
</trim>
</insert>
<update id="updatePrice" parameterType="Price">
update bst_price bp
<trim prefix="SET" suffixOverrides=",">
<include refid="updateColumns"/>
</trim>
where bp.price_id = #{data.priceId}
</update>
<update id="updateByQuery">
update bst_price bp
<trim prefix="SET" suffixOverrides=",">
<include refid="updateColumns"/>
</trim>
<where>
<include refid="searchCondition"/>
</where>
</update>
<sql id="updateColumns">
<if test="data.deptId != null">bp.dept_id = #{data.deptId},</if>
<if test="data.status != null and data.status != ''">bp.`status` = #{data.status},</if>
<if test="data.category != null">bp.category = #{data.category},</if>
<if test="data.size != null">bp.size = #{data.size},</if>
<if test="data.name != null">bp.`name` = #{data.name},</if>
<if test="data.subName != null">bp.sub_name = #{data.subName},</if>
<if test="data.pattern != null">bp.pattern = #{data.pattern},</if>
<if test="data.spec != null">bp.spec = #{data.spec},</if>
<if test="data.price != null">bp.price = #{data.price},</if>
<if test="data.unit != null and data.unit != ''">bp.unit = #{data.unit},</if>
<if test="data.remark != null">bp.remark = #{data.remark},</if>
<if test="data.classify != null">bp.classify = #{data.classify},</if>
<if test="data.createTime != null">bp.create_time = #{data.createTime},</if>
<if test="data.createId != null">bp.create_id = #{data.createId},</if>
<if test="data.createBy != null and data.createBy != ''">bp.create_by = #{data.createBy},</if>
<if test="data.verifyTime != null">bp.verify_time = #{data.verifyTime},</if>
<if test="data.verifyId != null">bp.verify_id = #{data.verifyId},</if>
<if test="data.verifyBy != null">bp.verify_by = #{data.verifyBy},</if>
<if test="data.updateTime != null">bp.update_time = #{data.updateTime},</if>
<if test="data.updateId != null">bp.update_id = #{data.updateId},</if>
<if test="data.updateBy != null">bp.update_by = #{data.updateBy},</if>
<if test="data.disabled != null">bp.disabled = #{data.disabled},</if>
<if test="data.disabledTime != null">bp.disabled_time = #{data.disabledTime},</if>
<if test="data.quantity != null">bp.quantity = #{data.quantity},</if>
</sql>
<delete id="deletePriceByPriceId" parameterType="Long">
delete from bst_price where price_id = #{priceId}
</delete>
<delete id="deletePriceByPriceIds" parameterType="String">
delete from bst_price where price_id in
<foreach item="priceId" collection="array" open="(" separator="," close=")">
#{priceId}
</foreach>
</delete>
</mapper>

View File

@ -0,0 +1,21 @@
package com.ruoyi.web.yh.price.service;
import com.ruoyi.web.yh.price.domain.Price;
import org.springframework.stereotype.Service;
/**
* @author wjh
* 2024/10/17
*/
public interface PriceConverter {
/**
* 创建时转为PO
*/
Price toPoByCreate(Price data);
/**
* 修改时转为PO
*/
Price toPoByUpdate(Price data);
}

View File

@ -0,0 +1,95 @@
package com.ruoyi.web.yh.price.service;
import java.util.List;
import com.ruoyi.web.yh.price.domain.Price;
import com.ruoyi.web.yh.price.domain.PriceVO;
import com.ruoyi.web.yh.price.domain.PriceQuery;
import com.ruoyi.web.yh.price.domain.dto.PriceVerifyDTO;
/**
* 单价Service接口
*
* @author ruoyi
* @date 2024-10-17
*/
public interface PriceService
{
/**
* 查询单价
*
* @param priceId 单价主键
* @return 单价
*/
public PriceVO selectPriceByPriceId(Long priceId);
/**
* 查询单价列表
*
* @param price 单价
* @return 单价集合
*/
public List<PriceVO> selectPriceList(PriceQuery price);
/**
* 新增单价
*
* @param price 单价
* @return 结果
*/
public int insertPrice(Price price);
/**
* 修改单价
*
* @param price 单价
* @return 结果
*/
public int updatePrice(Price price);
/**
* 批量删除单价
*
* @param priceIds 需要删除的单价主键集合
* @return 结果
*/
public int deletePriceByPriceIds(Long[] priceIds);
/**
* 删除单价信息
*
* @param priceId 单价主键
* @return 结果
*/
public int deletePriceByPriceId(Long priceId);
/**
* 条件更新
* @param data 数据
* @param query 条件
*/
int updateByQuery(Price data, PriceQuery query);
/**
* 提交审核
* @param priceId 单价ID
*/
int submit(Long priceId);
/**
* 取消提交
* @param priceId 单价ID
*/
int cancel(Long priceId);
/**
* 审核操作
* @param dto 参数
*/
int verify(PriceVerifyDTO dto);
/**
* 禁用操作
* @param priceId 单价ID
*/
int disable(Long priceId);
}

View File

@ -0,0 +1,73 @@
package com.ruoyi.web.yh.price.service.impl;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.web.yh.price.domain.Price;
import com.ruoyi.web.yh.price.domain.enums.PriceStatus;
import com.ruoyi.web.yh.price.service.PriceConverter;
import org.springframework.stereotype.Service;
/**
* @author wjh
* 2024/10/17
*/
@Service
public class PriceConverterImpl implements PriceConverter {
/**
* 创建时转为PO
*/
@Override
public Price toPoByCreate(Price data) {
if (data == null) {
return null;
}
LoginUser loginUser = SecurityUtils.getLoginUser();
Price po = new Price();
po.setStatus(PriceStatus.WAIT_SUBMIT.getStatus());
po.setDisabled(false);
po.setDeptId(data.getDeptId());
po.setCategory(data.getCategory());
po.setSize(data.getSize());
po.setName(data.getName());
po.setSubName(data.getSubName());
po.setPattern(data.getPattern());
po.setSpec(data.getSpec());
po.setPrice(data.getPrice());
po.setUnit(data.getUnit());
po.setClassify(data.getClassify());
po.setCreateId(loginUser.getUserId());
po.setQuantity(data.getQuantity());
po.setCreateBy(loginUser.getNickName());
po.setRemark(data.getRemark());
return po;
}
@Override
public Price toPoByUpdate(Price data) {
if (data == null) {
return null;
}
LoginUser loginUser = SecurityUtils.getLoginUser();
Price po = new Price();
po.setPriceId(data.getPriceId());
po.setDeptId(data.getDeptId());
po.setCategory(data.getCategory());
po.setSize(data.getSize());
po.setName(data.getName());
po.setSubName(data.getSubName());
po.setPattern(data.getPattern());
po.setSpec(data.getSpec());
po.setPrice(data.getPrice());
po.setUnit(data.getUnit());
po.setClassify(data.getClassify());
po.setQuantity(data.getQuantity());
po.setUpdateId(loginUser.getUserId());
po.setUpdateBy(loginUser.getNickName());
po.setRemark(data.getRemark());
return po;
}
}

View File

@ -0,0 +1,230 @@
package com.ruoyi.web.yh.price.service.impl;
import java.time.LocalDateTime;
import java.util.List;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.web.yh.price.domain.dto.PriceVerifyDTO;
import com.ruoyi.web.yh.price.domain.enums.PriceStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.web.yh.price.mapper.PriceMapper;
import com.ruoyi.web.yh.price.domain.Price;
import com.ruoyi.web.yh.price.domain.PriceVO;
import com.ruoyi.web.yh.price.domain.PriceQuery;
import com.ruoyi.web.yh.price.service.PriceService;
import org.springframework.transaction.support.TransactionTemplate;
/**
* 单价Service业务层处理
*
* @author ruoyi
* @date 2024-10-17
*/
@Service
public class PriceServiceImpl implements PriceService
{
@Autowired
private PriceMapper priceMapper;
@Autowired
private TransactionTemplate transactionTemplate;
/**
* 查询单价
*
* @param priceId 单价主键
* @return 单价
*/
@Override
public PriceVO selectPriceByPriceId(Long priceId)
{
return priceMapper.selectPriceByPriceId(priceId);
}
/**
* 查询单价列表
*
* @param price 单价
* @return 单价
*/
@Override
public List<PriceVO> selectPriceList(PriceQuery price)
{
return priceMapper.selectPriceList(price);
}
/**
* 新增单价
*
* @param price 单价
* @return 结果
*/
@Override
public int insertPrice(Price price)
{
price.setCreateTime(DateUtils.getNowDate());
return priceMapper.insertPrice(price);
}
/**
* 修改单价
*
* @param data 单价
* @return 结果
*/
@Override
public int updatePrice(Price data)
{
PriceVO old = selectPriceByPriceId(data.getPriceId());
ServiceUtil.assertion(old == null, "待修改的单价不存在");
ServiceUtil.assertion(!PriceStatus.canEdit().contains(old.getStatus()), "待修改的单价当前状态不允许修改,请刷新后重试");
data.setUpdateTime(DateUtils.getNowDate());
Integer result = transactionTemplate.execute(status -> {
PriceQuery query = new PriceQuery();
query.setPriceId(data.getPriceId());
query.setStatusList(PriceStatus.canEdit());
int update = this.updateByQuery(data, query);
ServiceUtil.assertion(update != 1, "修改单价失败,当前单价已发生变化,请刷新后重试");
return update;
});
return result == null ? 0 : result;
}
/**
* 批量删除单价
*
* @param priceIds 需要删除的单价主键
* @return 结果
*/
@Override
public int deletePriceByPriceIds(Long[] priceIds)
{
return priceMapper.deletePriceByPriceIds(priceIds);
}
/**
* 删除单价信息
*
* @param priceId 单价主键
* @return 结果
*/
@Override
public int deletePriceByPriceId(Long priceId)
{
return priceMapper.deletePriceByPriceId(priceId);
}
@Override
public int updateByQuery(Price data, PriceQuery query) {
if (data == null || query == null) {
return 0;
}
return priceMapper.updateByQuery(data, query);
}
@Override
public int submit(Long priceId) {
PriceVO old = selectPriceByPriceId(priceId);
ServiceUtil.assertion(old == null, "待提交的单价不存在");
ServiceUtil.assertion(!PriceStatus.canSubmit().contains(old.getStatus()), "待提交的单价当前状态不允许提交,请刷新后重试");
Integer result = transactionTemplate.execute(status -> {
Price data = new Price();
data.setStatus(PriceStatus.WAIT_VERIFY.getStatus());
PriceQuery query = new PriceQuery();
query.setPriceId(priceId);
query.setStatusList(PriceStatus.canSubmit());
int update = this.updateByQuery(data, query);
ServiceUtil.assertion(update != 1, "提交失败,当前单价状态已发生变化,请刷新后重试");
return update;
});
return result == null ? 0 :result;
}
@Override
public int cancel(Long priceId) {
PriceVO old = selectPriceByPriceId(priceId);
ServiceUtil.assertion(old == null, "待取消提交的单价不存在");
ServiceUtil.assertion(!PriceStatus.canCancel().contains(old.getStatus()), "待提交的单价当前状态不允许取消提交,请刷新后重试");
Integer result = transactionTemplate.execute(status -> {
Price data = new Price();
data.setStatus(PriceStatus.WAIT_SUBMIT.getStatus());
PriceQuery query = new PriceQuery();
query.setPriceId(priceId);
query.setStatusList(PriceStatus.canCancel());
int update = this.updateByQuery(data, query);
ServiceUtil.assertion(update != 1, "取消失败,当前单价状态已发生变化,请刷新后重试");
return update;
});
return result == null ? 0 :result;
}
@Override
public int verify(PriceVerifyDTO dto) {
if (dto == null || dto.getPriceId() == null || dto.getPass() == null) {
return 0;
}
PriceVO old = selectPriceByPriceId(dto.getPriceId());
ServiceUtil.assertion(old == null, "待审核的单价不存在,请刷新后重试");
ServiceUtil.assertion(!PriceStatus.canVerify().contains(old.getStatus()), "待审核的单价当前状态无法审核,请刷新后重试");
Integer result = transactionTemplate.execute(status -> {
// 修改状态
Price data = new Price();
data.setStatus(dto.getPass() ? PriceStatus.PASS.getStatus() : PriceStatus.REJECT.getStatus());
data.setVerifyTime(LocalDateTime.now());
SysUser verifyUser = dto.getVerifyUser();
if (verifyUser != null) {
data.setVerifyBy(verifyUser.getNickName());
data.setVerifyId(verifyUser.getUserId());
}
PriceQuery query = new PriceQuery();
query.setPriceId(dto.getPriceId());
query.setStatusList(PriceStatus.canVerify());
int update = this.updateByQuery(data, query);
ServiceUtil.assertion(update != 1, "审核失败,当前单价状态已发生变化,请刷新后重试");
return update;
});
return result == null ? 0 : result;
}
@Override
public int disable(Long priceId) {
if (priceId == null) {
return 0;
}
PriceVO old = selectPriceByPriceId(priceId);
ServiceUtil.assertion(old == null, "待禁用的单价不存在,请刷新后重试");
ServiceUtil.assertion(!PriceStatus.canDisable().contains(old.getStatus()), "待禁用的单价当前状态不允许禁用");
ServiceUtil.assertion(old.getDisabled() != null && old.getDisabled(), "待禁用的单价已被禁用,请勿重复操作");
Integer result = transactionTemplate.execute(status -> {
Price data = new Price();
data.setDisabled(true);
data.setDisabledTime(LocalDateTime.now());
PriceQuery query = new PriceQuery();
query.setStatusList(PriceStatus.canDisable());
query.setPriceId(priceId);
query.setDisabled(false);
int update = this.updateByQuery(data, query);
ServiceUtil.assertion(update != 1, "禁用单价失败,当前状态已发生变化,请刷新后重试");
return update;
});
return result == null ? 0 : result;
}
}