17 changed files with 2003 additions and 13 deletions
-
123chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysAreaController.java
-
41chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysUserController.java
-
177chenhai-common/src/main/java/com/chenhai/common/core/domain/entity/SysArea.java
-
24chenhai-common/src/main/java/com/chenhai/common/core/domain/entity/SysUser.java
-
61chenhai-system/src/main/java/com/chenhai/system/mapper/SysAreaMapper.java
-
2chenhai-system/src/main/java/com/chenhai/system/mapper/SysUserMapper.java
-
61chenhai-system/src/main/java/com/chenhai/system/service/ISysAreaService.java
-
9chenhai-system/src/main/java/com/chenhai/system/service/ISysUserService.java
-
96chenhai-system/src/main/java/com/chenhai/system/service/impl/SysAreaServiceImpl.java
-
6chenhai-system/src/main/java/com/chenhai/system/service/impl/SysUserServiceImpl.java
-
116chenhai-system/src/main/resources/mapper/system/SysAreaMapper.xml
-
45chenhai-system/src/main/resources/mapper/system/SysUserMapper.xml
-
63chenhai-ui/src/api/system/area.js
-
29chenhai-ui/src/api/system/user.js
-
1chenhai-ui/src/assets/icons/svg/userinfo.svg
-
426chenhai-ui/src/views/system/area/index.vue
-
736chenhai-ui/src/views/system/userInfo/index.vue
@ -0,0 +1,123 @@ |
|||||
|
package com.chenhai.web.controller.system; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import jakarta.servlet.http.HttpServletResponse; |
||||
|
import org.springframework.security.access.prepost.PreAuthorize; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.web.bind.annotation.*; |
||||
|
import com.chenhai.common.annotation.Log; |
||||
|
import com.chenhai.common.core.controller.BaseController; |
||||
|
import com.chenhai.common.core.domain.AjaxResult; |
||||
|
import com.chenhai.common.enums.BusinessType; |
||||
|
import com.chenhai.common.core.domain.entity.SysArea; |
||||
|
import com.chenhai.system.service.ISysAreaService; |
||||
|
import com.chenhai.common.utils.poi.ExcelUtil; |
||||
|
import com.chenhai.common.core.page.TableDataInfo; |
||||
|
|
||||
|
/** |
||||
|
* 行政区划Controller |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
* @date 2026-01-09 |
||||
|
*/ |
||||
|
@RestController |
||||
|
@RequestMapping("/system/area") |
||||
|
public class SysAreaController extends BaseController |
||||
|
{ |
||||
|
@Autowired |
||||
|
private ISysAreaService sysAreaService; |
||||
|
|
||||
|
/** |
||||
|
* 查询行政区划列表 |
||||
|
*/ |
||||
|
@PreAuthorize("@ss.hasPermi('system:area:list')") |
||||
|
@GetMapping("/list") |
||||
|
public TableDataInfo list(SysArea sysArea) |
||||
|
{ |
||||
|
startPage(); |
||||
|
List<SysArea> list = sysAreaService.selectSysAreaList(sysArea); |
||||
|
return getDataTable(list); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 导出行政区划列表 |
||||
|
*/ |
||||
|
@PreAuthorize("@ss.hasPermi('system:area:export')") |
||||
|
@Log(title = "行政区划", businessType = BusinessType.EXPORT) |
||||
|
@PostMapping("/export") |
||||
|
public void export(HttpServletResponse response, SysArea sysArea) |
||||
|
{ |
||||
|
List<SysArea> list = sysAreaService.selectSysAreaList(sysArea); |
||||
|
ExcelUtil<SysArea> util = new ExcelUtil<SysArea>(SysArea.class); |
||||
|
util.exportExcel(response, list, "行政区划数据"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取行政区划详细信息 |
||||
|
*/ |
||||
|
@PreAuthorize("@ss.hasPermi('system:area:query')") |
||||
|
@GetMapping(value = "/{id}") |
||||
|
public AjaxResult getInfo(@PathVariable("id") Long id) |
||||
|
{ |
||||
|
return success(sysAreaService.selectSysAreaById(id)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 新增行政区划 |
||||
|
*/ |
||||
|
@PreAuthorize("@ss.hasPermi('system:area:add')") |
||||
|
@Log(title = "行政区划", businessType = BusinessType.INSERT) |
||||
|
@PostMapping |
||||
|
public AjaxResult add(@RequestBody SysArea sysArea) |
||||
|
{ |
||||
|
return toAjax(sysAreaService.insertSysArea(sysArea)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 修改行政区划 |
||||
|
*/ |
||||
|
@PreAuthorize("@ss.hasPermi('system:area:edit')") |
||||
|
@Log(title = "行政区划", businessType = BusinessType.UPDATE) |
||||
|
@PutMapping |
||||
|
public AjaxResult edit(@RequestBody SysArea sysArea) |
||||
|
{ |
||||
|
return toAjax(sysAreaService.updateSysArea(sysArea)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除行政区划 |
||||
|
*/ |
||||
|
@PreAuthorize("@ss.hasPermi('system:area:remove')") |
||||
|
@Log(title = "行政区划", businessType = BusinessType.DELETE) |
||||
|
@DeleteMapping("/{ids}") |
||||
|
public AjaxResult remove(@PathVariable Long[] ids) |
||||
|
{ |
||||
|
return toAjax(sysAreaService.deleteSysAreaByIds(ids)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 懒加载查询子节点 |
||||
|
*/ |
||||
|
@PreAuthorize("@ss.hasPermi('system:area:list')") |
||||
|
@GetMapping("/children") |
||||
|
public AjaxResult getChildren(@RequestParam(value = "parentCode", required = false, defaultValue = "152900") String parentCode) { |
||||
|
SysArea query = new SysArea(); |
||||
|
query.setParentCode(parentCode); |
||||
|
query.setDeleted(0); |
||||
|
List<SysArea> list = sysAreaService.selectSysAreaList(query); |
||||
|
return success(list); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取所有省级节点(type=2的就是省级) |
||||
|
*/ |
||||
|
@PreAuthorize("@ss.hasPermi('system:area:list')") |
||||
|
@GetMapping("/provinces") |
||||
|
public AjaxResult getProvinces() { |
||||
|
SysArea query = new SysArea(); |
||||
|
query.setType(2); // 省级 |
||||
|
query.setDeleted(0); |
||||
|
List<SysArea> list = sysAreaService.selectSysAreaList(query); |
||||
|
return success(list); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,177 @@ |
|||||
|
package com.chenhai.common.core.domain.entity; |
||||
|
|
||||
|
import org.apache.commons.lang3.builder.ToStringBuilder; |
||||
|
import org.apache.commons.lang3.builder.ToStringStyle; |
||||
|
import com.chenhai.common.annotation.Excel; |
||||
|
import com.chenhai.common.core.domain.BaseEntity; |
||||
|
|
||||
|
/** |
||||
|
* 行政区划对象 sys_area |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
* @date 2026-01-09 |
||||
|
*/ |
||||
|
public class SysArea extends BaseEntity |
||||
|
{ |
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
/** 自增ID */ |
||||
|
private Long id; |
||||
|
|
||||
|
/** 名称 */ |
||||
|
@Excel(name = "名称") |
||||
|
private String name; |
||||
|
|
||||
|
/** 编码 */ |
||||
|
@Excel(name = "编码") |
||||
|
private String code; |
||||
|
|
||||
|
/** 父节点编码 */ |
||||
|
@Excel(name = "父节点编码") |
||||
|
private String parentCode; |
||||
|
|
||||
|
/** 节点类型(1:国;2:省;3:市;4:县;5:街道;6:村) */ |
||||
|
@Excel(name = "节点类型", readConverterExp = "1=:国;2:省;3:市;4:县;5:街道;6:村") |
||||
|
private Integer type; |
||||
|
|
||||
|
/** 显示顺序 */ |
||||
|
@Excel(name = "显示顺序") |
||||
|
private Long sort; |
||||
|
|
||||
|
/** 行政区划节点状态(0:开启,1:关闭) */ |
||||
|
@Excel(name = "行政区划节点状态", readConverterExp = "0=:开启,1:关闭") |
||||
|
private Integer status; |
||||
|
|
||||
|
/** 全名称 */ |
||||
|
@Excel(name = "全名称") |
||||
|
private String namePath; |
||||
|
|
||||
|
/** 全编码 */ |
||||
|
@Excel(name = "全编码") |
||||
|
private String codePath; |
||||
|
|
||||
|
/** 是否删除 */ |
||||
|
@Excel(name = "是否删除") |
||||
|
private Integer deleted; |
||||
|
|
||||
|
public void setId(Long id) |
||||
|
{ |
||||
|
this.id = id; |
||||
|
} |
||||
|
|
||||
|
public Long getId() |
||||
|
{ |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
public void setName(String name) |
||||
|
{ |
||||
|
this.name = name; |
||||
|
} |
||||
|
|
||||
|
public String getName() |
||||
|
{ |
||||
|
return name; |
||||
|
} |
||||
|
|
||||
|
public void setCode(String code) |
||||
|
{ |
||||
|
this.code = code; |
||||
|
} |
||||
|
|
||||
|
public String getCode() |
||||
|
{ |
||||
|
return code; |
||||
|
} |
||||
|
|
||||
|
public void setParentCode(String parentCode) |
||||
|
{ |
||||
|
this.parentCode = parentCode; |
||||
|
} |
||||
|
|
||||
|
public String getParentCode() |
||||
|
{ |
||||
|
return parentCode; |
||||
|
} |
||||
|
|
||||
|
public void setType(Integer type) |
||||
|
{ |
||||
|
this.type = type; |
||||
|
} |
||||
|
|
||||
|
public Integer getType() |
||||
|
{ |
||||
|
return type; |
||||
|
} |
||||
|
|
||||
|
public void setSort(Long sort) |
||||
|
{ |
||||
|
this.sort = sort; |
||||
|
} |
||||
|
|
||||
|
public Long getSort() |
||||
|
{ |
||||
|
return sort; |
||||
|
} |
||||
|
|
||||
|
public void setStatus(Integer status) |
||||
|
{ |
||||
|
this.status = status; |
||||
|
} |
||||
|
|
||||
|
public Integer getStatus() |
||||
|
{ |
||||
|
return status; |
||||
|
} |
||||
|
|
||||
|
public void setNamePath(String namePath) |
||||
|
{ |
||||
|
this.namePath = namePath; |
||||
|
} |
||||
|
|
||||
|
public String getNamePath() |
||||
|
{ |
||||
|
return namePath; |
||||
|
} |
||||
|
|
||||
|
public void setCodePath(String codePath) |
||||
|
{ |
||||
|
this.codePath = codePath; |
||||
|
} |
||||
|
|
||||
|
public String getCodePath() |
||||
|
{ |
||||
|
return codePath; |
||||
|
} |
||||
|
|
||||
|
public void setDeleted(Integer deleted) |
||||
|
{ |
||||
|
this.deleted = deleted; |
||||
|
} |
||||
|
|
||||
|
public Integer getDeleted() |
||||
|
{ |
||||
|
return deleted; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public String toString() { |
||||
|
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) |
||||
|
.append("id", getId()) |
||||
|
.append("name", getName()) |
||||
|
.append("code", getCode()) |
||||
|
.append("parentCode", getParentCode()) |
||||
|
.append("type", getType()) |
||||
|
.append("sort", getSort()) |
||||
|
.append("status", getStatus()) |
||||
|
.append("namePath", getNamePath()) |
||||
|
.append("codePath", getCodePath()) |
||||
|
.append("createBy", getCreateBy()) |
||||
|
.append("createTime", getCreateTime()) |
||||
|
.append("updateBy", getUpdateBy()) |
||||
|
.append("updateTime", getUpdateTime()) |
||||
|
.append("deleted", getDeleted()) |
||||
|
.append("remark", getRemark()) |
||||
|
.toString(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,61 @@ |
|||||
|
package com.chenhai.system.mapper; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import com.chenhai.common.core.domain.entity.SysArea; |
||||
|
|
||||
|
/** |
||||
|
* 行政区划Mapper接口 |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
* @date 2026-01-09 |
||||
|
*/ |
||||
|
public interface SysAreaMapper |
||||
|
{ |
||||
|
/** |
||||
|
* 查询行政区划 |
||||
|
* |
||||
|
* @param id 行政区划主键 |
||||
|
* @return 行政区划 |
||||
|
*/ |
||||
|
public SysArea selectSysAreaById(Long id); |
||||
|
|
||||
|
/** |
||||
|
* 查询行政区划列表 |
||||
|
* |
||||
|
* @param sysArea 行政区划 |
||||
|
* @return 行政区划集合 |
||||
|
*/ |
||||
|
public List<SysArea> selectSysAreaList(SysArea sysArea); |
||||
|
|
||||
|
/** |
||||
|
* 新增行政区划 |
||||
|
* |
||||
|
* @param sysArea 行政区划 |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
public int insertSysArea(SysArea sysArea); |
||||
|
|
||||
|
/** |
||||
|
* 修改行政区划 |
||||
|
* |
||||
|
* @param sysArea 行政区划 |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
public int updateSysArea(SysArea sysArea); |
||||
|
|
||||
|
/** |
||||
|
* 删除行政区划 |
||||
|
* |
||||
|
* @param id 行政区划主键 |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
public int deleteSysAreaById(Long id); |
||||
|
|
||||
|
/** |
||||
|
* 批量删除行政区划 |
||||
|
* |
||||
|
* @param ids 需要删除的数据主键集合 |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
public int deleteSysAreaByIds(Long[] ids); |
||||
|
} |
||||
@ -0,0 +1,61 @@ |
|||||
|
package com.chenhai.system.service; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import com.chenhai.common.core.domain.entity.SysArea; |
||||
|
|
||||
|
/** |
||||
|
* 行政区划Service接口 |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
* @date 2026-01-09 |
||||
|
*/ |
||||
|
public interface ISysAreaService |
||||
|
{ |
||||
|
/** |
||||
|
* 查询行政区划 |
||||
|
* |
||||
|
* @param id 行政区划主键 |
||||
|
* @return 行政区划 |
||||
|
*/ |
||||
|
public SysArea selectSysAreaById(Long id); |
||||
|
|
||||
|
/** |
||||
|
* 查询行政区划列表 |
||||
|
* |
||||
|
* @param sysArea 行政区划 |
||||
|
* @return 行政区划集合 |
||||
|
*/ |
||||
|
public List<SysArea> selectSysAreaList(SysArea sysArea); |
||||
|
|
||||
|
/** |
||||
|
* 新增行政区划 |
||||
|
* |
||||
|
* @param sysArea 行政区划 |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
public int insertSysArea(SysArea sysArea); |
||||
|
|
||||
|
/** |
||||
|
* 修改行政区划 |
||||
|
* |
||||
|
* @param sysArea 行政区划 |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
public int updateSysArea(SysArea sysArea); |
||||
|
|
||||
|
/** |
||||
|
* 批量删除行政区划 |
||||
|
* |
||||
|
* @param ids 需要删除的行政区划主键集合 |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
public int deleteSysAreaByIds(Long[] ids); |
||||
|
|
||||
|
/** |
||||
|
* 删除行政区划信息 |
||||
|
* |
||||
|
* @param id 行政区划主键 |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
public int deleteSysAreaById(Long id); |
||||
|
} |
||||
@ -0,0 +1,96 @@ |
|||||
|
package com.chenhai.system.service.impl; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import com.chenhai.common.utils.DateUtils; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import com.chenhai.system.mapper.SysAreaMapper; |
||||
|
import com.chenhai.common.core.domain.entity.SysArea; |
||||
|
import com.chenhai.system.service.ISysAreaService; |
||||
|
|
||||
|
/** |
||||
|
* 行政区划Service业务层处理 |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
* @date 2026-01-09 |
||||
|
*/ |
||||
|
@Service |
||||
|
public class SysAreaServiceImpl implements ISysAreaService |
||||
|
{ |
||||
|
@Autowired |
||||
|
private SysAreaMapper sysAreaMapper; |
||||
|
|
||||
|
/** |
||||
|
* 查询行政区划 |
||||
|
* |
||||
|
* @param id 行政区划主键 |
||||
|
* @return 行政区划 |
||||
|
*/ |
||||
|
@Override |
||||
|
public SysArea selectSysAreaById(Long id) |
||||
|
{ |
||||
|
return sysAreaMapper.selectSysAreaById(id); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询行政区划列表 |
||||
|
* |
||||
|
* @param sysArea 行政区划 |
||||
|
* @return 行政区划 |
||||
|
*/ |
||||
|
@Override |
||||
|
public List<SysArea> selectSysAreaList(SysArea sysArea) |
||||
|
{ |
||||
|
return sysAreaMapper.selectSysAreaList(sysArea); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 新增行政区划 |
||||
|
* |
||||
|
* @param sysArea 行政区划 |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
@Override |
||||
|
public int insertSysArea(SysArea sysArea) |
||||
|
{ |
||||
|
sysArea.setCreateTime(DateUtils.getNowDate()); |
||||
|
return sysAreaMapper.insertSysArea(sysArea); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 修改行政区划 |
||||
|
* |
||||
|
* @param sysArea 行政区划 |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
@Override |
||||
|
public int updateSysArea(SysArea sysArea) |
||||
|
{ |
||||
|
sysArea.setUpdateTime(DateUtils.getNowDate()); |
||||
|
return sysAreaMapper.updateSysArea(sysArea); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 批量删除行政区划 |
||||
|
* |
||||
|
* @param ids 需要删除的行政区划主键 |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
@Override |
||||
|
public int deleteSysAreaByIds(Long[] ids) |
||||
|
{ |
||||
|
return sysAreaMapper.deleteSysAreaByIds(ids); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除行政区划信息 |
||||
|
* |
||||
|
* @param id 行政区划主键 |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
@Override |
||||
|
public int deleteSysAreaById(Long id) |
||||
|
{ |
||||
|
return sysAreaMapper.deleteSysAreaById(id); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,116 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<!DOCTYPE mapper |
||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
<mapper namespace="com.chenhai.system.mapper.SysAreaMapper"> |
||||
|
|
||||
|
<resultMap type="SysArea" id="SysAreaResult"> |
||||
|
<result property="id" column="id" /> |
||||
|
<result property="name" column="name" /> |
||||
|
<result property="code" column="code" /> |
||||
|
<result property="parentCode" column="parent_code" /> |
||||
|
<result property="type" column="type" /> |
||||
|
<result property="sort" column="sort" /> |
||||
|
<result property="status" column="status" /> |
||||
|
<result property="namePath" column="name_path" /> |
||||
|
<result property="codePath" column="code_path" /> |
||||
|
<result property="createBy" column="create_by" /> |
||||
|
<result property="createTime" column="create_time" /> |
||||
|
<result property="updateBy" column="update_by" /> |
||||
|
<result property="updateTime" column="update_time" /> |
||||
|
<result property="deleted" column="deleted" /> |
||||
|
<result property="remark" column="remark" /> |
||||
|
</resultMap> |
||||
|
|
||||
|
<sql id="selectSysAreaVo"> |
||||
|
select id, name, code, parent_code, type, sort, status, name_path, code_path, create_by, create_time, update_by, update_time, deleted, remark from sys_area |
||||
|
</sql> |
||||
|
|
||||
|
<select id="selectSysAreaList" parameterType="SysArea" resultMap="SysAreaResult"> |
||||
|
<include refid="selectSysAreaVo"/> |
||||
|
<where> |
||||
|
<if test="name != null and name != ''"> and name like concat('%', #{name}, '%')</if> |
||||
|
<if test="code != null and code != ''"> and code = #{code}</if> |
||||
|
<if test="parentCode != null and parentCode != ''"> and parent_code = #{parentCode}</if> |
||||
|
<if test="type != null "> and type = #{type}</if> |
||||
|
<if test="sort != null "> and sort = #{sort}</if> |
||||
|
<if test="status != null "> and status = #{status}</if> |
||||
|
<if test="namePath != null and namePath != ''"> and name_path = #{namePath}</if> |
||||
|
<if test="codePath != null and codePath != ''"> and code_path = #{codePath}</if> |
||||
|
<if test="deleted != null "> and deleted = #{deleted}</if> |
||||
|
</where> |
||||
|
</select> |
||||
|
|
||||
|
<select id="selectSysAreaById" parameterType="Long" resultMap="SysAreaResult"> |
||||
|
<include refid="selectSysAreaVo"/> |
||||
|
where id = #{id} |
||||
|
</select> |
||||
|
|
||||
|
<insert id="insertSysArea" parameterType="SysArea" useGeneratedKeys="true" keyProperty="id"> |
||||
|
insert into sys_area |
||||
|
<trim prefix="(" suffix=")" suffixOverrides=","> |
||||
|
<if test="name != null and name != ''">name,</if> |
||||
|
<if test="code != null and code != ''">code,</if> |
||||
|
<if test="parentCode != null and parentCode != ''">parent_code,</if> |
||||
|
<if test="type != null">type,</if> |
||||
|
<if test="sort != null">sort,</if> |
||||
|
<if test="status != null">status,</if> |
||||
|
<if test="namePath != null">name_path,</if> |
||||
|
<if test="codePath != null">code_path,</if> |
||||
|
<if test="createBy != null">create_by,</if> |
||||
|
<if test="createTime != null">create_time,</if> |
||||
|
<if test="updateBy != null">update_by,</if> |
||||
|
<if test="updateTime != null">update_time,</if> |
||||
|
<if test="deleted != null">deleted,</if> |
||||
|
<if test="remark != null">remark,</if> |
||||
|
</trim> |
||||
|
<trim prefix="values (" suffix=")" suffixOverrides=","> |
||||
|
<if test="name != null and name != ''">#{name},</if> |
||||
|
<if test="code != null and code != ''">#{code},</if> |
||||
|
<if test="parentCode != null and parentCode != ''">#{parentCode},</if> |
||||
|
<if test="type != null">#{type},</if> |
||||
|
<if test="sort != null">#{sort},</if> |
||||
|
<if test="status != null">#{status},</if> |
||||
|
<if test="namePath != null">#{namePath},</if> |
||||
|
<if test="codePath != null">#{codePath},</if> |
||||
|
<if test="createBy != null">#{createBy},</if> |
||||
|
<if test="createTime != null">#{createTime},</if> |
||||
|
<if test="updateBy != null">#{updateBy},</if> |
||||
|
<if test="updateTime != null">#{updateTime},</if> |
||||
|
<if test="deleted != null">#{deleted},</if> |
||||
|
<if test="remark != null">#{remark},</if> |
||||
|
</trim> |
||||
|
</insert> |
||||
|
|
||||
|
<update id="updateSysArea" parameterType="SysArea"> |
||||
|
update sys_area |
||||
|
<trim prefix="SET" suffixOverrides=","> |
||||
|
<if test="name != null and name != ''">name = #{name},</if> |
||||
|
<if test="code != null and code != ''">code = #{code},</if> |
||||
|
<if test="parentCode != null and parentCode != ''">parent_code = #{parentCode},</if> |
||||
|
<if test="type != null">type = #{type},</if> |
||||
|
<if test="sort != null">sort = #{sort},</if> |
||||
|
<if test="status != null">status = #{status},</if> |
||||
|
<if test="namePath != null">name_path = #{namePath},</if> |
||||
|
<if test="codePath != null">code_path = #{codePath},</if> |
||||
|
<if test="createBy != null">create_by = #{createBy},</if> |
||||
|
<if test="createTime != null">create_time = #{createTime},</if> |
||||
|
<if test="updateBy != null">update_by = #{updateBy},</if> |
||||
|
<if test="updateTime != null">update_time = #{updateTime},</if> |
||||
|
<if test="deleted != null">deleted = #{deleted},</if> |
||||
|
<if test="remark != null">remark = #{remark},</if> |
||||
|
</trim> |
||||
|
where id = #{id} |
||||
|
</update> |
||||
|
|
||||
|
<delete id="deleteSysAreaById" parameterType="Long"> |
||||
|
delete from sys_area where id = #{id} |
||||
|
</delete> |
||||
|
|
||||
|
<delete id="deleteSysAreaByIds" parameterType="String"> |
||||
|
delete from sys_area where id in |
||||
|
<foreach item="id" collection="array" open="(" separator="," close=")"> |
||||
|
#{id} |
||||
|
</foreach> |
||||
|
</delete> |
||||
|
</mapper> |
||||
@ -0,0 +1,63 @@ |
|||||
|
import request from '@/utils/request' |
||||
|
|
||||
|
// 查询行政区划列表
|
||||
|
export function listArea(query) { |
||||
|
return request({ |
||||
|
url: '/system/area/list', |
||||
|
method: 'get', |
||||
|
params: query |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 查询行政区划详细
|
||||
|
export function getArea(id) { |
||||
|
return request({ |
||||
|
url: '/system/area/' + id, |
||||
|
method: 'get' |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 新增行政区划
|
||||
|
export function addArea(data) { |
||||
|
return request({ |
||||
|
url: '/system/area', |
||||
|
method: 'post', |
||||
|
data: data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 修改行政区划
|
||||
|
export function updateArea(data) { |
||||
|
return request({ |
||||
|
url: '/system/area', |
||||
|
method: 'put', |
||||
|
data: data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 删除行政区划
|
||||
|
export function delArea(id) { |
||||
|
return request({ |
||||
|
url: '/system/area/' + id, |
||||
|
method: 'delete' |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// ========== 新增的接口 ==========
|
||||
|
|
||||
|
// 懒加载查询子节点
|
||||
|
export function listChildren(parentCode) { |
||||
|
return request({ |
||||
|
url: '/system/area/children', |
||||
|
method: 'get', |
||||
|
params: { parentCode } |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 查询所有省级节点
|
||||
|
export function listProvinces() { |
||||
|
return request({ |
||||
|
url: '/system/area/provinces', |
||||
|
method: 'get' |
||||
|
}) |
||||
|
} |
||||
@ -0,0 +1 @@ |
|||||
|
<svg t="1768374664236" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7455" width="200" height="200"><path d="M484.751579 529.237872c4.782757 0 9.621781 0.393874 14.517074 0.393874a264.795926 264.795926 0 1 0-145.227005-43.607489 471.861163 471.861163 0 0 0-172.404317 106.627344C95.435172 675.927837 38.661035 789.869986 21.724449 914.109128a99.593878 99.593878 0 0 0 23.238572 78.774819 88.509135 88.509135 0 0 0 66.452186 30.834714h345.315044a33.760637 33.760637 0 0 0 0-67.521273H111.358939a21.156666 21.156666 0 0 1-15.58616-7.708678 32.128872 32.128872 0 0 1-7.202269-25.545549c29.934431-219.162799 198.906417-385.884076 396.181069-393.705289zM303.850835 265.173426A195.474086 195.474086 0 1 1 499.043582 460.647512 195.699156 195.699156 0 0 1 303.850835 265.173426z" fill="#6CAB86" p-id="7456"></path><path d="M991.83634 613.47066l-34.15451-34.041975a36.348952 36.348952 0 0 0-51.2599 0l-42.763473 42.538402 85.526946 85.133071 42.707205-42.482134a35.955078 35.955078 0 0 0-0.056268-51.147364zM615.292707 869.151214l85.526946 85.133072 232.385715-229.516061-85.470678-85.133072-232.441983 229.516061zM546.758615 1023.831197v0.168803l136.67431-53.848215-84.739197-84.345324-51.935113 138.024736z" fill="#6CAB86" p-id="7457"></path></svg> |
||||
@ -0,0 +1,426 @@ |
|||||
|
<template> |
||||
|
<div class="app-container"> |
||||
|
<!-- 懒加载树 --> |
||||
|
<div class="tree-wrapper"> |
||||
|
<el-tree |
||||
|
ref="areaTree" |
||||
|
:data="treeData" |
||||
|
:props="treeProps" |
||||
|
node-key="id" |
||||
|
highlight-current |
||||
|
:expand-on-click-node="false" |
||||
|
:load="loadNode" |
||||
|
lazy |
||||
|
@node-click="handleNodeClick" |
||||
|
:render-content="renderContent" |
||||
|
v-loading="loading" |
||||
|
> |
||||
|
</el-tree> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 对话框 --> |
||||
|
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="450px" append-to-body> |
||||
|
<el-form ref="form" :model="form" :rules="rules" label-width="80px"> |
||||
|
<el-form-item label="父节点"> |
||||
|
<el-input v-model="form.parentName" disabled size="small" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="名称" prop="name"> |
||||
|
<el-input v-model="form.name" placeholder="请输入名称" size="small" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="编码" prop="code"> |
||||
|
<el-input v-model="form.code" placeholder="请输入编码" size="small" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="类型" prop="type"> |
||||
|
<el-select v-model="form.type" placeholder="请选择" size="small" style="width: 100%"> |
||||
|
<el-option label="省级" :value="2" /> |
||||
|
<el-option label="市级" :value="3" /> |
||||
|
<el-option label="区县级" :value="4" /> |
||||
|
<el-option label="街道/乡镇" :value="5" /> |
||||
|
<el-option label="村/社区" :value="6" /> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="显示顺序"> |
||||
|
<el-input-number v-model="form.sort" :min="0" size="small" style="width: 100%" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="状态"> |
||||
|
<el-radio-group v-model="form.status" size="small"> |
||||
|
<el-radio :label="0">开启</el-radio> |
||||
|
<el-radio :label="1">关闭</el-radio> |
||||
|
</el-radio-group> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="备注"> |
||||
|
<el-input v-model="form.remark" type="textarea" :rows="2" size="small" /> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
<div slot="footer"> |
||||
|
<el-button @click="dialogVisible = false" size="small">取消</el-button> |
||||
|
<el-button type="primary" @click="submitForm" size="small">确定</el-button> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { listArea, getArea, addArea, updateArea, listChildren, listProvinces } from "@/api/system/area" |
||||
|
|
||||
|
export default { |
||||
|
name: "Area", |
||||
|
data() { |
||||
|
return { |
||||
|
loading: false, |
||||
|
dialogVisible: false, |
||||
|
dialogTitle: "", |
||||
|
currentNode: null, |
||||
|
treeData: [], |
||||
|
treeProps: { |
||||
|
label: 'name', |
||||
|
children: 'children', |
||||
|
isLeaf: 'leaf' |
||||
|
}, |
||||
|
form: { |
||||
|
id: null, |
||||
|
parentCode: "", |
||||
|
parentName: "", |
||||
|
name: "", |
||||
|
code: "", |
||||
|
type: 2, |
||||
|
sort: 0, |
||||
|
status: 0, |
||||
|
remark: "" |
||||
|
}, |
||||
|
rules: { |
||||
|
name: [ |
||||
|
{ required: true, message: "名称不能为空", trigger: "blur" } |
||||
|
], |
||||
|
code: [ |
||||
|
{ required: true, message: "编码不能为空", trigger: "blur" } |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
created() { |
||||
|
this.loadProvinces() |
||||
|
}, |
||||
|
methods: { |
||||
|
// 加载省级 |
||||
|
async loadProvinces() { |
||||
|
this.loading = true |
||||
|
try { |
||||
|
const response = await listProvinces() |
||||
|
this.treeData = (response.data || response).map(item => ({ |
||||
|
...item, |
||||
|
leaf: item.type >= 6 |
||||
|
})) |
||||
|
} catch (error) { |
||||
|
console.error("加载失败:", error) |
||||
|
this.$modal.msgError("加载数据失败") |
||||
|
} finally { |
||||
|
this.loading = false |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 懒加载子节点 |
||||
|
async loadNode(node, resolve) { |
||||
|
if (node.level === 0) return resolve(this.treeData) |
||||
|
|
||||
|
try { |
||||
|
const response = await listChildren(node.data.code) |
||||
|
const children = (response.data || response).map(item => ({ |
||||
|
...item, |
||||
|
leaf: item.type >= 6 |
||||
|
})) |
||||
|
resolve(children) |
||||
|
} catch (error) { |
||||
|
console.error("加载子节点失败:", error) |
||||
|
resolve([]) |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 渲染节点 - 只有查看和添加功能 |
||||
|
renderContent(h, { node, data }) { |
||||
|
return h('div', { |
||||
|
class: 'tree-node', |
||||
|
style: { |
||||
|
display: 'flex', |
||||
|
alignItems: 'center', |
||||
|
width: '100%', |
||||
|
fontSize: '12px', |
||||
|
padding: '4px 0' |
||||
|
} |
||||
|
}, [ |
||||
|
// 节点信息(可点击查看/编辑) |
||||
|
h('span', { |
||||
|
style: { flex: 1 }, |
||||
|
on: { |
||||
|
click: (e) => { |
||||
|
e.stopPropagation() |
||||
|
this.handleNodeClick(data) |
||||
|
this.handleUpdate(data) |
||||
|
} |
||||
|
} |
||||
|
}, [ |
||||
|
h('span', { |
||||
|
style: { |
||||
|
marginRight: '8px', |
||||
|
cursor: 'pointer', |
||||
|
color: '#606266', |
||||
|
textDecoration: 'none' |
||||
|
}, |
||||
|
class: 'node-label' |
||||
|
}, node.label), |
||||
|
h('el-tag', { |
||||
|
props: { |
||||
|
size: 'mini', |
||||
|
type: data.status === 0 ? 'success' : 'danger' |
||||
|
}, |
||||
|
style: { marginRight: '5px' } |
||||
|
}, data.status === 0 ? '开启' : '关闭'), |
||||
|
h('el-tag', { |
||||
|
props: { |
||||
|
size: 'mini', |
||||
|
type: this.getTypeTag(data.type) |
||||
|
} |
||||
|
}, this.getTypeName(data.type)) |
||||
|
]), |
||||
|
|
||||
|
// 只有添加按钮(没有删除) |
||||
|
h('span', { |
||||
|
style: { |
||||
|
display: 'flex', |
||||
|
gap: '8px', |
||||
|
opacity: 0.7, |
||||
|
transition: 'opacity 0.3s' |
||||
|
}, |
||||
|
on: { |
||||
|
mouseenter: (e) => { e.currentTarget.style.opacity = 1 }, |
||||
|
mouseleave: (e) => { e.currentTarget.style.opacity = 0.7 } |
||||
|
} |
||||
|
}, [ |
||||
|
// 添加子节点按钮(如果不是最后一级) |
||||
|
data.type < 6 && h('el-button', { |
||||
|
props: { |
||||
|
type: 'text', |
||||
|
size: 'mini', |
||||
|
icon: 'el-icon-plus', |
||||
|
title: '添加子节点' |
||||
|
}, |
||||
|
style: { |
||||
|
color: '#409EFF', |
||||
|
padding: '2px' |
||||
|
}, |
||||
|
on: { |
||||
|
click: (e) => { |
||||
|
e.stopPropagation() |
||||
|
this.handleAdd(data) |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
]) |
||||
|
]) |
||||
|
}, |
||||
|
|
||||
|
// 节点点击 |
||||
|
handleNodeClick(data) { |
||||
|
this.currentNode = data |
||||
|
this.$refs.areaTree.setCurrentKey(data.id) |
||||
|
}, |
||||
|
|
||||
|
// 新增(点击加号按钮) |
||||
|
handleAdd(parentNode) { |
||||
|
this.resetForm() |
||||
|
this.dialogTitle = "新增行政区划" |
||||
|
|
||||
|
if (parentNode) { |
||||
|
this.form.parentCode = parentNode.code |
||||
|
this.form.parentName = parentNode.name |
||||
|
this.form.type = Math.min(parentNode.type + 1, 6) |
||||
|
} else { |
||||
|
// 如果需要新增省级,可以在这里处理 |
||||
|
this.form.parentCode = "" |
||||
|
this.form.parentName = "" |
||||
|
this.form.type = 2 |
||||
|
} |
||||
|
|
||||
|
this.dialogVisible = true |
||||
|
}, |
||||
|
|
||||
|
// 修改(点击节点名称) |
||||
|
async handleUpdate(node) { |
||||
|
if (!node) node = this.currentNode |
||||
|
if (!node) { |
||||
|
this.$modal.msgWarning("请先选择一个节点") |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
this.resetForm() |
||||
|
this.dialogTitle = "修改行政区划" |
||||
|
this.currentNode = node |
||||
|
|
||||
|
// 获取父节点名称 |
||||
|
let parentName = "" |
||||
|
if (node.parentCode) { |
||||
|
try { |
||||
|
const response = await listArea({ code: node.parentCode }) |
||||
|
const parentList = response.rows || response.data || response |
||||
|
if (parentList.length > 0) parentName = parentList[0].name |
||||
|
} catch (error) { |
||||
|
console.error("获取父节点失败:", error) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
this.form = { |
||||
|
id: node.id, |
||||
|
parentCode: node.parentCode || "", |
||||
|
parentName: parentName || "无", |
||||
|
name: node.name, |
||||
|
code: node.code, |
||||
|
type: node.type, |
||||
|
sort: node.sort || 0, |
||||
|
status: node.status || 0, |
||||
|
remark: node.remark || "" |
||||
|
} |
||||
|
|
||||
|
this.dialogVisible = true |
||||
|
}, |
||||
|
|
||||
|
// 提交表单 |
||||
|
submitForm() { |
||||
|
this.$refs["form"].validate(valid => { |
||||
|
if (valid) { |
||||
|
const promise = this.form.id ? updateArea(this.form) : addArea(this.form) |
||||
|
|
||||
|
promise.then(response => { |
||||
|
this.$modal.msgSuccess(this.form.id ? "修改成功" : "新增成功") |
||||
|
this.dialogVisible = false |
||||
|
this.refreshTree() |
||||
|
}).catch(error => { |
||||
|
console.error("保存失败:", error) |
||||
|
this.$modal.msgError("保存失败:" + (error.message || "请检查数据")) |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
// 重置表单 |
||||
|
resetForm() { |
||||
|
this.form = { |
||||
|
id: null, |
||||
|
parentCode: "", |
||||
|
parentName: "", |
||||
|
name: "", |
||||
|
code: "", |
||||
|
type: 2, |
||||
|
sort: 0, |
||||
|
status: 0, |
||||
|
remark: "" |
||||
|
} |
||||
|
if (this.$refs.form) { |
||||
|
this.$refs.form.clearValidate() |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 刷新整个树 |
||||
|
refreshTree() { |
||||
|
this.loadProvinces() |
||||
|
this.currentNode = null |
||||
|
if (this.$refs.areaTree) { |
||||
|
this.$refs.areaTree.setCurrentKey(null) |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 获取类型标签颜色 |
||||
|
getTypeTag(type) { |
||||
|
const map = { |
||||
|
1: '', // 国家 |
||||
|
2: 'info', // 省 |
||||
|
3: 'primary', // 市 |
||||
|
4: 'warning', // 区县 |
||||
|
5: 'success', // 街道 |
||||
|
6: 'danger' // 村社 |
||||
|
} |
||||
|
return map[type] || '' |
||||
|
}, |
||||
|
|
||||
|
// 获取类型名称 |
||||
|
getTypeName(type) { |
||||
|
const map = { |
||||
|
1: '国家', |
||||
|
2: '省', |
||||
|
3: '市', |
||||
|
4: '区县', |
||||
|
5: '街道', |
||||
|
6: '村社' |
||||
|
} |
||||
|
return map[type] || '未知' |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.app-container { |
||||
|
padding: 15px; |
||||
|
background: #f5f7fa; |
||||
|
min-height: calc(100vh - 50px); |
||||
|
} |
||||
|
|
||||
|
.tree-wrapper { |
||||
|
background: white; |
||||
|
border-radius: 4px; |
||||
|
padding: 15px; |
||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); |
||||
|
min-height: 600px; |
||||
|
} |
||||
|
|
||||
|
/* 紧凑样式 */ |
||||
|
:deep(.el-tree) { |
||||
|
font-size: 12px !important; |
||||
|
} |
||||
|
|
||||
|
:deep(.el-tree-node__content) { |
||||
|
height: 36px !important; |
||||
|
margin: 2px 0; |
||||
|
border-radius: 4px; |
||||
|
} |
||||
|
|
||||
|
:deep(.el-tree-node__content:hover) { |
||||
|
background-color: #f5f7fa; |
||||
|
} |
||||
|
|
||||
|
:deep(.el-tree-node__label) { |
||||
|
font-size: 12px !important; |
||||
|
} |
||||
|
|
||||
|
:deep(.el-tree-node__expand-icon) { |
||||
|
font-size: 12px !important; |
||||
|
padding: 6px !important; |
||||
|
} |
||||
|
|
||||
|
:deep(.el-tag) { |
||||
|
height: 18px !important; |
||||
|
line-height: 16px !important; |
||||
|
padding: 0 5px !important; |
||||
|
font-size: 10px !important; |
||||
|
} |
||||
|
|
||||
|
:deep(.el-button--mini) { |
||||
|
padding: 3px 6px !important; |
||||
|
font-size: 10px !important; |
||||
|
} |
||||
|
|
||||
|
/* 节点标签样式 */ |
||||
|
.node-label { |
||||
|
transition: color 0.3s; |
||||
|
} |
||||
|
|
||||
|
.node-label:hover { |
||||
|
color: #409EFF !important; |
||||
|
text-decoration: underline !important; |
||||
|
} |
||||
|
|
||||
|
/* 当前选中节点样式 */ |
||||
|
:deep(.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content) { |
||||
|
background-color: #ecf5ff !important; |
||||
|
border-left: 3px solid #409EFF; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,736 @@ |
|||||
|
<template> |
||||
|
<div class="app-container"> |
||||
|
<el-row :gutter="20"> |
||||
|
<splitpanes :horizontal="this.$store.getters.device === 'mobile'" class="default-theme"> |
||||
|
<!--行政区划数据--> |
||||
|
<pane size="16"> |
||||
|
<el-col> |
||||
|
<div class="head-container"> |
||||
|
<el-input v-model="areaName" placeholder="请输入行政区划名称" clearable size="small" prefix-icon="el-icon-search" style="margin-bottom: 20px" @keyup.enter.native="handleAreaSearch" /> |
||||
|
</div> |
||||
|
<div class="head-container"> |
||||
|
<el-tree |
||||
|
:data="areaOptions" |
||||
|
:props="defaultProps" |
||||
|
:expand-on-click-node="false" |
||||
|
:filter-node-method="filterNode" |
||||
|
:load="loadNode" |
||||
|
lazy |
||||
|
:highlight-current="true" |
||||
|
node-key="code" |
||||
|
ref="tree" |
||||
|
@node-click="handleNodeClick" |
||||
|
class="area-tree"> |
||||
|
<span class="custom-tree-node" slot-scope="{ node, data }"> |
||||
|
<span>{{ node.label }}</span> |
||||
|
<span v-if="node.childNodes && node.childNodes.length > 0" class="tree-expand-icon"> |
||||
|
<i v-if="node.expanded" class="el-icon-caret-bottom"></i> |
||||
|
<i v-else class="el-icon-caret-right"></i> |
||||
|
</span> |
||||
|
</span> |
||||
|
</el-tree> |
||||
|
</div> |
||||
|
</el-col> |
||||
|
</pane> |
||||
|
<!--用户数据--> |
||||
|
<pane size="84"> |
||||
|
<el-col> |
||||
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> |
||||
|
<el-form-item label="用户名称" prop="userName"> |
||||
|
<el-input v-model="queryParams.userName" placeholder="请输入用户名称" clearable style="width: 240px" @keyup.enter.native="handleQuery" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="手机号码" prop="phonenumber"> |
||||
|
<el-input v-model="queryParams.phonenumber" placeholder="请输入手机号码" clearable style="width: 240px" @keyup.enter.native="handleQuery" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="用户类型" prop="userType"> |
||||
|
<el-select v-model="queryParams.userType" placeholder="请选择用户类型" clearable style="width: 240px"> |
||||
|
<el-option |
||||
|
v-for="dict in dict.type.sys_user_type" |
||||
|
:key="dict.value" |
||||
|
:label="dict.label" |
||||
|
:value="dict.value" |
||||
|
/> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
<!-- <el-form-item label="行政区划" prop="areaName">--> |
||||
|
<!-- <el-input v-model="currentAreaName" placeholder="点击左侧选择行政区划" readonly style="width: 240px" />--> |
||||
|
<!-- </el-form-item>--> |
||||
|
<el-form-item label="状态" prop="status"> |
||||
|
<el-select v-model="queryParams.status" placeholder="用户状态" clearable style="width: 240px"> |
||||
|
<el-option v-for="dict in dict.type.sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" /> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="创建时间"> |
||||
|
<el-date-picker v-model="dateRange" style="width: 240px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker> |
||||
|
</el-form-item> |
||||
|
<el-form-item> |
||||
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> |
||||
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
|
||||
|
<el-row :gutter="10" class="mb8"> |
||||
|
<el-col :span="1.5"> |
||||
|
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['system:user:add']">新增</el-button> |
||||
|
</el-col> |
||||
|
<el-col :span="1.5"> |
||||
|
<el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate" v-hasPermi="['system:user:edit']">修改</el-button> |
||||
|
</el-col> |
||||
|
<el-col :span="1.5"> |
||||
|
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete" v-hasPermi="['system:user:remove']">删除</el-button> |
||||
|
</el-col> |
||||
|
<el-col :span="1.5"> |
||||
|
<el-button type="info" plain icon="el-icon-upload2" size="mini" @click="handleImport" v-hasPermi="['system:user:import']">导入</el-button> |
||||
|
</el-col> |
||||
|
<el-col :span="1.5"> |
||||
|
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['system:user:export']">导出</el-button> |
||||
|
</el-col> |
||||
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar> |
||||
|
</el-row> |
||||
|
|
||||
|
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange"> |
||||
|
<el-table-column type="selection" width="50" align="center" /> |
||||
|
<el-table-column label="用户编号" align="center" key="userId" prop="userId" v-if="columns.userId.visible" /> |
||||
|
<el-table-column label="用户名称" align="center" key="userName" prop="userName" v-if="columns.userName.visible" :show-overflow-tooltip="true" /> |
||||
|
<el-table-column label="用户昵称" align="center" key="nickName" prop="nickName" v-if="columns.nickName.visible" :show-overflow-tooltip="true" /> |
||||
|
<el-table-column label="用户类型" align="center" key="userType" prop="userType" v-if="columns.userType.visible"> |
||||
|
<template slot-scope="scope"> |
||||
|
<dict-tag :options="dict.type.sys_user_type" :value="scope.row.userType"/> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="行政区划" align="center" key="areaName" prop="area.name" v-if="columns.areaName.visible" :show-overflow-tooltip="true" /> |
||||
|
<el-table-column label="手机号码" align="center" key="phonenumber" prop="phonenumber" v-if="columns.phonenumber.visible" width="120" /> |
||||
|
<el-table-column label="状态" align="center" key="status" v-if="columns.status.visible"> |
||||
|
<template slot-scope="scope"> |
||||
|
<el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="创建时间" align="center" prop="createTime" v-if="columns.createTime.visible" width="160"> |
||||
|
<template slot-scope="scope"> |
||||
|
<span>{{ parseTime(scope.row.createTime) }}</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="操作" align="center" width="160" class-name="small-padding fixed-width"> |
||||
|
<template slot-scope="scope" v-if="scope.row.userId !== 1"> |
||||
|
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:user:edit']">修改</el-button> |
||||
|
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['system:user:remove']">删除</el-button> |
||||
|
<el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['system:user:resetPwd', 'system:user:edit']"> |
||||
|
<el-button size="mini" type="text" icon="el-icon-d-arrow-right">更多</el-button> |
||||
|
<el-dropdown-menu slot="dropdown"> |
||||
|
<el-dropdown-item command="handleResetPwd" icon="el-icon-key" v-hasPermi="['system:user:resetPwd']">重置密码</el-dropdown-item> |
||||
|
<el-dropdown-item command="handleAuthRole" icon="el-icon-circle-check" v-hasPermi="['system:user:edit']">分配角色</el-dropdown-item> |
||||
|
</el-dropdown-menu> |
||||
|
</el-dropdown> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
|
||||
|
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" /> |
||||
|
</el-col> |
||||
|
</pane> |
||||
|
</splitpanes> |
||||
|
</el-row> |
||||
|
|
||||
|
<!-- 添加或修改用户配置对话框 --> |
||||
|
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body> |
||||
|
<el-form ref="form" :model="form" :rules="rules" label-width="80px"> |
||||
|
<el-row> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item label="用户昵称" prop="nickName"> |
||||
|
<el-input v-model="form.nickName" placeholder="请输入用户昵称" maxlength="30" /> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item label="用户类型" prop="userType"> |
||||
|
<el-select v-model="form.userType" placeholder="请选择用户类型"> |
||||
|
<el-option |
||||
|
v-for="dict in dict.type.sys_user_type" |
||||
|
:key="dict.value" |
||||
|
:label="dict.label" |
||||
|
:value="dict.value" |
||||
|
/> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
<el-row> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item label="归属行政区划" prop="areaCode"> |
||||
|
<treeselect |
||||
|
v-model="form.areaCode" |
||||
|
:options="areaSelectOptions" |
||||
|
:load-options="loadAreaOptions" |
||||
|
:auto-load-root-options="false" |
||||
|
placeholder="请选择归属行政区划" /> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item label="手机号码" prop="phonenumber"> |
||||
|
<el-input v-model="form.phonenumber" placeholder="请输入手机号码" maxlength="11" /> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
<el-row> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item label="邮箱" prop="email"> |
||||
|
<el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" /> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item v-if="form.userId == undefined" label="用户名称" prop="userName"> |
||||
|
<el-input v-model="form.userName" placeholder="请输入用户名称" maxlength="30" /> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
<el-row> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item v-if="form.userId == undefined" label="用户密码" prop="password"> |
||||
|
<el-input v-model="form.password" placeholder="请输入用户密码" type="password" maxlength="20" show-password /> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item label="用户性别"> |
||||
|
<el-select v-model="form.sex" placeholder="请选择性别"> |
||||
|
<el-option v-for="dict in dict.type.sys_user_sex" :key="dict.value" :label="dict.label" :value="dict.value"></el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
<el-row> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item label="状态"> |
||||
|
<el-radio-group v-model="form.status"> |
||||
|
<el-radio v-for="dict in dict.type.sys_normal_disable" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio> |
||||
|
</el-radio-group> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item label="岗位"> |
||||
|
<el-select v-model="form.postIds" multiple placeholder="请选择岗位"> |
||||
|
<el-option v-for="item in postOptions" :key="item.postId" :label="item.postName" :value="item.postId" :disabled="item.status == 1" ></el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
<el-row> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item label="角色"> |
||||
|
<el-select v-model="form.roleIds" multiple placeholder="请选择角色"> |
||||
|
<el-option v-for="item in roleOptions" :key="item.roleId" :label="item.roleName" :value="item.roleId" :disabled="item.status == 1"></el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item label="备注"> |
||||
|
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" style="width: 100%;"></el-input> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
</el-form> |
||||
|
<div slot="footer" class="dialog-footer"> |
||||
|
<el-button type="primary" @click="submitForm">确 定</el-button> |
||||
|
<el-button @click="cancel">取 消</el-button> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
|
||||
|
<!-- 用户导入对话框 --> |
||||
|
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body> |
||||
|
<el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag> |
||||
|
<i class="el-icon-upload"></i> |
||||
|
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> |
||||
|
<div class="el-upload__tip text-center" slot="tip"> |
||||
|
<div class="el-upload__tip" slot="tip"> |
||||
|
<el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据 |
||||
|
</div> |
||||
|
<span>仅允许导入xls、xlsx格式文件。</span> |
||||
|
<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="importTemplate">下载模板</el-link> |
||||
|
</div> |
||||
|
</el-upload> |
||||
|
<div slot="footer" class="dialog-footer"> |
||||
|
<el-button type="primary" @click="submitFileForm">确 定</el-button> |
||||
|
<el-button @click="upload.open = false">取 消</el-button> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { listUserByArea, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus, getAreaChildren, areaTreeSelect } from "@/api/system/user" |
||||
|
import { getToken } from "@/utils/auth" |
||||
|
import Treeselect from "@riophae/vue-treeselect" |
||||
|
import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect' |
||||
|
import "@riophae/vue-treeselect/dist/vue-treeselect.css" |
||||
|
import { Splitpanes, Pane } from "splitpanes" |
||||
|
import "splitpanes/dist/splitpanes.css" |
||||
|
|
||||
|
export default { |
||||
|
name: "User", |
||||
|
dicts: ['sys_normal_disable', 'sys_user_sex', 'sys_user_type'], |
||||
|
components: { Treeselect, Splitpanes, Pane }, |
||||
|
data() { |
||||
|
return { |
||||
|
// 遮罩层 |
||||
|
loading: true, |
||||
|
// 选中数组 |
||||
|
ids: [], |
||||
|
// 非单个禁用 |
||||
|
single: true, |
||||
|
// 非多个禁用 |
||||
|
multiple: true, |
||||
|
// 显示搜索条件 |
||||
|
showSearch: true, |
||||
|
// 总条数 |
||||
|
total: 0, |
||||
|
// 用户表格数据 |
||||
|
userList: null, |
||||
|
// 弹出层标题 |
||||
|
title: "", |
||||
|
// 行政区划树选项 |
||||
|
areaOptions: [], |
||||
|
// 行政区划选择框选项 |
||||
|
areaSelectOptions: [], |
||||
|
// 是否显示弹出层 |
||||
|
open: false, |
||||
|
// 行政区划搜索名称 |
||||
|
areaName: undefined, |
||||
|
// 当前选中的行政区划名称 |
||||
|
currentAreaName: "", |
||||
|
// 默认密码 |
||||
|
initPassword: undefined, |
||||
|
// 日期范围 |
||||
|
dateRange: [], |
||||
|
// 岗位选项 |
||||
|
postOptions: [], |
||||
|
// 角色选项 |
||||
|
roleOptions: [], |
||||
|
// 表单参数 |
||||
|
form: {}, |
||||
|
defaultProps: { |
||||
|
children: "children", |
||||
|
label: "name", |
||||
|
isLeaf: (data, node) => { |
||||
|
// 判断是否是叶子节点:如果没有hasChildren字段或者hasChildren为false,则是叶子节点 |
||||
|
return !data.hasChildren |
||||
|
} |
||||
|
}, |
||||
|
// 用户导入参数 |
||||
|
upload: { |
||||
|
// 是否显示弹出层(用户导入) |
||||
|
open: false, |
||||
|
// 弹出层标题(用户导入) |
||||
|
title: "", |
||||
|
// 是否禁用上传 |
||||
|
isUploading: false, |
||||
|
// 是否更新已经存在的用户数据 |
||||
|
updateSupport: 0, |
||||
|
// 设置上传的请求头部 |
||||
|
headers: { Authorization: "Bearer " + getToken() }, |
||||
|
// 上传的地址 |
||||
|
url: process.env.VUE_APP_BASE_API + "/system/user/importData" |
||||
|
}, |
||||
|
// 查询参数 |
||||
|
queryParams: { |
||||
|
pageNum: 1, |
||||
|
pageSize: 10, |
||||
|
userName: undefined, |
||||
|
phonenumber: undefined, |
||||
|
userType: undefined, |
||||
|
status: undefined, |
||||
|
areaCode: undefined, |
||||
|
areaName: undefined |
||||
|
}, |
||||
|
// 列信息 |
||||
|
columns: { |
||||
|
userId: { label: '用户编号', visible: true }, |
||||
|
userName: { label: '用户名称', visible: true }, |
||||
|
nickName: { label: '用户昵称', visible: true }, |
||||
|
userType: { label: '用户类型', visible: true }, |
||||
|
areaName: { label: '行政区划', visible: true }, |
||||
|
phonenumber: { label: '手机号码', visible: true }, |
||||
|
status: { label: '状态', visible: true }, |
||||
|
createTime: { label: '创建时间', visible: true } |
||||
|
}, |
||||
|
// 表单校验 |
||||
|
rules: { |
||||
|
userName: [ |
||||
|
{ required: true, message: "用户名称不能为空", trigger: "blur" }, |
||||
|
{ min: 2, max: 20, message: '用户名称长度必须介于 2 和 20 之间', trigger: 'blur' } |
||||
|
], |
||||
|
nickName: [ |
||||
|
{ required: true, message: "用户昵称不能为空", trigger: "blur" } |
||||
|
], |
||||
|
password: [ |
||||
|
{ required: true, message: "用户密码不能为空", trigger: "blur" }, |
||||
|
{ min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur' }, |
||||
|
{ pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" } |
||||
|
], |
||||
|
email: [ |
||||
|
{ |
||||
|
type: "email", |
||||
|
message: "请输入正确的邮箱地址", |
||||
|
trigger: ["blur", "change"] |
||||
|
} |
||||
|
], |
||||
|
phonenumber: [ |
||||
|
{ |
||||
|
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, |
||||
|
message: "请输入正确的手机号码", |
||||
|
trigger: "blur" |
||||
|
} |
||||
|
], |
||||
|
areaCode: [ |
||||
|
{ required: true, message: "归属行政区划不能为空", trigger: "blur" } |
||||
|
], |
||||
|
userType: [ |
||||
|
{ required: true, message: "用户类型不能为空", trigger: "blur" } |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
// 根据名称筛选行政区划树 |
||||
|
areaName(val) { |
||||
|
this.$refs.tree.filter(val) |
||||
|
} |
||||
|
}, |
||||
|
created() { |
||||
|
this.getList() |
||||
|
// 不再初始化加载顶层行政区划,由el-tree的懒加载处理 |
||||
|
this.getConfigKey("sys.user.initPassword").then(response => { |
||||
|
this.initPassword = response.msg |
||||
|
}) |
||||
|
}, |
||||
|
methods: { |
||||
|
/** 查询用户列表 */ |
||||
|
getList() { |
||||
|
this.loading = true |
||||
|
listUserByArea(this.addDateRange(this.queryParams, this.dateRange)).then(response => { |
||||
|
if (response.code === 200) { |
||||
|
this.userList = response.rows |
||||
|
this.total = response.total |
||||
|
this.loading = false |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
/** 懒加载行政区划节点 */ |
||||
|
loadNode(node, resolve) { |
||||
|
if (node.level === 0) { |
||||
|
// 第一级:加载阿拉善盟下的旗县 |
||||
|
getAreaChildren('152900').then(response => { |
||||
|
if (response.code === 200) { |
||||
|
const uniqueAreas = this.removeDuplicates(response.data, 'code') |
||||
|
// 为每个节点添加hasChildren字段,让el-tree知道哪些节点可以展开 |
||||
|
uniqueAreas.forEach(item => { |
||||
|
item.hasChildren = this.shouldHaveChildren(item.code) |
||||
|
}) |
||||
|
resolve(uniqueAreas) |
||||
|
} else { |
||||
|
resolve([]) |
||||
|
} |
||||
|
}).catch(error => { |
||||
|
console.error('加载行政区划失败:', error) |
||||
|
resolve([]) |
||||
|
}) |
||||
|
} else { |
||||
|
// 其他级:加载该节点的子节点 |
||||
|
getAreaChildren(node.data.code).then(response => { |
||||
|
if (response.code === 200) { |
||||
|
const uniqueAreas = this.removeDuplicates(response.data, 'code') |
||||
|
// 为每个节点添加hasChildren字段 |
||||
|
uniqueAreas.forEach(item => { |
||||
|
item.hasChildren = this.shouldHaveChildren(item.code) |
||||
|
}) |
||||
|
resolve(uniqueAreas) |
||||
|
} else { |
||||
|
resolve([]) |
||||
|
} |
||||
|
}).catch(error => { |
||||
|
console.error('加载行政区划子节点失败:', error) |
||||
|
resolve([]) |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
/** 去重方法 */ |
||||
|
removeDuplicates(array, key) { |
||||
|
const seen = new Set() |
||||
|
return array.filter(item => { |
||||
|
const value = item[key] |
||||
|
if (!seen.has(value)) { |
||||
|
seen.add(value) |
||||
|
return true |
||||
|
} |
||||
|
return false |
||||
|
}) |
||||
|
}, |
||||
|
/** 判断行政区划是否有子节点 */ |
||||
|
shouldHaveChildren(code) { |
||||
|
// 这里可以根据实际情况判断哪些编码应该有子节点 |
||||
|
// 比如:编码长度为6的可能是乡镇级别,不应该有子节点 |
||||
|
// 暂时返回true,让所有节点都可以展开 |
||||
|
return true |
||||
|
}, |
||||
|
/** 行政区划搜索 */ |
||||
|
handleAreaSearch() { |
||||
|
if (this.areaName) { |
||||
|
this.$refs.tree.filter(this.areaName) |
||||
|
} |
||||
|
}, |
||||
|
// 筛选节点 |
||||
|
filterNode(value, data) { |
||||
|
if (!value) return true |
||||
|
return data.name && data.name.indexOf(value) !== -1 |
||||
|
}, |
||||
|
// 节点单击事件 |
||||
|
handleNodeClick(data) { |
||||
|
this.queryParams.areaCode = data.code |
||||
|
this.currentAreaName = data.name |
||||
|
this.handleQuery() |
||||
|
}, |
||||
|
/** 懒加载行政区划选项(用于表单中的treeselect) */ |
||||
|
loadAreaOptions({ action, parentNode, callback }) { |
||||
|
if (action === LOAD_CHILDREN_OPTIONS) { |
||||
|
// 加载子节点 |
||||
|
const parentCode = parentNode.id || '152900' |
||||
|
getAreaChildren(parentCode).then(response => { |
||||
|
if (response.code === 200) { |
||||
|
const uniqueAreas = this.removeDuplicates(response.data, 'code') |
||||
|
|
||||
|
parentNode.children = uniqueAreas.map(item => ({ |
||||
|
id: item.code, |
||||
|
label: item.name, |
||||
|
children: item.hasChildren ? [] : null |
||||
|
})) |
||||
|
callback() |
||||
|
} else { |
||||
|
callback() |
||||
|
} |
||||
|
}).catch(() => { |
||||
|
callback() |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
/** 初始化行政区划选择框 */ |
||||
|
initAreaSelectOptions() { |
||||
|
// 初始化顶层选项 |
||||
|
this.areaSelectOptions = [{ |
||||
|
id: '152900', |
||||
|
label: '阿拉善盟', |
||||
|
children: [] |
||||
|
}] |
||||
|
}, |
||||
|
// 用户状态修改 |
||||
|
handleStatusChange(row) { |
||||
|
let text = row.status === "0" ? "启用" : "停用" |
||||
|
this.$modal.confirm('确认要"' + text + '""' + row.userName + '"用户吗?').then(function() { |
||||
|
return changeUserStatus(row.userId, row.status) |
||||
|
}).then(() => { |
||||
|
this.$modal.msgSuccess(text + "成功") |
||||
|
}).catch(function() { |
||||
|
row.status = row.status === "0" ? "1" : "0" |
||||
|
}) |
||||
|
}, |
||||
|
// 取消按钮 |
||||
|
cancel() { |
||||
|
this.open = false |
||||
|
this.reset() |
||||
|
}, |
||||
|
// 表单重置 |
||||
|
reset() { |
||||
|
this.form = { |
||||
|
userId: undefined, |
||||
|
areaCode: undefined, |
||||
|
userName: undefined, |
||||
|
nickName: undefined, |
||||
|
userType: undefined, |
||||
|
password: undefined, |
||||
|
phonenumber: undefined, |
||||
|
email: undefined, |
||||
|
sex: undefined, |
||||
|
status: "0", |
||||
|
remark: undefined, |
||||
|
postIds: [], |
||||
|
roleIds: [] |
||||
|
} |
||||
|
this.resetForm("form") |
||||
|
}, |
||||
|
/** 搜索按钮操作 */ |
||||
|
handleQuery() { |
||||
|
this.queryParams.pageNum = 1 |
||||
|
this.getList() |
||||
|
}, |
||||
|
/** 重置按钮操作 */ |
||||
|
resetQuery() { |
||||
|
this.dateRange = [] |
||||
|
this.resetForm("queryForm") |
||||
|
this.queryParams.areaCode = undefined |
||||
|
this.currentAreaName = "" |
||||
|
if (this.$refs.tree) { |
||||
|
this.$refs.tree.setCurrentKey(null) |
||||
|
} |
||||
|
this.handleQuery() |
||||
|
}, |
||||
|
// 多选框选中数据 |
||||
|
handleSelectionChange(selection) { |
||||
|
this.ids = selection.map(item => item.userId) |
||||
|
this.single = selection.length != 1 |
||||
|
this.multiple = !selection.length |
||||
|
}, |
||||
|
// 更多操作触发 |
||||
|
handleCommand(command, row) { |
||||
|
switch (command) { |
||||
|
case "handleResetPwd": |
||||
|
this.handleResetPwd(row) |
||||
|
break |
||||
|
case "handleAuthRole": |
||||
|
this.handleAuthRole(row) |
||||
|
break |
||||
|
default: |
||||
|
break |
||||
|
} |
||||
|
}, |
||||
|
/** 新增按钮操作 */ |
||||
|
handleAdd() { |
||||
|
this.reset() |
||||
|
getUser().then(response => { |
||||
|
if (response.code === 200) { |
||||
|
this.postOptions = response.posts |
||||
|
this.roleOptions = response.roles |
||||
|
this.open = true |
||||
|
this.title = "添加用户" |
||||
|
this.form.password = this.initPassword |
||||
|
// 初始化行政区划选择框 |
||||
|
this.initAreaSelectOptions() |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
/** 修改按钮操作 */ |
||||
|
handleUpdate(row) { |
||||
|
this.reset() |
||||
|
const userId = row.userId || this.ids |
||||
|
getUser(userId).then(response => { |
||||
|
if (response.code === 200) { |
||||
|
this.form = response.data |
||||
|
this.postOptions = response.posts |
||||
|
this.roleOptions = response.roles |
||||
|
this.$set(this.form, "postIds", response.postIds) |
||||
|
this.$set(this.form, "roleIds", response.roleIds) |
||||
|
this.open = true |
||||
|
this.title = "修改用户" |
||||
|
this.form.password = "" |
||||
|
// 初始化行政区划选择框 |
||||
|
this.initAreaSelectOptions() |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
/** 重置密码按钮操作 */ |
||||
|
handleResetPwd(row) { |
||||
|
this.$prompt('请输入"' + row.userName + '"的新密码', "提示", { |
||||
|
confirmButtonText: "确定", |
||||
|
cancelButtonText: "取消", |
||||
|
closeOnClickModal: false, |
||||
|
inputPattern: /^.{5,20}$/, |
||||
|
inputErrorMessage: "用户密码长度必须介于 5 和 20 之间", |
||||
|
inputValidator: (value) => { |
||||
|
if (/<|>|"|'|\||\\/.test(value)) { |
||||
|
return "不能包含非法字符:< > \" ' \\\ |" |
||||
|
} |
||||
|
}, |
||||
|
}).then(({ value }) => { |
||||
|
resetUserPwd(row.userId, value).then(response => { |
||||
|
this.$modal.msgSuccess("修改成功,新密码是:" + value) |
||||
|
}) |
||||
|
}).catch(() => {}) |
||||
|
}, |
||||
|
/** 分配角色操作 */ |
||||
|
handleAuthRole: function(row) { |
||||
|
const userId = row.userId |
||||
|
this.$router.push("/system/user-auth/role/" + userId) |
||||
|
}, |
||||
|
/** 提交按钮 */ |
||||
|
submitForm: function() { |
||||
|
this.$refs["form"].validate(valid => { |
||||
|
if (valid) { |
||||
|
if (this.form.userId != undefined) { |
||||
|
updateUser(this.form).then(response => { |
||||
|
this.$modal.msgSuccess("修改成功") |
||||
|
this.open = false |
||||
|
this.getList() |
||||
|
}) |
||||
|
} else { |
||||
|
addUser(this.form).then(response => { |
||||
|
this.$modal.msgSuccess("新增成功") |
||||
|
this.open = false |
||||
|
this.getList() |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
/** 删除按钮操作 */ |
||||
|
handleDelete(row) { |
||||
|
const userIds = row.userId || this.ids |
||||
|
this.$modal.confirm('是否确认删除用户编号为"' + userIds + '"的数据项?').then(function() { |
||||
|
return delUser(userIds) |
||||
|
}).then(() => { |
||||
|
this.getList() |
||||
|
this.$modal.msgSuccess("删除成功") |
||||
|
}).catch(() => {}) |
||||
|
}, |
||||
|
/** 导出按钮操作 */ |
||||
|
handleExport() { |
||||
|
this.download('system/user/export', { |
||||
|
...this.queryParams |
||||
|
}, `user_${new Date().getTime()}.xlsx`) |
||||
|
}, |
||||
|
/** 导入按钮操作 */ |
||||
|
handleImport() { |
||||
|
this.upload.title = "用户导入" |
||||
|
this.upload.open = true |
||||
|
}, |
||||
|
/** 下载模板操作 */ |
||||
|
importTemplate() { |
||||
|
this.download('system/user/importTemplate', { |
||||
|
}, `user_template_${new Date().getTime()}.xlsx`) |
||||
|
}, |
||||
|
// 文件上传中处理 |
||||
|
handleFileUploadProgress(event, file, fileList) { |
||||
|
this.upload.isUploading = true |
||||
|
}, |
||||
|
// 文件上传成功处理 |
||||
|
handleFileSuccess(response, file, fileList) { |
||||
|
this.upload.open = false |
||||
|
this.upload.isUploading = false |
||||
|
this.$refs.upload.clearFiles() |
||||
|
this.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果", { dangerouslyUseHTMLString: true }) |
||||
|
this.getList() |
||||
|
}, |
||||
|
// 提交上传文件 |
||||
|
submitFileForm() { |
||||
|
const file = this.$refs.upload.uploadFiles |
||||
|
if (!file || file.length === 0 || (!file[0].name.toLowerCase().endsWith('.xls') && !file[0].name.toLowerCase().endsWith('.xlsx'))) { |
||||
|
this.$modal.msgError("请选择后缀为 \"xls\"或\"xlsx\"的文件。") |
||||
|
return |
||||
|
} |
||||
|
this.$refs.upload.submit() |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.custom-tree-node { |
||||
|
flex: 1; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: space-between; |
||||
|
font-size: 14px; |
||||
|
padding-right: 8px; |
||||
|
} |
||||
|
.tree-expand-icon { |
||||
|
margin-left: 8px; |
||||
|
color: #909399; |
||||
|
} |
||||
|
.area-tree { |
||||
|
min-height: 400px; |
||||
|
} |
||||
|
</style> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue