mirror of
				https://github.com/continew-org/continew-admin.git
				synced 2025-11-04 10:57:10 +08:00 
			
		
		
		
	新增:新增系统管理/岗位管理(列表、查看详情、新增、修改、删除、导出)
This commit is contained in:
		@@ -75,7 +75,7 @@ public class LoginUser implements Serializable {
 | 
			
		||||
    private String description;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 最后一次修改密码的时间
 | 
			
		||||
     * 最后一次修改密码时间
 | 
			
		||||
     */
 | 
			
		||||
    private LocalDateTime pwdResetTime;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -93,9 +93,9 @@ public class UserInfoVO implements Serializable {
 | 
			
		||||
    private String description;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 最后一次修改密码的时间
 | 
			
		||||
     * 最后一次修改密码时间
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "最后一次修改密码的时间")
 | 
			
		||||
    @Schema(description = "最后一次修改密码时间")
 | 
			
		||||
    private LocalDateTime pwdResetTime;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,28 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package top.charles7c.cnadmin.system.mapper;
 | 
			
		||||
 | 
			
		||||
import top.charles7c.cnadmin.common.base.BaseMapper;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.entity.PostDO;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 岗位 Mapper
 | 
			
		||||
 *
 | 
			
		||||
 * @author Charles7c
 | 
			
		||||
 * @since 2023/2/25 22:26
 | 
			
		||||
 */
 | 
			
		||||
public interface PostMapper extends BaseMapper<PostDO> {}
 | 
			
		||||
@@ -0,0 +1,28 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package top.charles7c.cnadmin.system.mapper;
 | 
			
		||||
 | 
			
		||||
import top.charles7c.cnadmin.common.base.BaseMapper;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.entity.UserPostDO;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 用户和岗位 Mapper
 | 
			
		||||
 *
 | 
			
		||||
 * @author Charles7c
 | 
			
		||||
 * @since 2023/2/25 22:28
 | 
			
		||||
 */
 | 
			
		||||
public interface UserPostMapper extends BaseMapper<UserPostDO> {}
 | 
			
		||||
@@ -0,0 +1,64 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package top.charles7c.cnadmin.system.model.entity;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
 | 
			
		||||
import com.baomidou.mybatisplus.annotation.TableId;
 | 
			
		||||
import com.baomidou.mybatisplus.annotation.TableName;
 | 
			
		||||
 | 
			
		||||
import top.charles7c.cnadmin.common.base.BaseDO;
 | 
			
		||||
import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 岗位实体
 | 
			
		||||
 *
 | 
			
		||||
 * @author Charles7c
 | 
			
		||||
 * @since 2023/2/25 22:25
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
@TableName("sys_post")
 | 
			
		||||
public class PostDO extends BaseDO {
 | 
			
		||||
 | 
			
		||||
    private static final long serialVersionUID = 1L;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 岗位 ID
 | 
			
		||||
     */
 | 
			
		||||
    @TableId
 | 
			
		||||
    private Long postId;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 岗位名称
 | 
			
		||||
     */
 | 
			
		||||
    private String postName;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 描述
 | 
			
		||||
     */
 | 
			
		||||
    private String description;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 岗位排序
 | 
			
		||||
     */
 | 
			
		||||
    private Integer postSort;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 状态(1启用 2禁用)
 | 
			
		||||
     */
 | 
			
		||||
    private DisEnableStatusEnum status;
 | 
			
		||||
}
 | 
			
		||||
@@ -32,7 +32,7 @@ import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum;
 | 
			
		||||
 * @since 2023/2/8 22:54
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
@TableName(value = "sys_role", autoResultMap = true)
 | 
			
		||||
@TableName("sys_role")
 | 
			
		||||
public class RoleDO extends BaseDO {
 | 
			
		||||
 | 
			
		||||
    private static final long serialVersionUID = 1L;
 | 
			
		||||
 
 | 
			
		||||
@@ -91,7 +91,7 @@ public class UserDO extends BaseDO {
 | 
			
		||||
    private DisEnableStatusEnum status;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 最后一次修改密码的时间
 | 
			
		||||
     * 最后一次修改密码时间
 | 
			
		||||
     */
 | 
			
		||||
    private LocalDateTime pwdResetTime;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,53 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package top.charles7c.cnadmin.system.model.entity;
 | 
			
		||||
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.NoArgsConstructor;
 | 
			
		||||
 | 
			
		||||
import com.baomidou.mybatisplus.annotation.TableName;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 用户和岗位实体
 | 
			
		||||
 *
 | 
			
		||||
 * @author Charles7c
 | 
			
		||||
 * @since 2023/2/25 22:28
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
@NoArgsConstructor
 | 
			
		||||
@TableName("sys_user_post")
 | 
			
		||||
public class UserPostDO implements Serializable {
 | 
			
		||||
 | 
			
		||||
    private static final long serialVersionUID = 1L;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 用户 ID
 | 
			
		||||
     */
 | 
			
		||||
    private Long userId;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 岗位 ID
 | 
			
		||||
     */
 | 
			
		||||
    private Long postId;
 | 
			
		||||
 | 
			
		||||
    public UserPostDO(Long userId, Long postId) {
 | 
			
		||||
        this.userId = userId;
 | 
			
		||||
        this.postId = postId;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,55 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package top.charles7c.cnadmin.system.model.query;
 | 
			
		||||
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
 | 
			
		||||
import org.springdoc.api.annotations.ParameterObject;
 | 
			
		||||
 | 
			
		||||
import top.charles7c.cnadmin.common.annotation.Query;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 岗位查询条件
 | 
			
		||||
 *
 | 
			
		||||
 * @author Charles7c
 | 
			
		||||
 * @since 2023/2/25 22:30
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
@ParameterObject
 | 
			
		||||
@Schema(description = "岗位查询条件")
 | 
			
		||||
public class PostQuery implements Serializable {
 | 
			
		||||
 | 
			
		||||
    private static final long serialVersionUID = 1L;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 岗位名称
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "岗位名称")
 | 
			
		||||
    @Query(type = Query.Type.INNER_LIKE)
 | 
			
		||||
    private String postName;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 状态(1启用 2禁用)
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "状态(1启用 2禁用)")
 | 
			
		||||
    @Query
 | 
			
		||||
    private Integer status;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,78 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package top.charles7c.cnadmin.system.model.request;
 | 
			
		||||
 | 
			
		||||
import javax.validation.constraints.NotBlank;
 | 
			
		||||
import javax.validation.constraints.NotNull;
 | 
			
		||||
import javax.validation.constraints.Null;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
 | 
			
		||||
import org.hibernate.validator.constraints.Length;
 | 
			
		||||
 | 
			
		||||
import top.charles7c.cnadmin.common.base.BaseRequest;
 | 
			
		||||
import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 创建或修改岗位信息
 | 
			
		||||
 *
 | 
			
		||||
 * @author Charles7c
 | 
			
		||||
 * @since 2023/2/25 22:31
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
@Schema(description = "创建或修改岗位信息")
 | 
			
		||||
public class PostRequest extends BaseRequest {
 | 
			
		||||
 | 
			
		||||
    private static final long serialVersionUID = 1L;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 岗位 ID
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "岗位 ID")
 | 
			
		||||
    @Null(message = "新增时,ID 必须为空", groups = Create.class)
 | 
			
		||||
    @NotNull(message = "修改时,ID 不能为空", groups = Update.class)
 | 
			
		||||
    private Long postId;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 岗位名称
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "岗位名称")
 | 
			
		||||
    @NotBlank(message = "岗位名称不能为空")
 | 
			
		||||
    private String postName;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 岗位排序
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "岗位排序")
 | 
			
		||||
    @NotNull(message = "岗位排序不能为空")
 | 
			
		||||
    private Integer postSort;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 描述
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "描述")
 | 
			
		||||
    @Length(max = 200, message = "描述长度不能超过 {max} 个字符")
 | 
			
		||||
    private String description;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 状态(1启用 2禁用)
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "状态(1启用 2禁用)", type = "Integer", allowableValues = {"1", "2"})
 | 
			
		||||
    private DisEnableStatusEnum status;
 | 
			
		||||
}
 | 
			
		||||
@@ -107,6 +107,12 @@ public class UserRequest extends BaseRequest {
 | 
			
		||||
    @NotNull(message = "所属部门不能为空")
 | 
			
		||||
    private Long deptId;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 岗位 ID 列表
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "所属岗位")
 | 
			
		||||
    private List<Long> postIds;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 角色 ID 列表
 | 
			
		||||
     */
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,77 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package top.charles7c.cnadmin.system.model.vo;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
 | 
			
		||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
 | 
			
		||||
import com.alibaba.excel.annotation.ExcelProperty;
 | 
			
		||||
 | 
			
		||||
import top.charles7c.cnadmin.common.base.BaseDetailVO;
 | 
			
		||||
import top.charles7c.cnadmin.common.config.easyexcel.ExcelBaseEnumConverter;
 | 
			
		||||
import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 岗位详情信息
 | 
			
		||||
 *
 | 
			
		||||
 * @author Charles7c
 | 
			
		||||
 * @since 2023/2/25 22:35
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
@ExcelIgnoreUnannotated
 | 
			
		||||
@Schema(description = "岗位详情信息")
 | 
			
		||||
public class PostDetailVO extends BaseDetailVO {
 | 
			
		||||
 | 
			
		||||
    private static final long serialVersionUID = 1L;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 岗位 ID
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "岗位 ID")
 | 
			
		||||
    @ExcelProperty(value = "岗位ID")
 | 
			
		||||
    private Long postId;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 岗位名称
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "岗位名称")
 | 
			
		||||
    @ExcelProperty(value = "岗位名称")
 | 
			
		||||
    private String postName;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 岗位排序
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "岗位排序")
 | 
			
		||||
    @ExcelProperty(value = "岗位排序")
 | 
			
		||||
    private Integer postSort;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 状态(1启用 2禁用)
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "状态(1启用 2禁用)")
 | 
			
		||||
    @ExcelProperty(value = "状态", converter = ExcelBaseEnumConverter.class)
 | 
			
		||||
    private DisEnableStatusEnum status;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 描述
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "描述")
 | 
			
		||||
    @ExcelProperty(value = "描述")
 | 
			
		||||
    private String description;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,69 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package top.charles7c.cnadmin.system.model.vo;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.experimental.Accessors;
 | 
			
		||||
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
 | 
			
		||||
import top.charles7c.cnadmin.common.base.BaseVO;
 | 
			
		||||
import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 岗位信息
 | 
			
		||||
 *
 | 
			
		||||
 * @author Charles7c
 | 
			
		||||
 * @since 2023/2/25 22:34
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
@Accessors(chain = true)
 | 
			
		||||
@Schema(description = "岗位信息")
 | 
			
		||||
public class PostVO extends BaseVO {
 | 
			
		||||
 | 
			
		||||
    private static final long serialVersionUID = 1L;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 岗位 ID
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "岗位 ID")
 | 
			
		||||
    private Long postId;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 岗位名称
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "岗位名称")
 | 
			
		||||
    private String postName;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 岗位排序
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "岗位排序")
 | 
			
		||||
    private Integer postSort;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 状态(1启用 2禁用)
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "状态(1启用 2禁用)")
 | 
			
		||||
    private DisEnableStatusEnum status;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 描述
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "描述")
 | 
			
		||||
    private String description;
 | 
			
		||||
}
 | 
			
		||||
@@ -16,6 +16,7 @@
 | 
			
		||||
 | 
			
		||||
package top.charles7c.cnadmin.system.model.vo;
 | 
			
		||||
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
@@ -107,17 +108,10 @@ public class UserDetailVO extends BaseDetailVO {
 | 
			
		||||
    private String description;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 角色 ID 列表
 | 
			
		||||
     * 最后一次修改密码时间
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "角色 ID 列表")
 | 
			
		||||
    private List<Long> roleIds;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 所属角色
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "所属角色")
 | 
			
		||||
    @ExcelProperty(value = "所属角色")
 | 
			
		||||
    private String roleNames;
 | 
			
		||||
    @Schema(description = "最后一次修改密码时间")
 | 
			
		||||
    private LocalDateTime pwdResetTime;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 部门 ID
 | 
			
		||||
@@ -131,4 +125,30 @@ public class UserDetailVO extends BaseDetailVO {
 | 
			
		||||
    @Schema(description = "所属部门")
 | 
			
		||||
    @ExcelProperty(value = "所属部门")
 | 
			
		||||
    private String deptName;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 岗位 ID 列表
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "岗位 ID 列表")
 | 
			
		||||
    private List<Long> postIds;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 所属岗位
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "所属岗位")
 | 
			
		||||
    @ExcelProperty(value = "所属岗位")
 | 
			
		||||
    private String postNames;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 角色 ID 列表
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "角色 ID 列表")
 | 
			
		||||
    private List<Long> roleIds;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 所属角色
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "所属角色")
 | 
			
		||||
    @ExcelProperty(value = "所属角色")
 | 
			
		||||
    private String roleNames;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,53 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package top.charles7c.cnadmin.system.service;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import top.charles7c.cnadmin.common.base.BaseService;
 | 
			
		||||
import top.charles7c.cnadmin.common.model.vo.LabelValueVO;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.query.PostQuery;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.request.PostRequest;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.vo.PostDetailVO;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.vo.PostVO;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 岗位业务接口
 | 
			
		||||
 *
 | 
			
		||||
 * @author Charles7c
 | 
			
		||||
 * @since 2023/2/25 22:38
 | 
			
		||||
 */
 | 
			
		||||
public interface PostService extends BaseService<PostVO, PostDetailVO, PostQuery, PostRequest> {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 构建字典
 | 
			
		||||
     *
 | 
			
		||||
     * @param list
 | 
			
		||||
     *            原始列表数据
 | 
			
		||||
     * @return 字典列表
 | 
			
		||||
     */
 | 
			
		||||
    List<LabelValueVO<Long>> buildDict(List<PostVO> list);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 根据岗位 ID 列表查询
 | 
			
		||||
     *
 | 
			
		||||
     * @param postIds
 | 
			
		||||
     *            岗位 ID 列表
 | 
			
		||||
     * @return 岗位名称列表
 | 
			
		||||
     */
 | 
			
		||||
    List<String> listPostNamesByPostIds(List<Long> postIds);
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,56 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package top.charles7c.cnadmin.system.service;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 用户和岗位业务接口
 | 
			
		||||
 *
 | 
			
		||||
 * @author Charles7c
 | 
			
		||||
 * @since 2023/2/25 22:40
 | 
			
		||||
 */
 | 
			
		||||
public interface UserPostService {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 保存
 | 
			
		||||
     *
 | 
			
		||||
     * @param postIds
 | 
			
		||||
     *            岗位 ID 列表
 | 
			
		||||
     * @param userId
 | 
			
		||||
     *            用户 ID
 | 
			
		||||
     */
 | 
			
		||||
    void save(List<Long> postIds, Long userId);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 根据岗位 ID 列表查询
 | 
			
		||||
     *
 | 
			
		||||
     * @param postIds
 | 
			
		||||
     *            岗位 ID 列表
 | 
			
		||||
     * @return 总记录数
 | 
			
		||||
     */
 | 
			
		||||
    Long countByPostIds(List<Long> postIds);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 根据用户 ID 查询
 | 
			
		||||
     *
 | 
			
		||||
     * @param userId
 | 
			
		||||
     *            用户 ID
 | 
			
		||||
     * @return 岗位 ID 列表
 | 
			
		||||
     */
 | 
			
		||||
    List<Long> listPostIdsByUserId(Long userId);
 | 
			
		||||
}
 | 
			
		||||
@@ -106,13 +106,4 @@ public interface UserService extends BaseService<UserVO, UserDetailVO, UserQuery
 | 
			
		||||
     * @return 用户数量
 | 
			
		||||
     */
 | 
			
		||||
    Long countByDeptIds(List<Long> deptIds);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 根据角色 ID 列表查询
 | 
			
		||||
     *
 | 
			
		||||
     * @param roleIds
 | 
			
		||||
     *            角色 ID 列表
 | 
			
		||||
     * @return 用户数量
 | 
			
		||||
     */
 | 
			
		||||
    Long countByRoleIds(List<Long> roleIds);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,113 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package top.charles7c.cnadmin.system.service.impl;
 | 
			
		||||
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
import lombok.RequiredArgsConstructor;
 | 
			
		||||
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.springframework.transaction.annotation.Transactional;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.collection.CollUtil;
 | 
			
		||||
 | 
			
		||||
import top.charles7c.cnadmin.common.base.BaseServiceImpl;
 | 
			
		||||
import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum;
 | 
			
		||||
import top.charles7c.cnadmin.common.model.vo.LabelValueVO;
 | 
			
		||||
import top.charles7c.cnadmin.common.util.validate.CheckUtils;
 | 
			
		||||
import top.charles7c.cnadmin.system.mapper.PostMapper;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.entity.PostDO;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.query.PostQuery;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.request.PostRequest;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.vo.*;
 | 
			
		||||
import top.charles7c.cnadmin.system.service.*;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 岗位业务实现类
 | 
			
		||||
 *
 | 
			
		||||
 * @author Charles7c
 | 
			
		||||
 * @since 2023/2/25 22:38
 | 
			
		||||
 */
 | 
			
		||||
@Service
 | 
			
		||||
@RequiredArgsConstructor
 | 
			
		||||
public class PostServiceImpl extends BaseServiceImpl<PostMapper, PostDO, PostVO, PostDetailVO, PostQuery, PostRequest>
 | 
			
		||||
    implements PostService {
 | 
			
		||||
 | 
			
		||||
    private final UserPostService userPostService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @Transactional(rollbackFor = Exception.class)
 | 
			
		||||
    public Long add(PostRequest request) {
 | 
			
		||||
        String postName = request.getPostName();
 | 
			
		||||
        boolean isExists = this.checkNameExists(postName, request.getPostId());
 | 
			
		||||
        CheckUtils.throwIf(() -> isExists, String.format("新增失败,'%s'已存在", postName));
 | 
			
		||||
 | 
			
		||||
        // 新增岗位
 | 
			
		||||
        request.setStatus(DisEnableStatusEnum.ENABLE);
 | 
			
		||||
        return super.add(request);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @Transactional(rollbackFor = Exception.class)
 | 
			
		||||
    public void update(PostRequest request) {
 | 
			
		||||
        String postName = request.getPostName();
 | 
			
		||||
        boolean isExists = this.checkNameExists(postName, request.getPostId());
 | 
			
		||||
        CheckUtils.throwIf(() -> isExists, String.format("修改失败,'%s'已存在", postName));
 | 
			
		||||
 | 
			
		||||
        // 更新岗位
 | 
			
		||||
        super.update(request);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @Transactional(rollbackFor = Exception.class)
 | 
			
		||||
    public void delete(List<Long> ids) {
 | 
			
		||||
        CheckUtils.throwIf(() -> userPostService.countByPostIds(ids) > 0, "所选岗位存在用户关联,请解除关联后重试");
 | 
			
		||||
        super.delete(ids);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 检查名称是否存在
 | 
			
		||||
     *
 | 
			
		||||
     * @param name
 | 
			
		||||
     *            名称
 | 
			
		||||
     * @param id
 | 
			
		||||
     *            ID
 | 
			
		||||
     * @return 是否存在
 | 
			
		||||
     */
 | 
			
		||||
    private boolean checkNameExists(String name, Long id) {
 | 
			
		||||
        return super.lambdaQuery().eq(PostDO::getPostName, name).ne(id != null, PostDO::getPostId, id).exists();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<LabelValueVO<Long>> buildDict(List<PostVO> list) {
 | 
			
		||||
        if (CollUtil.isEmpty(list)) {
 | 
			
		||||
            return Collections.emptyList();
 | 
			
		||||
        }
 | 
			
		||||
        return list.stream().map(p -> new LabelValueVO<>(p.getPostName(), p.getPostId())).collect(Collectors.toList());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<String> listPostNamesByPostIds(List<Long> postIds) {
 | 
			
		||||
        List<PostDO> postList = super.lambdaQuery().select(PostDO::getPostName).in(PostDO::getPostId, postIds).list();
 | 
			
		||||
        if (CollUtil.isEmpty(postList)) {
 | 
			
		||||
            return Collections.emptyList();
 | 
			
		||||
        }
 | 
			
		||||
        return postList.stream().map(PostDO::getPostName).collect(Collectors.toList());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -20,8 +20,6 @@ import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
 | 
			
		||||
import lombok.RequiredArgsConstructor;
 | 
			
		||||
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
@@ -57,15 +55,14 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleVO,
 | 
			
		||||
    private final RoleMenuService roleMenuService;
 | 
			
		||||
    private final RoleDeptService roleDeptService;
 | 
			
		||||
    private final MenuService menuService;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private UserService userService;
 | 
			
		||||
    private final UserRoleService userRoleService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @Transactional(rollbackFor = Exception.class)
 | 
			
		||||
    public Long add(RoleRequest request) {
 | 
			
		||||
        String roleName = request.getRoleName();
 | 
			
		||||
        boolean isExist = this.checkNameExists(roleName, request.getRoleId());
 | 
			
		||||
        CheckUtils.throwIf(() -> isExist, String.format("新增失败,'%s'已存在", roleName));
 | 
			
		||||
        boolean isExists = this.checkNameExists(roleName, request.getRoleId());
 | 
			
		||||
        CheckUtils.throwIf(() -> isExists, String.format("新增失败,'%s'已存在", roleName));
 | 
			
		||||
 | 
			
		||||
        // 新增角色
 | 
			
		||||
        request.setStatus(DisEnableStatusEnum.ENABLE);
 | 
			
		||||
@@ -81,8 +78,8 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleVO,
 | 
			
		||||
    @Transactional(rollbackFor = Exception.class)
 | 
			
		||||
    public void update(RoleRequest request) {
 | 
			
		||||
        String roleName = request.getRoleName();
 | 
			
		||||
        boolean isExist = this.checkNameExists(roleName, request.getRoleId());
 | 
			
		||||
        CheckUtils.throwIf(() -> isExist, String.format("修改失败,'%s'已存在", roleName));
 | 
			
		||||
        boolean isExists = this.checkNameExists(roleName, request.getRoleId());
 | 
			
		||||
        CheckUtils.throwIf(() -> isExists, String.format("修改失败,'%s'已存在", roleName));
 | 
			
		||||
 | 
			
		||||
        // 更新角色
 | 
			
		||||
        super.update(request);
 | 
			
		||||
@@ -96,7 +93,7 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleVO,
 | 
			
		||||
    @Override
 | 
			
		||||
    @Transactional(rollbackFor = Exception.class)
 | 
			
		||||
    public void delete(List<Long> ids) {
 | 
			
		||||
        CheckUtils.throwIf(() -> userService.countByRoleIds(ids) > 0, "所选角色存在用户关联,请解除关联后重试");
 | 
			
		||||
        CheckUtils.throwIf(() -> userRoleService.countByRoleIds(ids) > 0, "所选角色存在用户关联,请解除关联后重试");
 | 
			
		||||
        super.delete(ids);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,74 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package top.charles7c.cnadmin.system.service.impl;
 | 
			
		||||
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
import lombok.RequiredArgsConstructor;
 | 
			
		||||
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
 | 
			
		||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.collection.CollUtil;
 | 
			
		||||
 | 
			
		||||
import top.charles7c.cnadmin.system.mapper.UserPostMapper;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.entity.UserPostDO;
 | 
			
		||||
import top.charles7c.cnadmin.system.service.UserPostService;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 用户和岗位业务实现类
 | 
			
		||||
 *
 | 
			
		||||
 * @author Charles7c
 | 
			
		||||
 * @since 2023/2/25 22:40
 | 
			
		||||
 */
 | 
			
		||||
@Service
 | 
			
		||||
@RequiredArgsConstructor
 | 
			
		||||
public class UserPostServiceImpl implements UserPostService {
 | 
			
		||||
 | 
			
		||||
    private final UserPostMapper userPostMapper;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void save(List<Long> postIds, Long userId) {
 | 
			
		||||
        if (CollUtil.isEmpty(postIds)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        // 删除原有关联
 | 
			
		||||
        userPostMapper.delete(Wrappers.<UserPostDO>lambdaQuery().eq(UserPostDO::getUserId, userId));
 | 
			
		||||
        // 保存最新关联
 | 
			
		||||
        List<UserPostDO> userPostList =
 | 
			
		||||
            postIds.stream().map(postId -> new UserPostDO(userId, postId)).collect(Collectors.toList());
 | 
			
		||||
        userPostMapper.insertBatch(userPostList);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Long countByPostIds(List<Long> postIds) {
 | 
			
		||||
        return userPostMapper.selectCount(Wrappers.<UserPostDO>lambdaQuery().in(UserPostDO::getPostId, postIds));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<Long> listPostIdsByUserId(Long userId) {
 | 
			
		||||
        List<UserPostDO> userPostList = userPostMapper.selectList(
 | 
			
		||||
            Wrappers.<UserPostDO>lambdaQuery().select(UserPostDO::getPostId).eq(UserPostDO::getUserId, userId));
 | 
			
		||||
        if (CollUtil.isEmpty(userPostList)) {
 | 
			
		||||
            return Collections.emptyList();
 | 
			
		||||
        }
 | 
			
		||||
        return userPostList.stream().map(UserPostDO::getPostId).collect(Collectors.toList());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -51,10 +51,7 @@ import top.charles7c.cnadmin.system.model.request.UpdateUserRoleRequest;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.request.UserRequest;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.vo.UserDetailVO;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.vo.UserVO;
 | 
			
		||||
import top.charles7c.cnadmin.system.service.DeptService;
 | 
			
		||||
import top.charles7c.cnadmin.system.service.RoleService;
 | 
			
		||||
import top.charles7c.cnadmin.system.service.UserRoleService;
 | 
			
		||||
import top.charles7c.cnadmin.system.service.UserService;
 | 
			
		||||
import top.charles7c.cnadmin.system.service.*;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 用户业务实现类
 | 
			
		||||
@@ -67,19 +64,20 @@ import top.charles7c.cnadmin.system.service.UserService;
 | 
			
		||||
public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO, UserDetailVO, UserQuery, UserRequest>
 | 
			
		||||
    implements UserService, CommonUserService {
 | 
			
		||||
 | 
			
		||||
    private final UserPostService userPostService;
 | 
			
		||||
    private final PostService postService;
 | 
			
		||||
    private final UserRoleService userRoleService;
 | 
			
		||||
    private final RoleService roleService;
 | 
			
		||||
    private final LocalStorageProperties localStorageProperties;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private RoleService roleService;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private DeptService deptService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @Transactional(rollbackFor = Exception.class)
 | 
			
		||||
    public Long add(UserRequest request) {
 | 
			
		||||
        String username = request.getUsername();
 | 
			
		||||
        boolean isExist = this.checkNameExists(username, request.getUserId());
 | 
			
		||||
        CheckUtils.throwIf(() -> isExist, String.format("新增失败,'%s'已存在", username));
 | 
			
		||||
        boolean isExists = this.checkNameExists(username, request.getUserId());
 | 
			
		||||
        CheckUtils.throwIf(() -> isExists, String.format("新增失败,'%s'已存在", username));
 | 
			
		||||
 | 
			
		||||
        // 新增用户
 | 
			
		||||
        request.setStatus(DisEnableStatusEnum.ENABLE);
 | 
			
		||||
@@ -87,6 +85,8 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO,
 | 
			
		||||
        super.lambdaUpdate()
 | 
			
		||||
            .set(UserDO::getPassword, SecureUtils.md5Salt(Constants.DEFAULT_PASSWORD, userId.toString()))
 | 
			
		||||
            .set(UserDO::getPwdResetTime, LocalDateTime.now()).eq(UserDO::getUserId, userId).update();
 | 
			
		||||
        // 保存用户和岗位关联
 | 
			
		||||
        userPostService.save(request.getPostIds(), userId);
 | 
			
		||||
        // 保存用户和角色关联
 | 
			
		||||
        userRoleService.save(request.getRoleIds(), userId);
 | 
			
		||||
        return userId;
 | 
			
		||||
@@ -96,12 +96,14 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO,
 | 
			
		||||
    @Transactional(rollbackFor = Exception.class)
 | 
			
		||||
    public void update(UserRequest request) {
 | 
			
		||||
        String username = request.getUsername();
 | 
			
		||||
        boolean isExist = this.checkNameExists(username, request.getUserId());
 | 
			
		||||
        CheckUtils.throwIf(() -> isExist, String.format("修改失败,'%s'已存在", username));
 | 
			
		||||
        boolean isExists = this.checkNameExists(username, request.getUserId());
 | 
			
		||||
        CheckUtils.throwIf(() -> isExists, String.format("修改失败,'%s'已存在", username));
 | 
			
		||||
 | 
			
		||||
        // 更新用户
 | 
			
		||||
        super.update(request);
 | 
			
		||||
        Long userId = request.getUserId();
 | 
			
		||||
        // 保存用户和岗位关联
 | 
			
		||||
        userPostService.save(request.getPostIds(), userId);
 | 
			
		||||
        // 保存用户和角色关联
 | 
			
		||||
        userRoleService.save(request.getRoleIds(), userId);
 | 
			
		||||
    }
 | 
			
		||||
@@ -128,6 +130,9 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO,
 | 
			
		||||
            List<Long> roleIds = userRoleService.listRoleIdsByUserId(detailVO.getUserId());
 | 
			
		||||
            detailVO.setRoleIds(roleIds);
 | 
			
		||||
            detailVO.setRoleNames(String.join(",", roleService.listRoleNamesByRoleIds(roleIds)));
 | 
			
		||||
            List<Long> postIds = userPostService.listPostIdsByUserId(detailVO.getUserId());
 | 
			
		||||
            detailVO.setPostIds(postIds);
 | 
			
		||||
            detailVO.setPostNames(String.join(",", postService.listPostNamesByPostIds(postIds)));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -227,11 +232,6 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO,
 | 
			
		||||
        return super.lambdaQuery().in(UserDO::getDeptId, deptIds).count();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Long countByRoleIds(List<Long> roleIds) {
 | 
			
		||||
        return userRoleService.countByRoleIds(roleIds);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getNicknameById(Long userId) {
 | 
			
		||||
        return super.getById(userId).getNickname();
 | 
			
		||||
 
 | 
			
		||||
@@ -3,8 +3,14 @@ import qs from 'query-string';
 | 
			
		||||
import { DeptParam } from '@/api/system/dept';
 | 
			
		||||
import { MenuParam } from '@/api/system/menu';
 | 
			
		||||
import { RoleParam } from '@/api/system/role';
 | 
			
		||||
import { PostParam } from '@/api/system/post';
 | 
			
		||||
import { TreeNodeData } from '@arco-design/web-vue';
 | 
			
		||||
 | 
			
		||||
export interface LabelValueRecord {
 | 
			
		||||
  label: string;
 | 
			
		||||
  value: any;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function listDeptTree(params: DeptParam) {
 | 
			
		||||
  return axios.get<TreeNodeData[]>('/common/tree/dept', {
 | 
			
		||||
    params,
 | 
			
		||||
@@ -24,7 +30,16 @@ export function listMenuTree(params: MenuParam) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function listRoleDict(params: RoleParam) {
 | 
			
		||||
  return axios.get<TreeNodeData[]>('/common/dict/role', {
 | 
			
		||||
  return axios.get<LabelValueRecord[]>('/common/dict/role', {
 | 
			
		||||
    params,
 | 
			
		||||
    paramsSerializer: (obj) => {
 | 
			
		||||
      return qs.stringify(obj);
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function listPostDict(params: PostParam) {
 | 
			
		||||
  return axios.get<LabelValueRecord[]>('/common/dict/post', {
 | 
			
		||||
    params,
 | 
			
		||||
    paramsSerializer: (obj) => {
 | 
			
		||||
      return qs.stringify(obj);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										54
									
								
								continew-admin-ui/src/api/system/post.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								continew-admin-ui/src/api/system/post.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
import axios from 'axios';
 | 
			
		||||
import qs from 'query-string';
 | 
			
		||||
 | 
			
		||||
const BASE_URL = '/system/post';
 | 
			
		||||
 | 
			
		||||
export interface PostRecord {
 | 
			
		||||
  postId?: number;
 | 
			
		||||
  postName: string;
 | 
			
		||||
  postSort?: number;
 | 
			
		||||
  description?: string;
 | 
			
		||||
  status?: number;
 | 
			
		||||
  createUserString?: string;
 | 
			
		||||
  createTime?: string;
 | 
			
		||||
  updateUserString?: string;
 | 
			
		||||
  updateTime?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface PostParam {
 | 
			
		||||
  postName?: string;
 | 
			
		||||
  status?: number;
 | 
			
		||||
  page?: number;
 | 
			
		||||
  size?: number;
 | 
			
		||||
  sort?: Array<string>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface PostListRes {
 | 
			
		||||
  list: PostRecord[];
 | 
			
		||||
  total: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function listPost(params: PostParam) {
 | 
			
		||||
  return axios.get<PostListRes>(`${BASE_URL}`, {
 | 
			
		||||
    params,
 | 
			
		||||
    paramsSerializer: (obj) => {
 | 
			
		||||
      return qs.stringify(obj);
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getPost(id: number) {
 | 
			
		||||
  return axios.get<PostRecord>(`${BASE_URL}/${id}`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function addPost(req: PostRecord) {
 | 
			
		||||
  return axios.post(BASE_URL, req);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function updatePost(req: PostRecord) {
 | 
			
		||||
  return axios.put(BASE_URL, req);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function deletePost(ids: number | Array<number>) {
 | 
			
		||||
  return axios.delete(`${BASE_URL}/${ids}`);
 | 
			
		||||
}
 | 
			
		||||
@@ -11,14 +11,17 @@ export interface UserRecord {
 | 
			
		||||
  email?: string;
 | 
			
		||||
  phone?: string;
 | 
			
		||||
  description?: string;
 | 
			
		||||
  roleIds?: Array<number>;
 | 
			
		||||
  deptId?: number;
 | 
			
		||||
  status?: number;
 | 
			
		||||
  pwdResetTime?: string;
 | 
			
		||||
  createUserString?: string;
 | 
			
		||||
  createTime?: string;
 | 
			
		||||
  updateUserString?: string;
 | 
			
		||||
  updateTime?: string;
 | 
			
		||||
  deptId?: number;
 | 
			
		||||
  deptName?: string;
 | 
			
		||||
  postIds?: Array<number>;
 | 
			
		||||
  postNames?: Array<string>;
 | 
			
		||||
  roleIds?: Array<number>;
 | 
			
		||||
  roleNames?: Array<string>;
 | 
			
		||||
  disabled?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import localeUser from '@/views/system/user/locale/en-US';
 | 
			
		||||
import localeRole from '@/views/system/role/locale/en-US';
 | 
			
		||||
import localeMenu from '@/views/system/menu/locale/en-US';
 | 
			
		||||
import localeDept from '@/views/system/dept/locale/en-US';
 | 
			
		||||
import localePost from '@/views/system/post/locale/en-US';
 | 
			
		||||
 | 
			
		||||
import localeOnlineUser from '@/views/monitor/online/locale/en-US';
 | 
			
		||||
import localeLoginLog from '@/views/monitor/log/login/locale/en-US';
 | 
			
		||||
@@ -55,6 +56,7 @@ export default {
 | 
			
		||||
  ...localeRole,
 | 
			
		||||
  ...localeMenu,
 | 
			
		||||
  ...localeDept,
 | 
			
		||||
  ...localePost,
 | 
			
		||||
 | 
			
		||||
  ...localeOnlineUser,
 | 
			
		||||
  ...localeLoginLog,
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import localeUser from '@/views/system/user/locale/zh-CN';
 | 
			
		||||
import localeRole from '@/views/system/role/locale/zh-CN';
 | 
			
		||||
import localeMenu from '@/views/system/menu/locale/zh-CN';
 | 
			
		||||
import localeDept from '@/views/system/dept/locale/zh-CN';
 | 
			
		||||
import localePost from '@/views/system/post/locale/zh-CN';
 | 
			
		||||
 | 
			
		||||
import localeOnlineUser from '@/views/monitor/online/locale/zh-CN';
 | 
			
		||||
import localeLoginLog from '@/views/monitor/log/login/locale/zh-CN';
 | 
			
		||||
@@ -55,6 +56,7 @@ export default {
 | 
			
		||||
  ...localeRole,
 | 
			
		||||
  ...localeMenu,
 | 
			
		||||
  ...localeDept,
 | 
			
		||||
  ...localePost,
 | 
			
		||||
 | 
			
		||||
  ...localeOnlineUser,
 | 
			
		||||
  ...localeLoginLog,
 | 
			
		||||
 
 | 
			
		||||
@@ -52,6 +52,16 @@ const System: AppRouteRecordRaw = {
 | 
			
		||||
        roles: ['*'],
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      path: '/system/post',
 | 
			
		||||
      name: 'Post',
 | 
			
		||||
      component: () => import('@/views/system/post/index.vue'),
 | 
			
		||||
      meta: {
 | 
			
		||||
        locale: 'menu.system.post.list',
 | 
			
		||||
        requiresAuth: true,
 | 
			
		||||
        roles: ['*'],
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  ],
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -216,7 +216,7 @@
 | 
			
		||||
        render-to-body
 | 
			
		||||
        @cancel="handleDetailCancel"
 | 
			
		||||
      >
 | 
			
		||||
        <a-descriptions title="基础信息" :column="2" bordered size="large">
 | 
			
		||||
        <a-descriptions :column="2" bordered size="large" layout="vertical">
 | 
			
		||||
          <a-descriptions-item label="部门名称">
 | 
			
		||||
            <a-skeleton v-if="detailLoading" :animation="true">
 | 
			
		||||
              <a-skeleton-line :rows="1" />
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										552
									
								
								continew-admin-ui/src/views/system/post/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										552
									
								
								continew-admin-ui/src/views/system/post/index.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,552 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="app-container">
 | 
			
		||||
    <Breadcrumb :items="['menu.system', 'menu.system.post.list']" />
 | 
			
		||||
    <a-card class="general-card" :title="$t('menu.system.post.list')">
 | 
			
		||||
      <!-- 头部区域 -->
 | 
			
		||||
      <div class="header">
 | 
			
		||||
        <!-- 搜索栏 -->
 | 
			
		||||
        <div v-if="showQuery" class="header-query">
 | 
			
		||||
          <a-form ref="queryRef" :model="queryParams" layout="inline">
 | 
			
		||||
            <a-form-item field="postName" hide-label>
 | 
			
		||||
              <a-input
 | 
			
		||||
                v-model="queryParams.postName"
 | 
			
		||||
                placeholder="输入岗位名称搜索"
 | 
			
		||||
                allow-clear
 | 
			
		||||
                style="width: 150px"
 | 
			
		||||
                @press-enter="handleQuery"
 | 
			
		||||
              />
 | 
			
		||||
            </a-form-item>
 | 
			
		||||
            <a-form-item field="status" hide-label>
 | 
			
		||||
              <a-select
 | 
			
		||||
                v-model="queryParams.status"
 | 
			
		||||
                :options="statusOptions"
 | 
			
		||||
                placeholder="状态搜索"
 | 
			
		||||
                allow-clear
 | 
			
		||||
                style="width: 150px"
 | 
			
		||||
              />
 | 
			
		||||
            </a-form-item>
 | 
			
		||||
            <a-form-item hide-label>
 | 
			
		||||
              <a-space>
 | 
			
		||||
                <a-button type="primary" @click="handleQuery">
 | 
			
		||||
                  <template #icon><icon-search /></template>查询
 | 
			
		||||
                </a-button>
 | 
			
		||||
                <a-button @click="resetQuery">
 | 
			
		||||
                  <template #icon><icon-refresh /></template>重置
 | 
			
		||||
                </a-button>
 | 
			
		||||
              </a-space>
 | 
			
		||||
            </a-form-item>
 | 
			
		||||
          </a-form>
 | 
			
		||||
        </div>
 | 
			
		||||
        <!-- 操作栏 -->
 | 
			
		||||
        <div class="header-operation">
 | 
			
		||||
          <a-row>
 | 
			
		||||
            <a-col :span="12">
 | 
			
		||||
              <a-space>
 | 
			
		||||
                <a-button type="primary" @click="toCreate">
 | 
			
		||||
                  <template #icon><icon-plus /></template>新增
 | 
			
		||||
                </a-button>
 | 
			
		||||
                <a-button
 | 
			
		||||
                  type="primary"
 | 
			
		||||
                  status="success"
 | 
			
		||||
                  :disabled="single"
 | 
			
		||||
                  :title="single ? '请选择一条要修改的数据' : ''"
 | 
			
		||||
                  @click="toUpdate(ids[0])"
 | 
			
		||||
                >
 | 
			
		||||
                  <template #icon><icon-edit /></template>修改
 | 
			
		||||
                </a-button>
 | 
			
		||||
                <a-button
 | 
			
		||||
                  type="primary"
 | 
			
		||||
                  status="danger"
 | 
			
		||||
                  :disabled="multiple"
 | 
			
		||||
                  :title="multiple ? '请选择要删除的数据' : ''"
 | 
			
		||||
                  @click="handleBatchDelete"
 | 
			
		||||
                >
 | 
			
		||||
                  <template #icon><icon-delete /></template>删除
 | 
			
		||||
                </a-button>
 | 
			
		||||
                <a-button
 | 
			
		||||
                  :loading="exportLoading"
 | 
			
		||||
                  type="primary"
 | 
			
		||||
                  status="warning"
 | 
			
		||||
                  @click="handleExport"
 | 
			
		||||
                >
 | 
			
		||||
                  <template #icon><icon-download /></template>导出
 | 
			
		||||
                </a-button>
 | 
			
		||||
              </a-space>
 | 
			
		||||
            </a-col>
 | 
			
		||||
            <a-col :span="12">
 | 
			
		||||
              <right-toolbar
 | 
			
		||||
                v-model:show-query="showQuery"
 | 
			
		||||
                @refresh="getList"
 | 
			
		||||
              />
 | 
			
		||||
            </a-col>
 | 
			
		||||
          </a-row>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <!-- 列表区域 -->
 | 
			
		||||
      <a-table
 | 
			
		||||
        ref="tableRef"
 | 
			
		||||
        :data="postList"
 | 
			
		||||
        :row-selection="{
 | 
			
		||||
          type: 'checkbox',
 | 
			
		||||
          showCheckedAll: true,
 | 
			
		||||
          onlyCurrent: false,
 | 
			
		||||
        }"
 | 
			
		||||
        :pagination="{
 | 
			
		||||
          showTotal: true,
 | 
			
		||||
          showPageSize: true,
 | 
			
		||||
          total: total,
 | 
			
		||||
          current: queryParams.page,
 | 
			
		||||
        }"
 | 
			
		||||
        row-key="postId"
 | 
			
		||||
        :bordered="false"
 | 
			
		||||
        :stripe="true"
 | 
			
		||||
        :loading="loading"
 | 
			
		||||
        size="large"
 | 
			
		||||
        @page-change="handlePageChange"
 | 
			
		||||
        @page-size-change="handlePageSizeChange"
 | 
			
		||||
        @selection-change="handleSelectionChange"
 | 
			
		||||
      >
 | 
			
		||||
        <template #columns>
 | 
			
		||||
          <a-table-column title="ID" data-index="postId" />
 | 
			
		||||
          <a-table-column title="岗位名称">
 | 
			
		||||
            <template #cell="{ record }">
 | 
			
		||||
              <a-link @click="toDetail(record.postId)">{{
 | 
			
		||||
                record.postName
 | 
			
		||||
              }}</a-link>
 | 
			
		||||
            </template>
 | 
			
		||||
          </a-table-column>
 | 
			
		||||
          <a-table-column
 | 
			
		||||
            title="岗位排序"
 | 
			
		||||
            align="center"
 | 
			
		||||
            data-index="postSort"
 | 
			
		||||
          />
 | 
			
		||||
          <a-table-column title="状态" align="center" data-index="status">
 | 
			
		||||
            <template #cell="{ record }">
 | 
			
		||||
              <a-switch
 | 
			
		||||
                v-model="record.status"
 | 
			
		||||
                :checked-value="1"
 | 
			
		||||
                :unchecked-value="2"
 | 
			
		||||
                :disabled="record.disabled"
 | 
			
		||||
                @change="handleChangeStatus(record)"
 | 
			
		||||
              />
 | 
			
		||||
            </template>
 | 
			
		||||
          </a-table-column>
 | 
			
		||||
          <a-table-column title="描述" data-index="description" />
 | 
			
		||||
          <a-table-column title="创建人" data-index="createUserString" />
 | 
			
		||||
          <a-table-column title="创建时间" data-index="createTime" />
 | 
			
		||||
          <a-table-column title="操作" align="center">
 | 
			
		||||
            <template #cell="{ record }">
 | 
			
		||||
              <a-button
 | 
			
		||||
                v-permission="['admin']"
 | 
			
		||||
                type="text"
 | 
			
		||||
                size="small"
 | 
			
		||||
                title="修改"
 | 
			
		||||
                :disabled="record.disabled"
 | 
			
		||||
                @click="toUpdate(record.postId)"
 | 
			
		||||
              >
 | 
			
		||||
                <template #icon><icon-edit /></template>修改
 | 
			
		||||
              </a-button>
 | 
			
		||||
              <a-popconfirm
 | 
			
		||||
                content="确定要删除当前选中的数据吗?"
 | 
			
		||||
                type="warning"
 | 
			
		||||
                @ok="handleDelete([record.postId])"
 | 
			
		||||
              >
 | 
			
		||||
                <a-button
 | 
			
		||||
                  v-permission="['admin']"
 | 
			
		||||
                  type="text"
 | 
			
		||||
                  size="small"
 | 
			
		||||
                  title="删除"
 | 
			
		||||
                  :disabled="record.disabled"
 | 
			
		||||
                >
 | 
			
		||||
                  <template #icon><icon-delete /></template>删除
 | 
			
		||||
                </a-button>
 | 
			
		||||
              </a-popconfirm>
 | 
			
		||||
            </template>
 | 
			
		||||
          </a-table-column>
 | 
			
		||||
        </template>
 | 
			
		||||
      </a-table>
 | 
			
		||||
 | 
			
		||||
      <!-- 表单区域 -->
 | 
			
		||||
      <a-modal
 | 
			
		||||
        :title="title"
 | 
			
		||||
        :visible="visible"
 | 
			
		||||
        :mask-closable="false"
 | 
			
		||||
        unmount-on-close
 | 
			
		||||
        render-to-body
 | 
			
		||||
        @ok="handleOk"
 | 
			
		||||
        @cancel="handleCancel"
 | 
			
		||||
      >
 | 
			
		||||
        <a-form ref="formRef" :model="form" :rules="rules" size="large">
 | 
			
		||||
          <a-form-item label="岗位名称" field="postName">
 | 
			
		||||
            <a-input v-model="form.postName" placeholder="请输入岗位名称" />
 | 
			
		||||
          </a-form-item>
 | 
			
		||||
          <a-form-item label="岗位排序" field="postSort">
 | 
			
		||||
            <a-input-number
 | 
			
		||||
              v-model="form.postSort"
 | 
			
		||||
              placeholder="请输入岗位排序"
 | 
			
		||||
              :min="1"
 | 
			
		||||
              mode="button"
 | 
			
		||||
            />
 | 
			
		||||
          </a-form-item>
 | 
			
		||||
          <a-form-item label="描述" field="description">
 | 
			
		||||
            <a-textarea
 | 
			
		||||
              v-model="form.description"
 | 
			
		||||
              :max-length="200"
 | 
			
		||||
              placeholder="请输入描述"
 | 
			
		||||
              :auto-size="{
 | 
			
		||||
                minRows: 3,
 | 
			
		||||
              }"
 | 
			
		||||
              show-word-limit
 | 
			
		||||
            />
 | 
			
		||||
          </a-form-item>
 | 
			
		||||
        </a-form>
 | 
			
		||||
      </a-modal>
 | 
			
		||||
 | 
			
		||||
      <!-- 详情区域 -->
 | 
			
		||||
      <a-drawer
 | 
			
		||||
        title="岗位详情"
 | 
			
		||||
        :visible="detailVisible"
 | 
			
		||||
        :width="580"
 | 
			
		||||
        :footer="false"
 | 
			
		||||
        unmount-on-close
 | 
			
		||||
        render-to-body
 | 
			
		||||
        @cancel="handleDetailCancel"
 | 
			
		||||
      >
 | 
			
		||||
        <a-descriptions :column="2" bordered size="large" layout="vertical">
 | 
			
		||||
          <a-descriptions-item label="岗位名称">
 | 
			
		||||
            <a-skeleton v-if="detailLoading" :animation="true">
 | 
			
		||||
              <a-skeleton-line :rows="1" />
 | 
			
		||||
            </a-skeleton>
 | 
			
		||||
            <span v-else>{{ post.postName }}</span>
 | 
			
		||||
          </a-descriptions-item>
 | 
			
		||||
          <a-descriptions-item label="状态">
 | 
			
		||||
            <a-skeleton v-if="detailLoading" :animation="true">
 | 
			
		||||
              <a-skeleton-line :rows="1" />
 | 
			
		||||
            </a-skeleton>
 | 
			
		||||
            <span v-else>
 | 
			
		||||
              <a-tag v-if="post.status === 1" color="green">启用</a-tag>
 | 
			
		||||
              <a-tag v-else color="red">禁用</a-tag>
 | 
			
		||||
            </span>
 | 
			
		||||
          </a-descriptions-item>
 | 
			
		||||
          <a-descriptions-item label="创建人">
 | 
			
		||||
            <a-skeleton v-if="detailLoading" :animation="true">
 | 
			
		||||
              <a-skeleton-line :rows="1" />
 | 
			
		||||
            </a-skeleton>
 | 
			
		||||
            <span v-else>{{ post.createUserString }}</span>
 | 
			
		||||
          </a-descriptions-item>
 | 
			
		||||
          <a-descriptions-item label="创建时间">
 | 
			
		||||
            <a-skeleton v-if="detailLoading" :animation="true">
 | 
			
		||||
              <a-skeleton-line :rows="1" />
 | 
			
		||||
            </a-skeleton>
 | 
			
		||||
            <span v-else>{{ post.createTime }}</span>
 | 
			
		||||
          </a-descriptions-item>
 | 
			
		||||
          <a-descriptions-item label="修改人">
 | 
			
		||||
            <a-skeleton v-if="detailLoading" :animation="true">
 | 
			
		||||
              <a-skeleton-line :rows="1" />
 | 
			
		||||
            </a-skeleton>
 | 
			
		||||
            <span v-else>{{ post.updateUserString }}</span>
 | 
			
		||||
          </a-descriptions-item>
 | 
			
		||||
          <a-descriptions-item label="修改时间">
 | 
			
		||||
            <a-skeleton v-if="detailLoading" :animation="true">
 | 
			
		||||
              <a-skeleton-line :rows="1" />
 | 
			
		||||
            </a-skeleton>
 | 
			
		||||
            <span v-else>{{ post.updateTime }}</span>
 | 
			
		||||
          </a-descriptions-item>
 | 
			
		||||
          <a-descriptions-item label="描述">
 | 
			
		||||
            <a-skeleton v-if="detailLoading" :animation="true">
 | 
			
		||||
              <a-skeleton-line :rows="1" />
 | 
			
		||||
            </a-skeleton>
 | 
			
		||||
            <span v-else>{{ post.description }}</span>
 | 
			
		||||
          </a-descriptions-item>
 | 
			
		||||
        </a-descriptions>
 | 
			
		||||
      </a-drawer>
 | 
			
		||||
    </a-card>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
  import { getCurrentInstance, ref, toRefs, reactive } from 'vue';
 | 
			
		||||
  import { SelectOptionData } from '@arco-design/web-vue';
 | 
			
		||||
  import {
 | 
			
		||||
    PostRecord,
 | 
			
		||||
    PostParam,
 | 
			
		||||
    listPost,
 | 
			
		||||
    getPost,
 | 
			
		||||
    addPost,
 | 
			
		||||
    updatePost,
 | 
			
		||||
    deletePost,
 | 
			
		||||
  } from '@/api/system/post';
 | 
			
		||||
 | 
			
		||||
  const { proxy } = getCurrentInstance() as any;
 | 
			
		||||
 | 
			
		||||
  const postList = ref<PostRecord[]>([]);
 | 
			
		||||
  const post = ref<PostRecord>({
 | 
			
		||||
    postName: '',
 | 
			
		||||
    status: 1,
 | 
			
		||||
    createUserString: '',
 | 
			
		||||
    createTime: '',
 | 
			
		||||
    updateUserString: '',
 | 
			
		||||
    updateTime: '',
 | 
			
		||||
    description: '',
 | 
			
		||||
  });
 | 
			
		||||
  const total = ref(0);
 | 
			
		||||
  const ids = ref<Array<number>>([]);
 | 
			
		||||
  const title = ref('');
 | 
			
		||||
  const single = ref(true);
 | 
			
		||||
  const multiple = ref(true);
 | 
			
		||||
  const showQuery = ref(true);
 | 
			
		||||
  const loading = ref(false);
 | 
			
		||||
  const detailLoading = ref(false);
 | 
			
		||||
  const exportLoading = ref(false);
 | 
			
		||||
  const visible = ref(false);
 | 
			
		||||
  const detailVisible = ref(false);
 | 
			
		||||
  const statusOptions = ref<SelectOptionData[]>([
 | 
			
		||||
    { label: '启用', value: 1 },
 | 
			
		||||
    { label: '禁用', value: 2 },
 | 
			
		||||
  ]);
 | 
			
		||||
 | 
			
		||||
  const data = reactive({
 | 
			
		||||
    // 查询参数
 | 
			
		||||
    queryParams: {
 | 
			
		||||
      postName: undefined,
 | 
			
		||||
      status: undefined,
 | 
			
		||||
      page: 1,
 | 
			
		||||
      size: 10,
 | 
			
		||||
      sort: ['createTime,desc'],
 | 
			
		||||
    },
 | 
			
		||||
    // 表单数据
 | 
			
		||||
    form: {} as PostRecord,
 | 
			
		||||
    // 表单验证规则
 | 
			
		||||
    rules: {
 | 
			
		||||
      postName: [{ required: true, message: '请输入岗位名称' }],
 | 
			
		||||
      postSort: [{ required: true, message: '请输入岗位排序' }],
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
  const { queryParams, form, rules } = toRefs(data);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 查询列表
 | 
			
		||||
   *
 | 
			
		||||
   * @param params 查询参数
 | 
			
		||||
   */
 | 
			
		||||
  const getList = (params: PostParam = { ...queryParams.value }) => {
 | 
			
		||||
    loading.value = true;
 | 
			
		||||
    listPost(params)
 | 
			
		||||
      .then((res) => {
 | 
			
		||||
        postList.value = res.data.list;
 | 
			
		||||
        total.value = res.data.total;
 | 
			
		||||
      })
 | 
			
		||||
      .finally(() => {
 | 
			
		||||
        loading.value = false;
 | 
			
		||||
      });
 | 
			
		||||
  };
 | 
			
		||||
  getList();
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 打开新增对话框
 | 
			
		||||
   */
 | 
			
		||||
  const toCreate = () => {
 | 
			
		||||
    reset();
 | 
			
		||||
    title.value = '新增岗位';
 | 
			
		||||
    visible.value = true;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 打开修改对话框
 | 
			
		||||
   *
 | 
			
		||||
   * @param id ID
 | 
			
		||||
   */
 | 
			
		||||
  const toUpdate = (id: number) => {
 | 
			
		||||
    reset();
 | 
			
		||||
    getPost(id).then((res) => {
 | 
			
		||||
      form.value = res.data;
 | 
			
		||||
      title.value = '修改岗位';
 | 
			
		||||
      visible.value = true;
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 重置表单
 | 
			
		||||
   */
 | 
			
		||||
  const reset = () => {
 | 
			
		||||
    form.value = {
 | 
			
		||||
      postId: undefined,
 | 
			
		||||
      postName: '',
 | 
			
		||||
      description: '',
 | 
			
		||||
      postSort: 999,
 | 
			
		||||
      status: 1,
 | 
			
		||||
    };
 | 
			
		||||
    proxy.$refs.formRef?.resetFields();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 取消
 | 
			
		||||
   */
 | 
			
		||||
  const handleCancel = () => {
 | 
			
		||||
    visible.value = false;
 | 
			
		||||
    proxy.$refs.formRef.resetFields();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 确定
 | 
			
		||||
   */
 | 
			
		||||
  const handleOk = () => {
 | 
			
		||||
    proxy.$refs.formRef.validate((valid: any) => {
 | 
			
		||||
      if (!valid) {
 | 
			
		||||
        if (form.value.postId !== undefined) {
 | 
			
		||||
          updatePost(form.value).then((res) => {
 | 
			
		||||
            handleCancel();
 | 
			
		||||
            getList();
 | 
			
		||||
            proxy.$message.success(res.msg);
 | 
			
		||||
          });
 | 
			
		||||
        } else {
 | 
			
		||||
          addPost(form.value).then((res) => {
 | 
			
		||||
            handleCancel();
 | 
			
		||||
            getList();
 | 
			
		||||
            proxy.$message.success(res.msg);
 | 
			
		||||
          });
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 查看详情
 | 
			
		||||
   *
 | 
			
		||||
   * @param id ID
 | 
			
		||||
   */
 | 
			
		||||
  const toDetail = async (id: number) => {
 | 
			
		||||
    if (detailLoading.value) return;
 | 
			
		||||
    detailLoading.value = true;
 | 
			
		||||
    detailVisible.value = true;
 | 
			
		||||
    getPost(id)
 | 
			
		||||
      .then((res) => {
 | 
			
		||||
        post.value = res.data;
 | 
			
		||||
      })
 | 
			
		||||
      .finally(() => {
 | 
			
		||||
        detailLoading.value = false;
 | 
			
		||||
      });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 关闭详情
 | 
			
		||||
   */
 | 
			
		||||
  const handleDetailCancel = () => {
 | 
			
		||||
    detailVisible.value = false;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 批量删除
 | 
			
		||||
   */
 | 
			
		||||
  const handleBatchDelete = () => {
 | 
			
		||||
    if (ids.value.length === 0) {
 | 
			
		||||
      proxy.$message.info('请选择要删除的数据');
 | 
			
		||||
    } else {
 | 
			
		||||
      proxy.$modal.warning({
 | 
			
		||||
        title: '警告',
 | 
			
		||||
        titleAlign: 'start',
 | 
			
		||||
        content: '确定要删除当前选中的数据吗?',
 | 
			
		||||
        hideCancel: false,
 | 
			
		||||
        onOk: () => {
 | 
			
		||||
          handleDelete(ids.value);
 | 
			
		||||
        },
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 删除
 | 
			
		||||
   *
 | 
			
		||||
   * @param ids ID 列表
 | 
			
		||||
   */
 | 
			
		||||
  const handleDelete = (ids: Array<number>) => {
 | 
			
		||||
    deletePost(ids).then((res) => {
 | 
			
		||||
      proxy.$message.success(res.msg);
 | 
			
		||||
      getList();
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 已选择的数据行发生改变时触发
 | 
			
		||||
   *
 | 
			
		||||
   * @param rowKeys ID 列表
 | 
			
		||||
   */
 | 
			
		||||
  const handleSelectionChange = (rowKeys: Array<any>) => {
 | 
			
		||||
    ids.value = rowKeys;
 | 
			
		||||
    single.value = rowKeys.length !== 1;
 | 
			
		||||
    multiple.value = !rowKeys.length;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 导出
 | 
			
		||||
   */
 | 
			
		||||
  const handleExport = () => {
 | 
			
		||||
    if (exportLoading.value) return;
 | 
			
		||||
    exportLoading.value = true;
 | 
			
		||||
    proxy
 | 
			
		||||
      .download('/system/post/export', { ...queryParams.value }, '岗位数据')
 | 
			
		||||
      .finally(() => {
 | 
			
		||||
        exportLoading.value = false;
 | 
			
		||||
      });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 修改状态
 | 
			
		||||
   *
 | 
			
		||||
   * @param record 记录信息
 | 
			
		||||
   */
 | 
			
		||||
  const handleChangeStatus = (record: PostRecord) => {
 | 
			
		||||
    const tip = record.status === 1 ? '启用' : '禁用';
 | 
			
		||||
    updatePost(record)
 | 
			
		||||
      .then(() => {
 | 
			
		||||
        proxy.$message.success(`${tip}成功`);
 | 
			
		||||
      })
 | 
			
		||||
      .catch(() => {
 | 
			
		||||
        record.status = record.status === 1 ? 2 : 1;
 | 
			
		||||
      });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 查询
 | 
			
		||||
   */
 | 
			
		||||
  const handleQuery = () => {
 | 
			
		||||
    getList();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 重置
 | 
			
		||||
   */
 | 
			
		||||
  const resetQuery = () => {
 | 
			
		||||
    proxy.$refs.queryRef.resetFields();
 | 
			
		||||
    handleQuery();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 切换页码
 | 
			
		||||
   *
 | 
			
		||||
   * @param current 页码
 | 
			
		||||
   */
 | 
			
		||||
  const handlePageChange = (current: number) => {
 | 
			
		||||
    queryParams.value.page = current;
 | 
			
		||||
    getList();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 切换每页条数
 | 
			
		||||
   *
 | 
			
		||||
   * @param pageSize 每页条数
 | 
			
		||||
   */
 | 
			
		||||
  const handlePageSizeChange = (pageSize: number) => {
 | 
			
		||||
    queryParams.value.size = pageSize;
 | 
			
		||||
    getList();
 | 
			
		||||
  };
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
  export default {
 | 
			
		||||
    name: 'Post',
 | 
			
		||||
  };
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="less"></style>
 | 
			
		||||
							
								
								
									
										3
									
								
								continew-admin-ui/src/views/system/post/locale/en-US.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								continew-admin-ui/src/views/system/post/locale/en-US.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
export default {
 | 
			
		||||
  'menu.system.post.list': 'Post management',
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										3
									
								
								continew-admin-ui/src/views/system/post/locale/zh-CN.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								continew-admin-ui/src/views/system/post/locale/zh-CN.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
export default {
 | 
			
		||||
  'menu.system.post.list': '岗位管理',
 | 
			
		||||
};
 | 
			
		||||
@@ -243,7 +243,7 @@
 | 
			
		||||
      <a-modal
 | 
			
		||||
        :title="title"
 | 
			
		||||
        :visible="visible"
 | 
			
		||||
        :width="580"
 | 
			
		||||
        :width="565"
 | 
			
		||||
        :mask-closable="false"
 | 
			
		||||
        unmount-on-close
 | 
			
		||||
        render-to-body
 | 
			
		||||
@@ -293,6 +293,29 @@
 | 
			
		||||
              <a-radio :value="0" disabled>未知</a-radio>
 | 
			
		||||
            </a-radio-group>
 | 
			
		||||
          </a-form-item>
 | 
			
		||||
          <a-form-item label="所属部门" field="deptId">
 | 
			
		||||
            <a-tree-select
 | 
			
		||||
              v-model="form.deptId"
 | 
			
		||||
              :data="deptOptions"
 | 
			
		||||
              placeholder="请选择所属部门"
 | 
			
		||||
              allow-clear
 | 
			
		||||
              allow-search
 | 
			
		||||
              :filter-tree-node="filterDeptOptions"
 | 
			
		||||
              style="width: 416px"
 | 
			
		||||
            />
 | 
			
		||||
          </a-form-item>
 | 
			
		||||
          <a-form-item label="所属岗位" field="postIds">
 | 
			
		||||
            <a-select
 | 
			
		||||
              v-model="form.postIds"
 | 
			
		||||
              :options="postOptions"
 | 
			
		||||
              placeholder="请选择所属岗位"
 | 
			
		||||
              :loading="postLoading"
 | 
			
		||||
              multiple
 | 
			
		||||
              allow-clear
 | 
			
		||||
              :allow-search="{ retainInputValue: true }"
 | 
			
		||||
              style="width: 416px"
 | 
			
		||||
            />
 | 
			
		||||
          </a-form-item>
 | 
			
		||||
          <a-form-item label="所属角色" field="roleIds">
 | 
			
		||||
            <a-select
 | 
			
		||||
              v-model="form.roleIds"
 | 
			
		||||
@@ -305,17 +328,6 @@
 | 
			
		||||
              style="width: 416px"
 | 
			
		||||
            />
 | 
			
		||||
          </a-form-item>
 | 
			
		||||
          <a-form-item label="所属部门" field="deptId">
 | 
			
		||||
            <a-tree-select
 | 
			
		||||
              v-model="form.deptId"
 | 
			
		||||
              :data="deptOptions"
 | 
			
		||||
              placeholder="请选择所属部门"
 | 
			
		||||
              allow-clear
 | 
			
		||||
              allow-search
 | 
			
		||||
              :filter-tree-node="filterDeptOptions"
 | 
			
		||||
              style="width: 416px"
 | 
			
		||||
            />
 | 
			
		||||
          </a-form-item>
 | 
			
		||||
          <a-form-item label="描述" field="description">
 | 
			
		||||
            <a-textarea
 | 
			
		||||
              v-model="form.description"
 | 
			
		||||
@@ -367,7 +379,7 @@
 | 
			
		||||
        render-to-body
 | 
			
		||||
        @cancel="handleDetailCancel"
 | 
			
		||||
      >
 | 
			
		||||
        <a-descriptions title="基础信息" :column="2" bordered size="large">
 | 
			
		||||
        <a-descriptions :column="2" bordered size="large" layout="vertical">
 | 
			
		||||
          <a-descriptions-item label="用户名">
 | 
			
		||||
            <a-skeleton v-if="detailLoading" :animation="true">
 | 
			
		||||
              <a-skeleton-line :rows="1" />
 | 
			
		||||
@@ -410,17 +422,29 @@
 | 
			
		||||
            </a-skeleton>
 | 
			
		||||
            <span v-else>{{ user.phone || '无' }}</span>
 | 
			
		||||
          </a-descriptions-item>
 | 
			
		||||
          <a-descriptions-item label="所属部门">
 | 
			
		||||
            <a-skeleton v-if="detailLoading" :animation="true">
 | 
			
		||||
              <a-skeleton-line :rows="1" />
 | 
			
		||||
            </a-skeleton>
 | 
			
		||||
            <span v-else>{{ user.deptName }}</span>
 | 
			
		||||
          </a-descriptions-item>
 | 
			
		||||
          <a-descriptions-item label="所属岗位">
 | 
			
		||||
            <a-skeleton v-if="detailLoading" :animation="true">
 | 
			
		||||
              <a-skeleton-line :rows="1" />
 | 
			
		||||
            </a-skeleton>
 | 
			
		||||
            <span v-else>{{ user.postNames }}</span>
 | 
			
		||||
          </a-descriptions-item>
 | 
			
		||||
          <a-descriptions-item label="所属角色">
 | 
			
		||||
            <a-skeleton v-if="detailLoading" :animation="true">
 | 
			
		||||
              <a-skeleton-line :rows="1" />
 | 
			
		||||
            </a-skeleton>
 | 
			
		||||
            <span v-else>{{ user.roleNames }}</span>
 | 
			
		||||
          </a-descriptions-item>
 | 
			
		||||
          <a-descriptions-item label="所属部门">
 | 
			
		||||
          <a-descriptions-item label="最后一次修改密码时间">
 | 
			
		||||
            <a-skeleton v-if="detailLoading" :animation="true">
 | 
			
		||||
              <a-skeleton-line :rows="1" />
 | 
			
		||||
            </a-skeleton>
 | 
			
		||||
            <span v-else>{{ user.deptName }}</span>
 | 
			
		||||
            <span v-else>{{ user.pwdResetTime }}</span>
 | 
			
		||||
          </a-descriptions-item>
 | 
			
		||||
          <a-descriptions-item label="创建人">
 | 
			
		||||
            <a-skeleton v-if="detailLoading" :animation="true">
 | 
			
		||||
@@ -472,7 +496,12 @@
 | 
			
		||||
    resetPassword,
 | 
			
		||||
    updateUserRole,
 | 
			
		||||
  } from '@/api/system/user';
 | 
			
		||||
  import { listRoleDict, listDeptTree } from '@/api/common';
 | 
			
		||||
  import {
 | 
			
		||||
    LabelValueRecord,
 | 
			
		||||
    listDeptTree,
 | 
			
		||||
    listPostDict,
 | 
			
		||||
    listRoleDict,
 | 
			
		||||
  } from '@/api/common';
 | 
			
		||||
  import getAvatar from '@/utils/avatar';
 | 
			
		||||
 | 
			
		||||
  const { proxy } = getCurrentInstance() as any;
 | 
			
		||||
@@ -485,6 +514,7 @@
 | 
			
		||||
    email: undefined,
 | 
			
		||||
    phone: undefined,
 | 
			
		||||
    status: 1,
 | 
			
		||||
    pwdResetTime: '',
 | 
			
		||||
    createUserString: '',
 | 
			
		||||
    createTime: '',
 | 
			
		||||
    updateUserString: '',
 | 
			
		||||
@@ -509,10 +539,12 @@
 | 
			
		||||
    { label: '启用', value: 1 },
 | 
			
		||||
    { label: '禁用', value: 2 },
 | 
			
		||||
  ]);
 | 
			
		||||
  const roleLoading = ref(false);
 | 
			
		||||
  const deptLoading = ref(false);
 | 
			
		||||
  const roleOptions = ref<TreeNodeData[]>([]);
 | 
			
		||||
  const postLoading = ref(false);
 | 
			
		||||
  const roleLoading = ref(false);
 | 
			
		||||
  const deptOptions = ref<TreeNodeData[]>([]);
 | 
			
		||||
  const postOptions = ref<LabelValueRecord[]>([]);
 | 
			
		||||
  const roleOptions = ref<LabelValueRecord[]>([]);
 | 
			
		||||
  const deptTree = ref<TreeNodeData[]>([]);
 | 
			
		||||
  const deptName = ref('');
 | 
			
		||||
 | 
			
		||||
@@ -580,8 +612,9 @@
 | 
			
		||||
   */
 | 
			
		||||
  const toCreate = () => {
 | 
			
		||||
    reset();
 | 
			
		||||
    getRoleOptions();
 | 
			
		||||
    getDeptOptions();
 | 
			
		||||
    getPostOptions();
 | 
			
		||||
    getRoleOptions();
 | 
			
		||||
    title.value = '新增用户';
 | 
			
		||||
    visible.value = true;
 | 
			
		||||
  };
 | 
			
		||||
@@ -593,8 +626,9 @@
 | 
			
		||||
   */
 | 
			
		||||
  const toUpdate = (id: number) => {
 | 
			
		||||
    reset();
 | 
			
		||||
    getRoleOptions();
 | 
			
		||||
    getDeptOptions();
 | 
			
		||||
    getPostOptions();
 | 
			
		||||
    getRoleOptions();
 | 
			
		||||
    getUser(id).then((res) => {
 | 
			
		||||
      form.value = res.data;
 | 
			
		||||
      title.value = '修改用户';
 | 
			
		||||
@@ -616,20 +650,6 @@
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 查询角色列表
 | 
			
		||||
   */
 | 
			
		||||
  const getRoleOptions = () => {
 | 
			
		||||
    roleLoading.value = true;
 | 
			
		||||
    listRoleDict({})
 | 
			
		||||
      .then((res) => {
 | 
			
		||||
        roleOptions.value = res.data;
 | 
			
		||||
      })
 | 
			
		||||
      .finally(() => {
 | 
			
		||||
        roleLoading.value = false;
 | 
			
		||||
      });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 查询部门列表
 | 
			
		||||
   */
 | 
			
		||||
@@ -644,6 +664,34 @@
 | 
			
		||||
      });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 查询岗位列表
 | 
			
		||||
   */
 | 
			
		||||
  const getPostOptions = () => {
 | 
			
		||||
    postLoading.value = true;
 | 
			
		||||
    listPostDict({})
 | 
			
		||||
      .then((res) => {
 | 
			
		||||
        postOptions.value = res.data;
 | 
			
		||||
      })
 | 
			
		||||
      .finally(() => {
 | 
			
		||||
        postLoading.value = false;
 | 
			
		||||
      });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 查询角色列表
 | 
			
		||||
   */
 | 
			
		||||
  const getRoleOptions = () => {
 | 
			
		||||
    roleLoading.value = true;
 | 
			
		||||
    listRoleDict({})
 | 
			
		||||
      .then((res) => {
 | 
			
		||||
        roleOptions.value = res.data;
 | 
			
		||||
      })
 | 
			
		||||
      .finally(() => {
 | 
			
		||||
        roleLoading.value = false;
 | 
			
		||||
      });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 重置表单
 | 
			
		||||
   */
 | 
			
		||||
@@ -657,8 +705,9 @@
 | 
			
		||||
      phone: undefined,
 | 
			
		||||
      description: '',
 | 
			
		||||
      status: 1,
 | 
			
		||||
      roleIds: [] as Array<number>,
 | 
			
		||||
      deptId: undefined,
 | 
			
		||||
      postIds: [] as Array<number>,
 | 
			
		||||
      roleIds: [] as Array<number>,
 | 
			
		||||
    };
 | 
			
		||||
    proxy.$refs.formRef?.resetFields();
 | 
			
		||||
  };
 | 
			
		||||
 
 | 
			
		||||
@@ -36,12 +36,15 @@ import top.charles7c.cnadmin.common.model.vo.R;
 | 
			
		||||
import top.charles7c.cnadmin.monitor.annotation.Log;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.query.DeptQuery;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.query.MenuQuery;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.query.PostQuery;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.query.RoleQuery;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.vo.DeptVO;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.vo.MenuVO;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.vo.PostVO;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.vo.RoleVO;
 | 
			
		||||
import top.charles7c.cnadmin.system.service.DeptService;
 | 
			
		||||
import top.charles7c.cnadmin.system.service.MenuService;
 | 
			
		||||
import top.charles7c.cnadmin.system.service.PostService;
 | 
			
		||||
import top.charles7c.cnadmin.system.service.RoleService;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -51,6 +54,7 @@ import top.charles7c.cnadmin.system.service.RoleService;
 | 
			
		||||
 * @since 2023/1/22 21:48
 | 
			
		||||
 */
 | 
			
		||||
@Tag(name = "公共 API")
 | 
			
		||||
@Log(ignore = true)
 | 
			
		||||
@RestController
 | 
			
		||||
@RequiredArgsConstructor
 | 
			
		||||
@RequestMapping("/common")
 | 
			
		||||
@@ -59,8 +63,8 @@ public class CommonController {
 | 
			
		||||
    private final DeptService deptService;
 | 
			
		||||
    private final MenuService menuService;
 | 
			
		||||
    private final RoleService roleService;
 | 
			
		||||
    private final PostService postService;
 | 
			
		||||
 | 
			
		||||
    @Log(ignore = true)
 | 
			
		||||
    @Operation(summary = "查询部门树", description = "查询树结构的部门列表")
 | 
			
		||||
    @GetMapping("/tree/dept")
 | 
			
		||||
    public R<List<Tree<Long>>> listDeptTree(@Validated DeptQuery query, @Validated SortQuery sortQuery) {
 | 
			
		||||
@@ -69,7 +73,6 @@ public class CommonController {
 | 
			
		||||
        return R.ok(treeList);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Log(ignore = true)
 | 
			
		||||
    @Operation(summary = "查询菜单树", description = "查询树结构的菜单列表")
 | 
			
		||||
    @GetMapping("/tree/menu")
 | 
			
		||||
    public R<List<Tree<Long>>> listMenuTree(@Validated MenuQuery query, @Validated SortQuery sortQuery) {
 | 
			
		||||
@@ -78,7 +81,6 @@ public class CommonController {
 | 
			
		||||
        return R.ok(treeList);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Log(ignore = true)
 | 
			
		||||
    @Operation(summary = "查询角色字典", description = "查询角色字典列表")
 | 
			
		||||
    @GetMapping("/dict/role")
 | 
			
		||||
    public R<List<LabelValueVO<Long>>> listRoleDict(@Validated RoleQuery query, @Validated SortQuery sortQuery) {
 | 
			
		||||
@@ -86,4 +88,12 @@ public class CommonController {
 | 
			
		||||
        List<LabelValueVO<Long>> dictList = roleService.buildDict(list);
 | 
			
		||||
        return R.ok(dictList);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Operation(summary = "查询岗位字典", description = "查询岗位字典列表")
 | 
			
		||||
    @GetMapping("/dict/post")
 | 
			
		||||
    public R<List<LabelValueVO<Long>>> listPostDict(@Validated PostQuery query, @Validated SortQuery sortQuery) {
 | 
			
		||||
        List<PostVO> list = postService.list(query, sortQuery);
 | 
			
		||||
        List<LabelValueVO<Long>> dictList = postService.buildDict(list);
 | 
			
		||||
        return R.ok(dictList);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,40 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package top.charles7c.cnadmin.webapi.controller.system;
 | 
			
		||||
 | 
			
		||||
import io.swagger.v3.oas.annotations.tags.Tag;
 | 
			
		||||
 | 
			
		||||
import org.springframework.web.bind.annotation.RestController;
 | 
			
		||||
 | 
			
		||||
import top.charles7c.cnadmin.common.annotation.CrudRequestMapping;
 | 
			
		||||
import top.charles7c.cnadmin.common.base.BaseController;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.query.PostQuery;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.request.PostRequest;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.vo.PostDetailVO;
 | 
			
		||||
import top.charles7c.cnadmin.system.model.vo.PostVO;
 | 
			
		||||
import top.charles7c.cnadmin.system.service.PostService;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 岗位管理 API
 | 
			
		||||
 *
 | 
			
		||||
 * @author Charles7c
 | 
			
		||||
 * @since 2023/2/25 22:54
 | 
			
		||||
 */
 | 
			
		||||
@Tag(name = "岗位管理 API")
 | 
			
		||||
@RestController
 | 
			
		||||
@CrudRequestMapping("/system/post")
 | 
			
		||||
public class PostController extends BaseController<PostService, PostVO, PostDetailVO, PostQuery, PostRequest> {}
 | 
			
		||||
@@ -3,21 +3,33 @@
 | 
			
		||||
-- changeset Charles7c:1
 | 
			
		||||
-- 初始化默认菜单
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1000, '系统管理', 0, 1, 'system', NULL, NULL, 'settings', b'0', b'0', b'0', NULL, 1, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1010, '角色管理', 1000, 2, '/system/role', 'Role', 'system/role/index', NULL, b'0', b'0', b'0', 'system:role:list', 2, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1011, '角色新增', 1010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:role:create', 1, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1012, '角色修改', 1010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:role:update', 2, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1013, '角色删除', 1010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:role:delete', 3, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1014, '角色导出', 1010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:role:export', 4, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1010, '用户管理', 1000, 2, '/system/user', 'User', '/system/user/index', NULL, b'0', b'0', b'0', 'system:user:list', 1, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1011, '用户新增', 1010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:user:create', 1, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1012, '用户修改', 1010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:user:update', 2, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1013, '用户删除', 1010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:user:delete', 3, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1014, '用户导出', 1010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:user:export', 4, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1015, '重置密码', 1010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:user:password:reset', 5, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1016, '分配角色', 1010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:user:role:update', 6, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1020, '角色管理', 1000, 2, '/system/role', 'Role', 'system/role/index', NULL, b'0', b'0', b'0', 'system:role:list', 2, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1021, '角色新增', 1020, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:role:create', 1, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1022, '角色修改', 1020, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:role:update', 2, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1023, '角色删除', 1020, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:role:delete', 3, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1024, '角色导出', 1020, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:role:export', 4, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1030, '菜单管理', 1000, 2, '/system/menu', 'Menu', 'system/menu/index', NULL, b'0', b'0', b'0', 'system:menu:list', 3, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1031, '菜单新增', 1030, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:menu:create', 1, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1032, '菜单修改', 1030, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:menu:update', 2, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1033, '菜单删除', 1030, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:menu:delete', 3, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1034, '菜单导出', 1030, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:menu:export', 4, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1050, '部门管理', 1000, 2, '/system/dept', 'Dept', 'system/dept/index', NULL, b'0', b'0', b'0', 'system:dept:list', 4, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1051, '部门新增', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dept:create', 1, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1052, '部门修改', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dept:update', 2, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1053, '部门删除', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dept:delete', 3, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1054, '部门导出', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dept:export', 4, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1040, '部门管理', 1000, 2, '/system/dept', 'Dept', 'system/dept/index', NULL, b'0', b'0', b'0', 'system:dept:list', 4, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1041, '部门新增', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dept:create', 1, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1042, '部门修改', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dept:update', 2, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1043, '部门删除', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dept:delete', 3, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1044, '部门导出', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dept:export', 4, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1050, '岗位管理', 1000, 2, '/system/post', 'Post', '/system/post/index', NULL, b'0', b'0', b'0', 'system:post:list', 5, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1051, '岗位新增', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:post:create', 1, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1052, '岗位修改', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:post:update', 2, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1053, '岗位删除', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:post:delete', 3, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (1054, '岗位导出', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:post:export', 4, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (2000, '系统监控', 0, 1, 'monitor', NULL, NULL, 'computer', b'0', b'0', b'0', NULL, 2, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (2010, '在线用户', 2000, 2, '/monitor/online', 'OnlineUser', 'monitor/online/index', NULL, b'0', b'0', b'0', 'monitor:online:user:list', 1, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_menu` VALUES (2011, '强退用户', 2010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'monitor:online:user:delete', 1, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
@@ -37,6 +49,18 @@ INSERT IGNORE INTO `sys_dept` VALUES (6, '运维部', 2, '系统初始部门', 4
 | 
			
		||||
INSERT IGNORE INTO `sys_dept` VALUES (7, '研发一组', 3, '系统初始部门', 1, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_dept` VALUES (8, '研发二组', 3, '系统初始部门', 2, 2, 1, NOW(), 1, NOW());
 | 
			
		||||
 | 
			
		||||
-- 初始化默认岗位
 | 
			
		||||
INSERT IGNORE INTO `sys_post` VALUES (1, '项目总监', '系统初始岗位', 1, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_post` VALUES (2, '技术总监', '系统初始岗位', 2, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_post` VALUES (3, '销售经理', '系统初始岗位', 3, 2, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_post` VALUES (4, '项目经理', '系统初始岗位', 4, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_post` VALUES (5, '产品经理', '系统初始岗位', 5, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_post` VALUES (6, '技术经理', '系统初始岗位', 6, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_post` VALUES (7, '测试经理', '系统初始岗位', 7, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_post` VALUES (8, '销售专员', '系统初始岗位', 8, 2, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_post` VALUES (9, '软件开发', '系统初始岗位', 9, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_post` VALUES (10, '软件测试', '系统初始岗位', 10, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
 | 
			
		||||
-- 初始化默认角色
 | 
			
		||||
INSERT IGNORE INTO `sys_role` VALUES (1, '超级管理员', 'admin', 1, '系统初始角色', 1, 1, 1, NOW(), 1, NOW());
 | 
			
		||||
INSERT IGNORE INTO `sys_role` VALUES (2, '测试人员', 'test', 5, '系统初始角色', 2, 2, 1, NOW(), 1, NOW());
 | 
			
		||||
@@ -69,3 +93,7 @@ INSERT IGNORE INTO `sys_role_dept` VALUES (2, 5);
 | 
			
		||||
-- 初始化默认用户和角色关联数据
 | 
			
		||||
INSERT IGNORE INTO `sys_user_role` VALUES (1, 1);
 | 
			
		||||
INSERT IGNORE INTO `sys_user_role` VALUES (2, 2);
 | 
			
		||||
 | 
			
		||||
-- 初始化默认用户和岗位关联数据
 | 
			
		||||
INSERT IGNORE INTO `sys_user_post` VALUES (1, 1);
 | 
			
		||||
INSERT IGNORE INTO `sys_user_post` VALUES (2, 10);
 | 
			
		||||
@@ -72,6 +72,21 @@ CREATE TABLE IF NOT EXISTS `sys_role_dept`  (
 | 
			
		||||
    PRIMARY KEY (`role_id`,`dept_id`) USING BTREE
 | 
			
		||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色和部门关联表';
 | 
			
		||||
 | 
			
		||||
CREATE TABLE IF NOT EXISTS `sys_post`  (
 | 
			
		||||
    `post_id` bigint(20) unsigned AUTO_INCREMENT COMMENT '岗位ID',
 | 
			
		||||
    `post_name` varchar(255) NOT NULL COMMENT '岗位名称',
 | 
			
		||||
    `description` varchar(512) DEFAULT NULL COMMENT '描述',
 | 
			
		||||
    `post_sort` int(11) unsigned DEFAULT 999 COMMENT '岗位排序',
 | 
			
		||||
    `status` tinyint(1) unsigned DEFAULT 1 COMMENT '状态(1启用 2禁用)',
 | 
			
		||||
    `create_user` bigint(20) unsigned NOT NULL COMMENT '创建人',
 | 
			
		||||
    `create_time` datetime NOT NULL COMMENT '创建时间',
 | 
			
		||||
    `update_user` bigint(20) unsigned NOT NULL COMMENT '修改人',
 | 
			
		||||
    `update_time` datetime NOT NULL COMMENT '修改时间',
 | 
			
		||||
    PRIMARY KEY (`post_id`) USING BTREE,
 | 
			
		||||
    INDEX `idx_create_user`(`create_user`) USING BTREE,
 | 
			
		||||
    INDEX `idx_update_user`(`update_user`) USING BTREE
 | 
			
		||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='岗位表';
 | 
			
		||||
 | 
			
		||||
CREATE TABLE IF NOT EXISTS `sys_user`  (
 | 
			
		||||
    `user_id` bigint(20) unsigned AUTO_INCREMENT COMMENT '用户ID',
 | 
			
		||||
    `username` varchar(255) NOT NULL COMMENT '用户名',
 | 
			
		||||
@@ -83,7 +98,7 @@ CREATE TABLE IF NOT EXISTS `sys_user`  (
 | 
			
		||||
    `avatar` varchar(255) DEFAULT NULL COMMENT '头像地址',
 | 
			
		||||
    `description` varchar(512) DEFAULT NULL COMMENT '描述',
 | 
			
		||||
    `status` tinyint(1) unsigned DEFAULT 1 COMMENT '状态(1启用 2禁用)',
 | 
			
		||||
    `pwd_reset_time` datetime DEFAULT NULL COMMENT '最后一次修改密码的时间',
 | 
			
		||||
    `pwd_reset_time` datetime DEFAULT NULL COMMENT '最后一次修改密码时间',
 | 
			
		||||
    `dept_id` bigint(20) unsigned DEFAULT NULL COMMENT '部门ID',
 | 
			
		||||
    `create_user` bigint(20) unsigned NOT NULL COMMENT '创建人',
 | 
			
		||||
    `create_time` datetime NOT NULL COMMENT '创建时间',
 | 
			
		||||
@@ -103,6 +118,12 @@ CREATE TABLE IF NOT EXISTS `sys_user_role`  (
 | 
			
		||||
    PRIMARY KEY (`user_id`,`role_id`) USING BTREE
 | 
			
		||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户和角色关联表';
 | 
			
		||||
 | 
			
		||||
CREATE TABLE IF NOT EXISTS `sys_user_post`  (
 | 
			
		||||
    `user_id` bigint(20) unsigned NOT NULL COMMENT '用户ID',
 | 
			
		||||
    `post_id` bigint(20) unsigned NOT NULL COMMENT '岗位ID',
 | 
			
		||||
    PRIMARY KEY (`user_id`,`post_id`) USING BTREE
 | 
			
		||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户和岗位关联表';
 | 
			
		||||
 | 
			
		||||
CREATE TABLE IF NOT EXISTS `sys_log` (
 | 
			
		||||
    `log_id` bigint(20) unsigned AUTO_INCREMENT COMMENT '日志ID',
 | 
			
		||||
    `description` varchar(255) NOT NULL COMMENT '日志描述',
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user