专家管理

main
Gitea 1 year ago
parent 10f34d6ddc
commit 51e0db66db
  1. 178
      jeecg-boot-master/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/compexp/controller/CompExpController.java
  2. 75
      jeecg-boot-master/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/compexp/entity/CompExp.java
  3. 17
      jeecg-boot-master/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/compexp/mapper/CompExpMapper.java
  4. 5
      jeecg-boot-master/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/compexp/mapper/xml/CompExpMapper.xml
  5. 14
      jeecg-boot-master/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/compexp/service/ICompExpService.java
  6. 19
      jeecg-boot-master/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/compexp/service/impl/CompExpServiceImpl.java
  7. 339
      jeecg-boot-master/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/expert/controller/ExpertController.java
  8. 92
      jeecg-boot-master/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/expert/entity/Expert.java
  9. 17
      jeecg-boot-master/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/expert/mapper/ExpertMapper.java
  10. 5
      jeecg-boot-master/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/expert/mapper/xml/ExpertMapper.xml
  11. 14
      jeecg-boot-master/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/expert/service/IExpertService.java
  12. 19
      jeecg-boot-master/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/expert/service/impl/ExpertServiceImpl.java
  13. 6
      jeecgboot-vue3-master/src/components/DrawerZJ/index.ts
  14. 237
      jeecgboot-vue3-master/src/components/DrawerZJ/src/BasicDrawerZJ.vue
  15. 75
      jeecgboot-vue3-master/src/components/DrawerZJ/src/components/DrawerFooter.vue
  16. 74
      jeecgboot-vue3-master/src/components/DrawerZJ/src/components/DrawerHeader.vue
  17. 45
      jeecgboot-vue3-master/src/components/DrawerZJ/src/props.ts
  18. 196
      jeecgboot-vue3-master/src/components/DrawerZJ/src/typing.ts
  19. 146
      jeecgboot-vue3-master/src/components/DrawerZJ/src/useDrawerZJ.ts
  20. 171
      jeecgboot-vue3-master/src/views/system/user/UserDrawerZJ.vue
  21. 60
      jeecgboot-vue3-master/src/views/system/user/index.vue
  22. 24
      jeecgboot-vue3-master/src/views/system/user/user.api.js
  23. 25
      jeecgboot-vue3-master/src/views/system/user/user.api.ts
  24. 237
      jeecgboot-vue3-master/src/views/system/user/user.data.js
  25. 238
      jeecgboot-vue3-master/src/views/system/user/user.data.ts

@ -0,0 +1,178 @@
package org.jeecg.modules.demo.compexp.controller;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.demo.compexp.entity.CompExp;
import org.jeecg.modules.demo.compexp.service.ICompExpService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.jeecg.common.system.base.controller.JeecgController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.apache.shiro.authz.annotation.RequiresPermissions;
/**
* @Description: 比赛专家
* @Author: jeecg-boot
* @Date: 2023-10-11
* @Version: V1.0
*/
@Api(tags="比赛专家")
@RestController
@RequestMapping("/compexp/compExp")
@Slf4j
public class CompExpController extends JeecgController<CompExp, ICompExpService> {
@Autowired
private ICompExpService compExpService;
/**
* 分页列表查询
*
* @param compExp
* @param pageNo
* @param pageSize
* @param req
* @return
*/
//@AutoLog(value = "比赛专家-分页列表查询")
@ApiOperation(value="比赛专家-分页列表查询", notes="比赛专家-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<CompExp>> queryPageList(CompExp compExp,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<CompExp> queryWrapper = QueryGenerator.initQueryWrapper(compExp, req.getParameterMap());
Page<CompExp> page = new Page<CompExp>(pageNo, pageSize);
IPage<CompExp> pageList = compExpService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 添加
*
* @param compExp
* @return
*/
@AutoLog(value = "比赛专家-添加")
@ApiOperation(value="比赛专家-添加", notes="比赛专家-添加")
@RequiresPermissions("compexp:comp_exp:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody CompExp compExp) {
compExpService.save(compExp);
return Result.OK("添加成功!");
}
/**
* 编辑
*
* @param compExp
* @return
*/
@AutoLog(value = "比赛专家-编辑")
@ApiOperation(value="比赛专家-编辑", notes="比赛专家-编辑")
@RequiresPermissions("compexp:comp_exp:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody CompExp compExp) {
compExpService.updateById(compExp);
return Result.OK("编辑成功!");
}
/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "比赛专家-通过id删除")
@ApiOperation(value="比赛专家-通过id删除", notes="比赛专家-通过id删除")
@RequiresPermissions("compexp:comp_exp:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
compExpService.removeById(id);
return Result.OK("删除成功!");
}
/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "比赛专家-批量删除")
@ApiOperation(value="比赛专家-批量删除", notes="比赛专家-批量删除")
@RequiresPermissions("compexp:comp_exp:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
this.compExpService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
//@AutoLog(value = "比赛专家-通过id查询")
@ApiOperation(value="比赛专家-通过id查询", notes="比赛专家-通过id查询")
@GetMapping(value = "/queryById")
public Result<CompExp> queryById(@RequestParam(name="id",required=true) String id) {
CompExp compExp = compExpService.getById(id);
if(compExp==null) {
return Result.error("未找到对应数据");
}
return Result.OK(compExp);
}
/**
* 导出excel
*
* @param request
* @param compExp
*/
@RequiresPermissions("compexp:comp_exp:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, CompExp compExp) {
return super.exportXls(request, compExp, CompExp.class, "比赛专家");
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequiresPermissions("compexp:comp_exp:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, CompExp.class);
}
}

@ -0,0 +1,75 @@
package org.jeecg.modules.demo.compexp.entity;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.jeecg.common.aspect.annotation.Dict;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* @Description: 比赛专家
* @Author: jeecg-boot
* @Date: 2023-10-11
* @Version: V1.0
*/
@Data
@TableName("comp_exp")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="comp_exp对象", description="比赛专家")
public class CompExp implements Serializable {
private static final long serialVersionUID = 1L;
/**主键*/
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "主键")
private java.lang.String id;
/**创建人*/
@ApiModelProperty(value = "创建人")
private java.lang.String createBy;
/**创建日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建日期")
private java.util.Date createTime;
/**更新人*/
@ApiModelProperty(value = "更新人")
private java.lang.String updateBy;
/**更新日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "更新日期")
private java.util.Date updateTime;
/**所属部门*/
@ApiModelProperty(value = "所属部门")
private java.lang.String sysOrgCode;
/**比赛*/
@Excel(name = "比赛", width = 15)
@ApiModelProperty(value = "比赛")
private java.lang.String compid;
/**专家*/
@Excel(name = "专家", width = 15, dictTable = "expert", dicText = "name", dicCode = "id")
@Dict(dictTable = "expert", dicText = "name", dicCode = "id")
@ApiModelProperty(value = "专家")
private java.lang.String expid;
/**状态*/
@Excel(name = "状态", width = 15)
@ApiModelProperty(value = "状态")
private java.lang.String stat;
/**比赛名称*/
@Excel(name = "比赛名称", width = 15)
@ApiModelProperty(value = "比赛名称")
private java.lang.String compName;
}

@ -0,0 +1,17 @@
package org.jeecg.modules.demo.compexp.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.demo.compexp.entity.CompExp;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: 比赛专家
* @Author: jeecg-boot
* @Date: 2023-10-11
* @Version: V1.0
*/
public interface CompExpMapper extends BaseMapper<CompExp> {
}

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.demo.compexp.mapper.CompExpMapper">
</mapper>

@ -0,0 +1,14 @@
package org.jeecg.modules.demo.compexp.service;
import org.jeecg.modules.demo.compexp.entity.CompExp;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @Description: 比赛专家
* @Author: jeecg-boot
* @Date: 2023-10-11
* @Version: V1.0
*/
public interface ICompExpService extends IService<CompExp> {
}

@ -0,0 +1,19 @@
package org.jeecg.modules.demo.compexp.service.impl;
import org.jeecg.modules.demo.compexp.entity.CompExp;
import org.jeecg.modules.demo.compexp.mapper.CompExpMapper;
import org.jeecg.modules.demo.compexp.service.ICompExpService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
/**
* @Description: 比赛专家
* @Author: jeecg-boot
* @Date: 2023-10-11
* @Version: V1.0
*/
@Service
public class CompExpServiceImpl extends ServiceImpl<CompExpMapper, CompExp> implements ICompExpService {
}

@ -0,0 +1,339 @@
package org.jeecg.modules.demo.expert.controller;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSONObject;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.PasswordUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.demo.compexp.entity.CompExp;
import org.jeecg.modules.demo.compexp.service.ICompExpService;
import org.jeecg.modules.demo.expert.entity.Expert;
import org.jeecg.modules.demo.expert.service.IExpertService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.jeecg.common.system.base.controller.JeecgController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.apache.shiro.authz.annotation.RequiresPermissions;
/**
* @Description: 专家表
* @Author: jeecg-boot
* @Date: 2023-10-11
* @Version: V1.0
*/
@Api(tags="专家表")
@RestController
@RequestMapping("/expert/expert")
@Slf4j
public class ExpertController extends JeecgController<Expert, IExpertService> {
@Autowired
private IExpertService expertService;
@Autowired
private ICompExpService compExpService;
@Autowired
private BaseCommonService baseCommonService;
@Autowired
private ISysUserService sysUserService;
/**
* 分页列表查询
*
* @param expert
* @param pageNo
* @param pageSize
* @param req
* @return
*/
//@AutoLog(value = "专家表-分页列表查询")
@ApiOperation(value="专家表-分页列表查询", notes="专家表-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<Expert>> queryPageList(Expert expert,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<Expert> queryWrapper = QueryGenerator.initQueryWrapper(expert, req.getParameterMap());
Page<Expert> page = new Page<Expert>(pageNo, pageSize);
IPage<Expert> pageList = expertService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 添加
*
* @param expert
* @return
*/
@AutoLog(value = "专家表-添加")
@ApiOperation(value="专家表-添加", notes="专家表-添加")
@RequiresPermissions("expert:expert:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody Expert expert) {
expertService.save(expert);
return Result.OK("添加成功!");
}
/**
* 编辑
*
* @param expert
* @return
*/
@AutoLog(value = "专家表-编辑")
@ApiOperation(value="专家表-编辑", notes="专家表-编辑")
@RequiresPermissions("expert:expert:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody Expert expert) {
expertService.updateById(expert);
return Result.OK("编辑成功!");
}
/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "专家表-通过id删除")
@ApiOperation(value="专家表-通过id删除", notes="专家表-通过id删除")
@RequiresPermissions("expert:expert:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
expertService.removeById(id);
return Result.OK("删除成功!");
}
/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "专家表-批量删除")
@ApiOperation(value="专家表-批量删除", notes="专家表-批量删除")
@RequiresPermissions("expert:expert:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
this.expertService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
//@AutoLog(value = "专家表-通过id查询")
@ApiOperation(value="专家表-通过id查询", notes="专家表-通过id查询")
@GetMapping(value = "/queryById")
public Result<Expert> queryById(@RequestParam(name="id",required=true) String id,HttpServletRequest req) {
Expert expert = new Expert();
QueryWrapper<Expert> queryWrapper = QueryGenerator.initQueryWrapper(expert, req.getParameterMap());
queryWrapper.eq("user_id",id);
List<Expert> list = expertService.list(queryWrapper);
CompExp compExp = new CompExp();
QueryWrapper<CompExp> queryWrapper1 = QueryGenerator.initQueryWrapper(compExp, req.getParameterMap());
queryWrapper1.eq("expid",list.get(0).getId());
List<CompExp> list1 = compExpService.list(queryWrapper1);
if(list.size()==0) {
return Result.error("未找到对应数据");
}
list.get(0).setCompid(list1.get(0).getCompid());
list.get(0).setStat(list1.get(0).getStat());
list.get(0).setCompName(list1.get(0).getCompName());
return Result.OK(list.get(0));
}
/**
* 通过id查询
*
* @param id
* @return
*/
//@AutoLog(value = "专家表-通过id查询")
@ApiOperation(value="专家表-通过id查询", notes="专家表-通过id查询")
@GetMapping(value = "/queryByUserId")
public Result<Expert> queryByUserId(@RequestParam(name="id",required=true) String id,HttpServletRequest req) {
Expert expert = new Expert();
QueryWrapper<Expert> queryWrapper = QueryGenerator.initQueryWrapper(expert, req.getParameterMap());
queryWrapper.eq("user_id",id);
List<Expert> list = expertService.list(queryWrapper);
if(list.size()>0) {
return Result.OK("zj");
}else{
return Result.OK("pt");
}
}
@RequestMapping(value = "/addZJ", method = RequestMethod.POST)
public Result<SysUser> addZJ(@RequestBody JSONObject jsonObject) {
Result<SysUser> result = new Result<SysUser>();
String selectedRoles = jsonObject.getString("selectedroles");
String selectedDeparts = jsonObject.getString("selecteddeparts");
String expSc = jsonObject.getString("expSc");
String expResume = jsonObject.getString("expResume");
String expTitle = jsonObject.getString("expTitle");
String compid = jsonObject.getString("compid");
String compName = jsonObject.getString("compName");
String stat = jsonObject.getString("stat");
try {
SysUser user = JSON.parseObject(jsonObject.toJSONString(), SysUser.class);
user.setCreateTime(new Date());//设置创建时间
String salt = oConvertUtils.randomGen(8);
user.setSalt(salt);
String passwordEncode = PasswordUtil.encrypt(user.getUsername(), user.getPassword(), salt);
user.setPassword(passwordEncode);
user.setStatus(1);
user.setDelFlag(CommonConstant.DEL_FLAG_0);
//用户表字段org_code不能在这里设置他的值
user.setOrgCode(null);
// 保存用户走一个service 保证事务
//获取租户ids
String relTenantIds = jsonObject.getString("relTenantIds");
sysUserService.saveUser(user, selectedRoles, selectedDeparts, relTenantIds);
baseCommonService.addLog("添加用户,username: " +user.getUsername() ,CommonConstant.LOG_TYPE_2, 2);
Expert expert = new Expert();
expert.setUserId(user.getId());
expert.setExpImg(user.getAvatar());
expert.setExpSc(expSc);
expert.setExpResume(expResume);
expert.setExpTitle(expTitle);
expert.setName(user.getRealname());
expertService.save(expert);
CompExp compExp = new CompExp();
compExp.setCompid(compid);
compExp.setCompName(compName);
compExp.setExpid(expert.getId());
compExp.setStat(stat);
compExpService.save(compExp);
result.success("添加成功!");
} catch (Exception e) {
log.error(e.getMessage(), e);
result.error500("操作失败");
}
return result;
}
@RequestMapping(value = "/editZJ", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<SysUser> editZJ(@RequestBody JSONObject jsonObject,HttpServletRequest req) {
Result<SysUser> result = new Result<SysUser>();
try {
SysUser sysUser = sysUserService.getById(jsonObject.getString("id"));
baseCommonService.addLog("编辑用户,username: " +sysUser.getUsername() ,CommonConstant.LOG_TYPE_2, 2);
if(sysUser==null) {
result.error500("未找到对应实体");
}else {
SysUser user = JSON.parseObject(jsonObject.toJSONString(), SysUser.class);
user.setUpdateTime(new Date());
//String passwordEncode = PasswordUtil.encrypt(user.getUsername(), user.getPassword(), sysUser.getSalt());
user.setPassword(sysUser.getPassword());
String roles = jsonObject.getString("selectedroles");
String departs = jsonObject.getString("selecteddeparts");
String expSc = jsonObject.getString("expSc");
String expResume = jsonObject.getString("expResume");
String expTitle = jsonObject.getString("expTitle");
String compid = jsonObject.getString("compid");
String compName = jsonObject.getString("compName");
String stat = jsonObject.getString("stat");
if(oConvertUtils.isEmpty(departs)){
//vue3.0前端只传递了departIds
departs=user.getDepartIds();
}
//用户表字段org_code不能在这里设置他的值
user.setOrgCode(null);
// 修改用户走一个service 保证事务
//获取租户ids
String relTenantIds = jsonObject.getString("relTenantIds");
sysUserService.editUser(user, roles, departs, relTenantIds);
Expert expert = new Expert();
QueryWrapper<Expert> queryWrapper = QueryGenerator.initQueryWrapper(expert, req.getParameterMap());
queryWrapper.eq("user_id",user.getId());
List<Expert> listex = expertService.list(queryWrapper);
expert = listex.get(0);
expert.setUserId(user.getId());
expert.setExpImg(user.getAvatar());
expert.setExpSc(expSc);
expert.setExpResume(expResume);
expert.setExpTitle(expTitle);
expert.setName(user.getRealname());
expertService.updateById(expert);
CompExp compExp = new CompExp();
QueryWrapper<CompExp> queryWrapper1 = QueryGenerator.initQueryWrapper(compExp, req.getParameterMap());
queryWrapper1.eq("expid",expert.getId());
List<CompExp> listce = compExpService.list(queryWrapper1);
compExp = listce.get(0);
compExp.setCompid(compid);
compExp.setCompName(compName);
compExp.setExpid(expert.getId());
compExp.setStat(stat);
compExpService.updateById(compExp);
result.success("修改成功!");
}
} catch (Exception e) {
log.error(e.getMessage(), e);
result.error500("操作失败");
}
return result;
}
/**
* 导出excel
*
* @param request
* @param expert
*/
@RequiresPermissions("expert:expert:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, Expert expert) {
return super.exportXls(request, expert, Expert.class, "专家表");
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequiresPermissions("expert:expert:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, Expert.class);
}
}

@ -0,0 +1,92 @@
package org.jeecg.modules.demo.expert.entity;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.jeecg.common.aspect.annotation.Dict;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* @Description: 专家表
* @Author: jeecg-boot
* @Date: 2023-10-11
* @Version: V1.0
*/
@Data
@TableName("expert")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="expert对象", description="专家表")
public class Expert implements Serializable {
private static final long serialVersionUID = 1L;
/**主键*/
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "主键")
private java.lang.String id;
/**创建人*/
@ApiModelProperty(value = "创建人")
private java.lang.String createBy;
/**创建日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建日期")
private java.util.Date createTime;
/**更新人*/
@ApiModelProperty(value = "更新人")
private java.lang.String updateBy;
/**更新日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "更新日期")
private java.util.Date updateTime;
/**所属部门*/
@ApiModelProperty(value = "所属部门")
private java.lang.String sysOrgCode;
/**用户id*/
@Excel(name = "用户id", width = 15)
@ApiModelProperty(value = "用户id")
private java.lang.String userId;
/**专家照片*/
@Excel(name = "专家照片", width = 15)
@ApiModelProperty(value = "专家照片")
private java.lang.String expImg;
/**专家毕业院校*/
@Excel(name = "专家毕业院校", width = 15)
@ApiModelProperty(value = "专家毕业院校")
private java.lang.String expSc;
/**专家履历*/
@Excel(name = "专家履历", width = 15)
@ApiModelProperty(value = "专家履历")
private java.lang.String expResume;
/**专家学历*/
@Excel(name = "专家学历", width = 15)
@ApiModelProperty(value = "专家学历")
private java.lang.String expTitle;
/**专家名称*/
@Excel(name = "专家名称", width = 15)
@ApiModelProperty(value = "专家名称")
private java.lang.String name;
/**比赛*/
@TableField(exist =false)
@ApiModelProperty(value = "比赛")
private java.lang.String compid;
/**状态*/
@TableField(exist =false)
@ApiModelProperty(value = "状态")
private java.lang.String stat;
/**比赛名称*/
@TableField(exist =false)
@ApiModelProperty(value = "比赛名称")
private java.lang.String compName;
}

@ -0,0 +1,17 @@
package org.jeecg.modules.demo.expert.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.demo.expert.entity.Expert;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: 专家表
* @Author: jeecg-boot
* @Date: 2023-10-11
* @Version: V1.0
*/
public interface ExpertMapper extends BaseMapper<Expert> {
}

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.demo.expert.mapper.ExpertMapper">
</mapper>

@ -0,0 +1,14 @@
package org.jeecg.modules.demo.expert.service;
import org.jeecg.modules.demo.expert.entity.Expert;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @Description: 专家表
* @Author: jeecg-boot
* @Date: 2023-10-11
* @Version: V1.0
*/
public interface IExpertService extends IService<Expert> {
}

@ -0,0 +1,19 @@
package org.jeecg.modules.demo.expert.service.impl;
import org.jeecg.modules.demo.expert.entity.Expert;
import org.jeecg.modules.demo.expert.mapper.ExpertMapper;
import org.jeecg.modules.demo.expert.service.IExpertService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
/**
* @Description: 专家表
* @Author: jeecg-boot
* @Date: 2023-10-11
* @Version: V1.0
*/
@Service
public class ExpertServiceImpl extends ServiceImpl<ExpertMapper, Expert> implements IExpertService {
}

@ -0,0 +1,6 @@
import { withInstall } from '/@/utils';
import basicDrawerZJ from './src/BasicDrawerZJ.vue';
export const BasicDrawerZJ = withInstall(basicDrawerZJ);
export * from './src/typing';
export { useDrawerZJ, useDrawerInner } from './src/useDrawerZJ';

@ -0,0 +1,237 @@
<template>
<Drawer :class="prefixCls" @close="onClose" v-bind="getBindValues">
<template #title v-if="!$slots.title">
<DrawerHeader :title="getMergeProps.title" :isDetail="isDetail" :showDetailBack="showDetailBack" @close="onClose">
<template #titleToolbar>
<slot name="titleToolbar"></slot>
</template>
</DrawerHeader>
</template>
<template v-else #title>
<slot name="title"></slot>
</template>
<ScrollContainer :style="getScrollContentStyle" v-loading="getLoading" :loading-tip="loadingText || t('common.loadingText')">
<slot></slot>
</ScrollContainer>
<DrawerFooter v-bind="getProps" @close="onClose" @ok="handleOk" :height="getFooterHeight">
<template #[item]="data" v-for="item in Object.keys($slots)">
<slot :name="item" v-bind="data || {}"></slot>
</template>
</DrawerFooter>
</Drawer>
</template>
<script lang="ts">
import type { DrawerInstance, DrawerProps } from './typing';
import type { CSSProperties } from 'vue';
import { defineComponent, ref, computed, watch, unref, nextTick, toRaw, getCurrentInstance } from 'vue';
import { Drawer } from 'ant-design-vue';
import { useI18n } from '/@/hooks/web/useI18n';
import { isFunction, isNumber } from '/@/utils/is';
import { deepMerge } from '/@/utils';
import DrawerFooter from './components/DrawerFooter.vue';
import DrawerHeader from './components/DrawerHeader.vue';
import { ScrollContainer } from '/@/components/Container';
import { basicProps } from './props';
import { useDesign } from '/@/hooks/web/useDesign';
import { useAttrs } from '/@/hooks/core/useAttrs';
export default defineComponent({
components: { Drawer, ScrollContainer, DrawerFooter, DrawerHeader },
inheritAttrs: false,
props: basicProps,
emits: ['visible-change', 'ok', 'close', 'register'],
setup(props, { emit }) {
const visibleRef = ref(false);
const attrs = useAttrs();
const propsRef = ref<Partial<Nullable<DrawerProps>>>(null);
const { t } = useI18n();
const { prefixVar, prefixCls } = useDesign('basic-drawer');
const drawerInstance: DrawerInstance = {
setDrawerProps: setDrawerProps,
emitVisible: undefined,
};
const instance = getCurrentInstance();
instance && emit('register', drawerInstance, instance.uid);
const getMergeProps = computed((): DrawerProps => {
return deepMerge(toRaw(props), unref(propsRef));
});
const getProps = computed((): DrawerProps => {
const opt = {
placement: 'right',
...unref(attrs),
...unref(getMergeProps),
visible: unref(visibleRef),
};
opt.title = undefined;
let { isDetail, width, wrapClassName, getContainer } = opt;
if (isDetail) {
if (!width) {
opt.width = '100%';
}
const detailCls = `${prefixCls}__detail`;
wrapClassName = opt['class'] ? opt['class'] : wrapClassName;
opt.class = wrapClassName ? `${wrapClassName} ${detailCls}` : detailCls;
if (!getContainer) {
// TODO type error?
opt.getContainer = `.${prefixVar}-layout-content` as any;
}
}
return opt as DrawerProps;
});
const getBindValues = computed((): DrawerProps => {
return {
...attrs,
...unref(getProps),
};
});
// Custom implementation of the bottom button,
const getFooterHeight = computed(() => {
const { footerHeight, showFooter } = unref(getProps);
if (showFooter && footerHeight) {
return isNumber(footerHeight) ? `${footerHeight}px` : `${footerHeight.replace('px', '')}px`;
}
return `0px`;
});
const getScrollContentStyle = computed((): CSSProperties => {
const footerHeight = unref(getFooterHeight);
return {
position: 'relative',
height: `calc(100% - ${footerHeight})`,
};
});
const getLoading = computed(() => {
return !!unref(getProps)?.loading;
});
watch(
() => props.visible,
(newVal, oldVal) => {
if (newVal !== oldVal) visibleRef.value = newVal;
},
{ deep: true }
);
watch(
() => visibleRef.value,
(visible) => {
nextTick(() => {
emit('visible-change', visible);
instance && drawerInstance.emitVisible?.(visible, instance.uid);
});
}
);
// Cancel event
async function onClose(e: Recordable) {
const { closeFunc } = unref(getProps);
emit('close', e);
if (closeFunc && isFunction(closeFunc)) {
const res = await closeFunc();
visibleRef.value = !res;
return;
}
visibleRef.value = false;
}
function setDrawerProps(props: Partial<DrawerProps>): void {
// Keep the last setDrawerProps
propsRef.value = deepMerge(unref(propsRef) || ({} as any), props);
if (Reflect.has(props, 'visible')) {
visibleRef.value = !!props.visible;
}
}
function handleOk() {
emit('ok');
}
return {
onClose,
t,
prefixCls,
getMergeProps: getMergeProps as any,
getScrollContentStyle,
getProps: getProps as any,
getLoading,
getBindValues,
getFooterHeight,
handleOk,
};
},
});
</script>
<style lang="less">
@header-height: 60px;
@detail-header-height: 40px;
@prefix-cls: ~'@{namespace}-basic-drawer';
@prefix-cls-detail: ~'@{namespace}-basic-drawer__detail';
.@{prefix-cls} {
.ant-drawer-wrapper-body {
overflow: hidden;
}
.ant-drawer-close {
&:hover {
color: @error-color;
}
}
.ant-drawer-body {
height: calc(100% - @header-height);
padding: 0;
background-color: @component-background;
.scrollbar__wrap {
padding: 16px !important;
margin-bottom: 0 !important;
}
> .scrollbar > .scrollbar__bar.is-horizontal {
display: none;
}
}
}
.@{prefix-cls-detail} {
position: absolute;
.ant-drawer-header {
width: 100%;
height: @detail-header-height;
padding: 0;
border-top: 1px solid @border-color-base;
box-sizing: border-box;
}
.ant-drawer-title {
height: 100%;
}
.ant-drawer-close {
height: @detail-header-height;
line-height: @detail-header-height;
}
.scrollbar__wrap {
padding: 0 !important;
}
.ant-drawer-body {
height: calc(100% - @detail-header-height);
}
}
</style>

@ -0,0 +1,75 @@
<template>
<div :class="prefixCls" :style="getStyle" v-if="showFooter || $slots.footer">
<template v-if="!$slots.footer">
<slot name="insertFooter"></slot>
<a-button v-bind="cancelButtonProps" @click="handleClose" class="mr-2" v-if="showCancelBtn">
{{ cancelText }}
</a-button>
<slot name="centerFooter"></slot>
<a-button :type="okType" @click="handleOk" v-bind="okButtonProps" class="mr-2" :loading="confirmLoading" v-if="showOkBtn">
{{ okText }}
</a-button>
<slot name="appendFooter"></slot>
</template>
<template v-else>
<slot name="footer"></slot>
</template>
</div>
</template>
<script lang="ts">
import type { CSSProperties } from 'vue';
import { defineComponent, computed } from 'vue';
import { useDesign } from '/@/hooks/web/useDesign';
import { footerProps } from '../props';
export default defineComponent({
name: 'BasicDrawerFooter',
props: {
...footerProps,
height: {
type: String,
default: '60px',
},
},
emits: ['ok', 'close'],
setup(props, { emit }) {
const { prefixCls } = useDesign('basic-drawer-footer');
const getStyle = computed((): CSSProperties => {
const heightStr = `${props.height}`;
return {
height: heightStr,
lineHeight: heightStr,
};
});
function handleOk() {
emit('ok');
}
function handleClose() {
emit('close');
}
return { handleOk, prefixCls, handleClose, getStyle };
},
});
</script>
<style lang="less">
@prefix-cls: ~'@{namespace}-basic-drawer-footer';
@footer-height: 60px;
.@{prefix-cls} {
position: absolute;
bottom: 0;
width: 100%;
padding: 0 12px 0 20px;
text-align: right;
background-color: @component-background;
border-top: 1px solid @border-color-base;
> * {
margin-right: 8px;
}
}
</style>

@ -0,0 +1,74 @@
<template>
<BasicTitle v-if="!isDetail" :class="prefixCls">
<slot name="title"></slot>
{{ !$slots.title ? title : '' }}
</BasicTitle>
<div :class="[prefixCls, `${prefixCls}--detail`]" v-else>
<span :class="`${prefixCls}__twrap`">
<span @click="handleClose" v-if="showDetailBack">
<ArrowLeftOutlined :class="`${prefixCls}__back`" />
</span>
<span v-if="title">{{ title }}</span>
</span>
<span :class="`${prefixCls}__toolbar`">
<slot name="titleToolbar"></slot>
</span>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicTitle } from '/@/components/Basic';
import { ArrowLeftOutlined } from '@ant-design/icons-vue';
import { useDesign } from '/@/hooks/web/useDesign';
import { propTypes } from '/@/utils/propTypes';
export default defineComponent({
name: 'BasicDrawerHeader',
components: { BasicTitle, ArrowLeftOutlined },
props: {
isDetail: propTypes.bool,
showDetailBack: propTypes.bool,
title: propTypes.string,
},
emits: ['close'],
setup(_, { emit }) {
const { prefixCls } = useDesign('basic-drawer-header');
function handleClose() {
emit('close');
}
return { prefixCls, handleClose };
},
});
</script>
<style lang="less">
@prefix-cls: ~'@{namespace}-basic-drawer-header';
@footer-height: 60px;
.@{prefix-cls} {
display: flex;
height: 100%;
align-items: center;
&__back {
padding: 0 12px;
cursor: pointer;
&:hover {
color: @primary-color;
}
}
&__twrap {
flex: 1;
}
&__toolbar {
padding-right: 50px;
}
}
</style>

@ -0,0 +1,45 @@
import type { PropType } from 'vue';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
export const footerProps = {
confirmLoading: { type: Boolean },
/**
* @description: Show close button
*/
showCancelBtn: { type: Boolean, default: true },
cancelButtonProps: Object as PropType<Recordable>,
cancelText: { type: String, default: t('common.cancelText') },
/**
* @description: Show confirmation button
*/
showOkBtn: { type: Boolean, default: true },
okButtonProps: Object as PropType<Recordable>,
okText: { type: String, default: t('common.okText') },
okType: { type: String, default: 'primary' },
showFooter: { type: Boolean },
footerHeight: {
type: [String, Number] as PropType<string | number>,
default: 60,
},
};
export const basicProps = {
class: {type: [String, Object, Array]},
isDetail: { type: Boolean },
title: { type: String, default: '' },
loadingText: { type: String },
showDetailBack: { type: Boolean, default: true },
visible: { type: Boolean },
loading: { type: Boolean },
maskClosable: { type: Boolean, default: true },
getContainer: {
type: [Object, String] as PropType<any>,
},
closeFunc: {
type: [Function, Object] as PropType<any>,
default: null,
},
destroyOnClose: { type: Boolean },
...footerProps,
};

@ -0,0 +1,196 @@
import type { ButtonProps } from 'ant-design-vue/lib/button/buttonTypes';
import type { CSSProperties, VNodeChild, ComputedRef } from 'vue';
import type { ScrollContainerOptions } from '/@/components/Container/index';
export interface DrawerInstance {
setDrawerProps: (props: Partial<DrawerProps> | boolean) => void;
emitVisible?: (visible: boolean, uid: number) => void;
}
export interface ReturnMethods extends DrawerInstance {
openDrawerZJ: <T = any>(visible?: boolean, data?: T, openOnSet?: boolean) => void;
closeDrawer: () => void;
getVisible?: ComputedRef<boolean>;
}
export type RegisterFn = (drawerInstance: DrawerInstance, uuid?: string) => void;
export interface ReturnInnerMethods extends DrawerInstance {
closeDrawer: () => void;
changeLoading: (loading: boolean) => void;
changeOkLoading: (loading: boolean) => void;
getVisible?: ComputedRef<boolean>;
}
export type UseDrawerReturnType = [RegisterFn, ReturnMethods];
export type UseDrawerInnerReturnType = [RegisterFn, ReturnInnerMethods];
export interface DrawerFooterProps {
showOkBtn: boolean;
showCancelBtn: boolean;
/**
* Text of the Cancel button
* @default 'cancel'
* @type string
*/
cancelText: string;
/**
* Text of the OK button
* @default 'OK'
* @type string
*/
okText: string;
/**
* Button type of the OK button
* @default 'primary'
* @type string
*/
okType: 'primary' | 'danger' | 'dashed' | 'ghost' | 'default';
/**
* The ok button props, follow jsx rules
* @type object
*/
okButtonProps: { props: ButtonProps; on: {} };
/**
* The cancel button props, follow jsx rules
* @type object
*/
cancelButtonProps: { props: ButtonProps; on: {} };
/**
* Whether to apply loading visual effect for OK button or not
* @default false
* @type boolean
*/
confirmLoading: boolean;
showFooter: boolean;
footerHeight: string | number;
}
export interface DrawerProps extends DrawerFooterProps {
isDetail?: boolean;
loading?: boolean;
showDetailBack?: boolean;
visible?: boolean;
/**
* Built-in ScrollContainer component configuration
* @type ScrollContainerOptions
*/
scrollOptions?: ScrollContainerOptions;
closeFunc?: () => Promise<any>;
triggerWindowResize?: boolean;
/**
* Whether a close (x) button is visible on top right of the Drawer dialog or not.
* @default true
* @type boolean
*/
closable?: boolean;
/**
* Whether to unmount child components on closing drawer or not.
* @default false
* @type boolean
*/
destroyOnClose?: boolean;
/**
* Return the mounted node for Drawer.
* @default 'body'
* @type any ( HTMLElement| () => HTMLElement | string)
*/
getContainer?: () => HTMLElement | string;
/**
* Whether to show mask or not.
* @default true
* @type boolean
*/
mask?: boolean;
/**
* Clicking on the mask (area outside the Drawer) to close the Drawer or not.
* @default true
* @type boolean
*/
maskClosable?: boolean;
/**
* Style for Drawer's mask element.
* @default {}
* @type object
*/
maskStyle?: CSSProperties;
/**
* The title for Drawer.
* @type any (string | slot)
*/
title?: VNodeChild | JSX.Element;
/**
* The class name of the container of the Drawer dialog.
* @type string
*/
class?: string;
// 兼容老版本的写法(后续可能会删除,优先写class)
wrapClassName?: string;
/**
* Style of wrapper element which **contains mask** compare to `drawerStyle`
* @type object
*/
wrapStyle?: CSSProperties;
/**
* Style of the popup layer element
* @type object
*/
drawerStyle?: CSSProperties;
/**
* Style of floating layer, typically used for adjusting its position.
* @type object
*/
bodyStyle?: CSSProperties;
headerStyle?: CSSProperties;
/**
* Width of the Drawer dialog.
* @default 256
* @type string | number
*/
width?: string | number;
/**
* placement is top or bottom, height of the Drawer dialog.
* @type string | number
*/
height?: string | number;
/**
* The z-index of the Drawer.
* @default 1000
* @type number
*/
zIndex?: number;
/**
* The placement of the Drawer.
* @default 'right'
* @type string
*/
placement?: 'top' | 'right' | 'bottom' | 'left';
afterVisibleChange?: (visible?: boolean) => void;
keyboard?: boolean;
/**
* Specify a callback that will be called when a user clicks mask, close button or Cancel button.
*/
onClose?: (e?: Event) => void;
}
export interface DrawerActionType {
scrollBottom: () => void;
scrollTo: (to: number) => void;
getScrollWrap: () => Element | null;
}

@ -0,0 +1,146 @@
import type { UseDrawerReturnType, DrawerInstance, ReturnMethods, DrawerProps, UseDrawerInnerReturnType } from './typing';
import { ref, getCurrentInstance, unref, reactive, watchEffect, nextTick, toRaw, computed } from 'vue';
import { isProdMode } from '/@/utils/env';
import { isFunction } from '/@/utils/is';
import { tryOnUnmounted } from '@vueuse/core';
import { isEqual } from 'lodash-es';
import { error } from '/@/utils/log';
const dataTransferRef = reactive<any>({});
const visibleData = reactive<{ [key: number]: boolean }>({});
/**
* @description: Applicable to separate drawer and call outside
*/
export function useDrawerZJ(): UseDrawerReturnType {
if (!getCurrentInstance()) {
throw new Error('useDrawerZJ() can only be used inside setup() or functional components!');
}
const drawer = ref<DrawerInstance | null>(null);
const loaded = ref<Nullable<boolean>>(false);
const uid = ref<string>('');
function register(drawerInstance: DrawerInstance, uuid: string) {
isProdMode() &&
tryOnUnmounted(() => {
drawer.value = null;
loaded.value = null;
dataTransferRef[unref(uid)] = null;
});
if (unref(loaded) && isProdMode() && drawerInstance === unref(drawer)) {
return;
}
uid.value = uuid;
drawer.value = drawerInstance;
loaded.value = true;
drawerInstance.emitVisible = (visible: boolean, uid: number) => {
visibleData[uid] = visible;
};
}
const getInstance = () => {
const instance = unref(drawer);
if (!instance) {
error('useDrawerZJ instance is undefined!');
}
return instance;
};
const methods: ReturnMethods = {
setDrawerProps: (props: Partial<DrawerProps>): void => {
getInstance()?.setDrawerProps(props);
},
getVisible: computed((): boolean => {
return visibleData[~~unref(uid)];
}),
openDrawerZJ: <T = any>(visible = true, data?: T, openOnSet = true): void => {
getInstance()?.setDrawerProps({
visible: visible,
});
if (!data) return;
if (openOnSet) {
dataTransferRef[unref(uid)] = null;
dataTransferRef[unref(uid)] = toRaw(data);
return;
}
const equal = isEqual(toRaw(dataTransferRef[unref(uid)]), toRaw(data));
if (!equal) {
dataTransferRef[unref(uid)] = toRaw(data);
}
},
closeDrawer: () => {
getInstance()?.setDrawerProps({ visible: false });
},
};
return [register, methods];
}
export const useDrawerInner = (callbackFn?: Fn): UseDrawerInnerReturnType => {
const drawerInstanceRef = ref<Nullable<DrawerInstance>>(null);
const currentInstance = getCurrentInstance();
const uidRef = ref<string>('');
if (!getCurrentInstance()) {
throw new Error('useDrawerInner() can only be used inside setup() or functional components!');
}
const getInstance = () => {
const instance = unref(drawerInstanceRef);
if (!instance) {
error('useDrawerInner instance is undefined!');
return;
}
return instance;
};
const register = (modalInstance: DrawerInstance, uuid: string) => {
isProdMode() &&
tryOnUnmounted(() => {
drawerInstanceRef.value = null;
});
uidRef.value = uuid;
drawerInstanceRef.value = modalInstance;
currentInstance?.emit('register', modalInstance, uuid);
};
watchEffect(() => {
const data = dataTransferRef[unref(uidRef)];
if (!data) return;
if (!callbackFn || !isFunction(callbackFn)) return;
nextTick(() => {
callbackFn(data);
});
});
return [
register,
{
changeLoading: (loading = true) => {
getInstance()?.setDrawerProps({ loading });
},
changeOkLoading: (loading = true) => {
getInstance()?.setDrawerProps({ confirmLoading: loading });
},
getVisible: computed((): boolean => {
return visibleData[~~unref(uidRef)];
}),
closeDrawer: () => {
getInstance()?.setDrawerProps({ visible: false });
},
setDrawerProps: (props: Partial<DrawerProps>) => {
getInstance()?.setDrawerProps(props);
},
},
];
};

@ -0,0 +1,171 @@
<template>
<BasicDrawerZJ
v-bind="$attrs"
@register="registerDrawerZJ"
:title="getTitle"
:width="adaptiveWidth"
@ok="handleSubmit"
:showFooter="showFooter"
destroyOnClose
>
<BasicForm @register="registerForm" />
</BasicDrawerZJ>
</template>
<script lang="ts" setup>
import { defineComponent, ref, computed, unref, useAttrs } from 'vue';
import { BasicForm, useForm } from '/@/components/Form/index';
import { formSchemaZJ } from './user.data';
import { BasicDrawerZJ, useDrawerInner } from '/@/components/DrawerZJ';
import { saveOrUpdateUserZJ, getUserRoles, getUserDepartList, getAllRolesListNoByTenant, getAllRolesList,queryExpertById } from './user.api';
import { useDrawerAdaptiveWidth } from '/@/hooks/jeecg/useAdaptiveWidth';
import { getTenantId } from "/@/utils/auth";
// Emits
const emit = defineEmits(['success', 'register']);
const attrs = useAttrs();
const isUpdate = ref(true);
const rowId = ref('');
const departOptions = ref([]);
//
const [registerForm, { setProps, resetFields, setFieldsValue, validate, updateSchema }] = useForm({
labelWidth: 90,
schemas: formSchemaZJ,
showActionButtonGroup: false,
});
// TODO [VUEN-527] https://www.teambition.com/task/6239beb894b358003fe93626
const showFooter = ref(true);
//
const [registerDrawerZJ, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
await resetFields();
showFooter.value = data?.showFooter ?? true;
setDrawerProps({ confirmLoading: false, showFooter: showFooter.value });
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
rowId.value = data.record.id;
//
if (data.record.relTenantIds && !Array.isArray(data.record.relTenantIds)) {
data.record.relTenantIds = data.record.relTenantIds.split(',');
} else {
//issues/I56C5I
//data.record.relTenantIds = [];
}
////try catch
try {
const userRoles = await getUserRoles({ userid: data.record.id });
if (userRoles && userRoles.length > 0) {
data.record.selectedroles = userRoles;
}
} catch (error) {}
try {
const Expert = await queryExpertById({ id: data.record.id });
console.log(Expert);
if (Expert!=null) {
data.record.expSc = Expert.expSc;
data.record.expResume = Expert.expResume;
data.record.expTitle = Expert.expTitle;
data.record.compid = Expert.compid;
data.record.compName = Expert.compName;
data.record.stat = Expert.stat;
}
} catch (error) {}
///
const userDepart = await getUserDepartList({ userId: data.record.id });
if (userDepart && userDepart.length > 0) {
data.record.selecteddeparts = userDepart;
let selectDepartKeys = Array.from(userDepart, ({ key }) => key);
data.record.selecteddeparts = selectDepartKeys.join(',');
departOptions.value = userDepart.map((item) => {
return { label: item.title, value: item.key };
});
}
///
data.record.departIds && !Array.isArray(data.record.departIds) && (data.record.departIds = data.record.departIds.split(','));
//update-begin---author:zyf Date:20211210 for------------
data.record.departIds = data.record.departIds == '' ? [] : data.record.departIds;
//update-begin---author:zyf Date:20211210 for------------
}
//()
data.selectedroles && (await setFieldsValue({ selectedroles: data.selectedroles }));
////
updateSchema([
{
field: 'password',
show: !unref(isUpdate),
},
{
field: 'confirmPassword',
ifShow: !unref(isUpdate),
},
{
field: 'selectedroles',
show: !data.isRole,
},
{
field: 'departIds',
componentProps: { options: departOptions },
},
{
field: 'selecteddeparts',
show: !data?.departDisabled ?? false,
},
{
field: 'selectedroles',
show: !data?.departDisabled ?? false,
//update-begin---author:wangshuai ---date:20230424 forissues/4844------------
//
componentProps:{
api: data.tenantSaas?getAllRolesList:getAllRolesListNoByTenant
}
//update-end---author:wangshuai ---date:20230424 forissues/4844------------
},
//update-begin---author:wangshuai ---date:20230522 forissues/4935------------
{
field: 'relTenantIds',
componentProps:{
disabled: !!data.tenantSaas,
},
},
//update-end---author:wangshuai ---date:20230522 forissues/4935------------
]);
//update-begin---author:wangshuai ---date:20230522 forissues/4935------------
if(!unref(isUpdate) && data.tenantSaas){
await setFieldsValue({ relTenantIds: getTenantId().toString() })
}
//update-end---author:wangshuai ---date:20230522 forissues/4935------------
//
if (typeof data.record === 'object') {
setFieldsValue({
...data.record,
});
}
//
//update-begin-author:taoyan date:2022-5-24 for: VUEN-1117issue0523
setProps({ disabled: !showFooter.value });
//update-end-author:taoyan date:2022-5-24 for: VUEN-1117issue0523
});
//
const getTitle = computed(() => (!unref(isUpdate) ? '新增专家用户' : '编辑专家用户'));
const { adaptiveWidth } = useDrawerAdaptiveWidth();
//
async function handleSubmit() {
try {
let values = await validate();
setDrawerProps({ confirmLoading: true });
values.userIdentity === 1 && (values.departIds = '');
let isUpdateVal = unref(isUpdate);
//
await saveOrUpdateUserZJ(values, isUpdateVal);
//
closeDrawer();
//
emit('success',{isUpdateVal ,values});
} finally {
setDrawerProps({ confirmLoading: false });
}
}
</script>

@ -5,6 +5,7 @@
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" preIcon="ant-design:plus-outlined" @click="handleCreate"> 新增</a-button>
<a-button type="primary" preIcon="ant-design:plus-outlined" @click="handleCreateZJ"> 新增专家</a-button>
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls" >导入</j-upload-button>
<a-button type="primary" @click="handleSyncUser" preIcon="ant-design:sync-outlined"> 同步流程</a-button>
@ -40,6 +41,7 @@
</BasicTable>
<!--用户抽屉-->
<UserDrawer @register="registerDrawer" @success="handleSuccess" />
<UserDrawerZJ @register="registerDrawerZJ" @success="handleSuccess" />
<!--修改密码-->
<PasswordModal @register="registerPasswordModal" @success="reload" />
<!--用户代理-->
@ -58,6 +60,7 @@
import { ref, computed, unref } from 'vue';
import { BasicTable, TableAction, ActionItem } from '/@/components/Table';
import UserDrawer from './UserDrawer.vue';
import UserDrawerZJ from './UserDrawerZJ.vue';
import UserRecycleBinModal from './UserRecycleBinModal.vue';
import PasswordModal from './PasswordModal.vue';
import UserAgentModal from './UserAgentModal.vue';
@ -65,17 +68,20 @@
import UserQuitAgentModal from './UserQuitAgentModal.vue';
import UserQuitModal from './UserQuitModal.vue';
import { useDrawer } from '/@/components/Drawer';
import { useDrawerZJ } from '/@/components/DrawerZJ';
import { useListPage } from '/@/hooks/system/useListPage';
import { useModal } from '/@/components/Modal';
import { useMessage } from '/@/hooks/web/useMessage';
import { columns, searchFormSchema } from './user.data';
import { listNoCareTenant, deleteUser, batchDeleteUser, getImportUrl, getExportUrl, frozenBatch, syncUser } from './user.api';
import { listNoCareTenant, deleteUser, batchDeleteUser, getImportUrl, getExportUrl, frozenBatch, syncUser,queryByUserId } from './user.api';
import {usePermission} from "/@/hooks/web/usePermission";
import {defHttp} from "../../../utils/http/axios";
const { createMessage, createConfirm } = useMessage();
const { isDisabledAuth } = usePermission();
//drawer
const [registerDrawer, { openDrawer }] = useDrawer();
const [registerDrawerZJ, { openDrawerZJ }] = useDrawerZJ();
//model
const [registerModal, { openModal }] = useModal();
//model
@ -129,25 +135,57 @@
});
}
/**
* 编辑事件
* 新增专家事件
*/
async function handleEdit(record: Recordable) {
openDrawer(true, {
record,
isUpdate: true,
function handleCreateZJ() {
openDrawerZJ(true, {
isUpdate: false,
showFooter: true,
tenantSaas: false,
});
}
/**
* 编辑事件
*/
async function handleEdit(record: Recordable) {
await queryByUserId({ id: record.id }).then(res => {
if(res==="zj"){
openDrawerZJ(true, {
record,
isUpdate: true,
showFooter: true,
tenantSaas: false,
});
}else{
openDrawer(true, {
record,
isUpdate: true,
showFooter: true,
tenantSaas: false,
});
}
});
}
/**
* 详情
*/
async function handleDetail(record: Recordable) {
openDrawer(true, {
record,
isUpdate: true,
showFooter: false,
tenantSaas: false,
await queryByUserId({ id: record.id }).then(res => {
if(res==="zj"){
openDrawerZJ(true, {
record,
isUpdate: true,
showFooter: false,
tenantSaas: false,
});
}else{
openDrawer(true, {
record,
isUpdate: true,
showFooter: false,
tenantSaas: false,
});
}
});
}
/**

@ -6,6 +6,9 @@ var Api;
Api["list"] = "/sys/user/list";
Api["save"] = "/sys/user/add";
Api["edit"] = "/sys/user/edit";
Api["saveZJ"] = "/expert/expert/addZJ";
Api["editZJ"] = "/expert/expert/editZJ";
Api["queryExpertById"] = '/expert/expert/queryById';
Api["agentSave"] = "/sys/sysUserAgent/add";
Api["agentEdit"] = "/sys/sysUserAgent/edit";
Api["getUserRole"] = "/sys/user/queryUserRole";
@ -31,6 +34,7 @@ var Api;
Api["putCancelQuit"] = "/sys/user/putCancelQuit";
Api["updateUserTenantStatus"] = "/sys/tenant/updateUserTenantStatus";
Api["getUserTenantPageList"] = "/sys/tenant/getUserTenantPageList";
Api["queryByUserId"] = '/expert/expert/queryByUserId';
})(Api || (Api = {}));
/**
* 导出api
@ -41,6 +45,18 @@ export const getExportUrl = Api.exportXls;
* 导入api
*/
export const getImportUrl = Api.importExcel;
/**
* 根据userid判断是否为专家
* @param params
*/
export const queryByUserId = (params) => {
return defHttp.get({ url: Api.queryByUserId, params },{ successMessageMode: 'none' });
};
/**
* 专家信息接口
* @param params
*/
export const queryExpertById = (params) => defHttp.get({ url: Api.queryExpertById, params }, { successMessageMode: 'none' });
/**
* 列表接口(查询用户通过租户隔离)
* @param params
@ -89,6 +105,14 @@ export const saveOrUpdateUser = (params, isUpdate) => {
let url = isUpdate ? Api.edit : Api.save;
return defHttp.post({ url: url, params });
};
/**
* 保存或者更新专家用户
* @param params
*/
export const saveOrUpdateUserZJ = (params, isUpdate) => {
let url = isUpdate ? Api.editZJ : Api.saveZJ;
return defHttp.post({ url: url, params });
};
/**
* 唯一校验
* @param params

@ -6,6 +6,9 @@ enum Api {
list = '/sys/user/list',
save = '/sys/user/add',
edit = '/sys/user/edit',
saveZJ = '/expert/expert/addZJ',
editZJ = '/expert/expert/editZJ',
queryExpertById = '/expert/expert/queryById',
agentSave = '/sys/sysUserAgent/add',
agentEdit = '/sys/sysUserAgent/edit',
getUserRole = '/sys/user/queryUserRole',
@ -31,7 +34,15 @@ enum Api {
putCancelQuit = '/sys/user/putCancelQuit',
updateUserTenantStatus='/sys/tenant/updateUserTenantStatus',
getUserTenantPageList='/sys/tenant/getUserTenantPageList',
queryByUserId = '/expert/expert/queryByUserId',
}
/**
* userid判断是否为专家
* @param params
*/
export const queryByUserId = (params) => {
return defHttp.get({ url: Api.queryByUserId, params },{ successMessageMode: 'none' });
};
/**
* api
* @param params
@ -58,6 +69,12 @@ export const listNoCareTenant = (params) => defHttp.get({ url: Api.listNoCareTen
* @param params
*/
export const getUserRoles = (params) => defHttp.get({ url: Api.getUserRole, params }, { errorMessageMode: 'none' });
/**
*
* @param params
*/
export const queryExpertById = (params) => defHttp.get({ url: Api.queryExpertById, params }, { successMessageMode: 'none' });
/**
*
@ -92,6 +109,14 @@ export const saveOrUpdateUser = (params, isUpdate) => {
let url = isUpdate ? Api.edit : Api.save;
return defHttp.post({ url: url, params });
};
/**
*
* @param params
*/
export const saveOrUpdateUserZJ = (params, isUpdate) => {
let url = isUpdate ? Api.editZJ : Api.saveZJ;
return defHttp.post({ url: url, params });
};
/**
*
* @param params

@ -314,6 +314,243 @@ export const formSchema = [
},
},
];
export const formSchemaZJ = [
{
label: '',
field: 'id',
component: 'Input',
show: false,
},
{
label: '专家用户账号',
field: 'username',
component: 'Input',
dynamicDisabled: ({ values }) => {
return !!values.id;
},
dynamicRules: ({ model, schema }) => rules.duplicateCheckRule('sys_user', 'username', model, schema, true),
},
{
label: '登录密码',
field: 'password',
component: 'StrengthMeter',
rules: [
{
required: true,
message: '请输入登录密码',
},
],
},
{
label: '确认密码',
field: 'confirmPassword',
component: 'InputPassword',
dynamicRules: ({ values }) => rules.confirmPassword(values, true),
},
{
label: '用户姓名',
field: 'realname',
required: true,
component: 'Input',
},
{
label: '工号',
field: 'workNo',
required: true,
component: 'Input',
dynamicRules: ({ model, schema }) => rules.duplicateCheckRule('sys_user', 'work_no', model, schema, true),
},
{
label: '职务',
field: 'post',
required: false,
component: 'JSelectPosition',
componentProps: {
rowKey: 'code',
labelKey: 'name',
},
},
{
label: '角色',
field: 'selectedroles',
component: 'ApiSelect',
componentProps: {
mode: 'multiple',
api: getAllRolesListNoByTenant,
labelField: 'roleName',
valueField: 'id',
},
},
{
label: '所属部门',
field: 'selecteddeparts',
component: 'JSelectDept',
componentProps: ({ formActionType, formModel }) => {
return {
sync: false,
checkStrictly: true,
defaultExpandLevel: 2,
onSelect: (options, values) => {
const { updateSchema } = formActionType;
//所属部门修改后更新负责部门下拉框数据
updateSchema([
{
field: 'departIds',
componentProps: { options },
},
]);
//所属部门修改后更新负责部门数据
formModel.departIds && (formModel.departIds = formModel.departIds.filter((item) => values.value.indexOf(item) > -1));
},
};
},
},
{
label: '租户',
field: 'relTenantIds',
component: 'ApiSelect',
componentProps: {
mode: 'multiple',
api: getAllTenantList,
numberToString: true,
labelField: 'name',
valueField: 'id',
},
},
{
label: '身份',
field: 'userIdentity',
component: 'RadioGroup',
defaultValue: 1,
componentProps: ({ formModel }) => {
return {
options: [
{ label: '普通用户', value: 1, key: '1' },
{ label: '上级', value: 2, key: '2' },
],
onChange: () => {
formModel.userIdentity == 1 && (formModel.departIds = []);
},
};
},
},
{
label: '负责部门',
field: 'departIds',
component: 'Select',
componentProps: {
mode: 'multiple',
},
ifShow: ({ values }) => values.userIdentity == 2,
},
{
label: '头像',
field: 'avatar',
component: 'JImageUpload',
componentProps: {
fileMax: 1,
},
},
{
label: '生日',
field: 'birthday',
component: 'DatePicker',
},
{
label: '性别',
field: 'sex',
component: 'JDictSelectTag',
componentProps: {
dictCode: 'sex',
placeholder: '请选择性别',
stringToNumber: true,
},
},
{
label: '邮箱',
field: 'email',
component: 'Input',
dynamicRules: ({ model, schema }) => {
return [
{ ...rules.duplicateCheckRule('sys_user', 'email', model, schema, true)[0] },
{ ...rules.rule('email', false)[0] },
];
},
},
{
label: '手机号码',
field: 'phone',
component: 'Input',
dynamicRules: ({ model, schema }) => {
return [
{ ...rules.duplicateCheckRule('sys_user', 'phone', model, schema, true)[0] },
{ pattern: /^1[3456789]\d{9}$/, message: '手机号码格式有误' },
];
},
},
{
label: '座机',
field: 'telephone',
component: 'Input',
rules: [{ pattern: /^0\d{2,3}-[1-9]\d{6,7}$/, message: '请输入正确的座机号码' }],
},
{
label: '工作流引擎',
field: 'activitiSync',
defaultValue: 1,
component: 'JDictSelectTag',
componentProps: {
dictCode: 'activiti_sync',
type: 'radio',
stringToNumber: true,
},
},
{
label: '专家毕业院校',
field: 'expSc',
component: 'Input',
},
{
label: '专家履历',
field: 'expResume',
component: 'InputTextArea',
},
{
label: '专家学历',
field: 'expTitle',
component: 'Input',
},
{
label: '比赛',
field: 'compid',
component: 'Input',
show: false,
},
{
label: '比赛名称',
field: 'compName',
component: 'JPopup',
componentProps: ({ formActionType }) => {
const {setFieldsValue} = formActionType;
return{
setFieldsValue:setFieldsValue,
code:"comp_select",
fieldConfig: [
{ source: 'id', target: 'compid' },
{ source: 'comp_name', target: 'compName' },
],
multi:true
}
},
},
{
label: '状态',
field: 'stat',
component: 'JSwitch',
componentProps:{
},
},
];
export const formPasswordSchema = [
{
label: '用户账号',

@ -126,6 +126,244 @@ export const searchFormSchema: FormSchema[] = [
colProps: { span: 6 },
},
];
export const formSchemaZJ: FormSchema[] = [
{
label: '',
field: 'id',
component: 'Input',
show: false,
},
{
label: '专家账号',
field: 'username',
component: 'Input',
dynamicDisabled: ({ values }) => {
return !!values.id;
},
dynamicRules: ({ model, schema }) => rules.duplicateCheckRule('sys_user', 'username', model, schema, true),
},
{
label: '登录密码',
field: 'password',
component: 'StrengthMeter',
rules: [
{
required: true,
message: '请输入登录密码',
},
],
},
{
label: '确认密码',
field: 'confirmPassword',
component: 'InputPassword',
dynamicRules: ({ values }) => rules.confirmPassword(values, true),
},
{
label: '用户姓名',
field: 'realname',
required: true,
component: 'Input',
},
{
label: '工号',
field: 'workNo',
required: true,
component: 'Input',
dynamicRules: ({ model, schema }) => rules.duplicateCheckRule('sys_user', 'work_no', model, schema, true),
},
{
label: '职务',
field: 'post',
required: false,
component: 'JSelectPosition',
componentProps: {
rowKey: 'code',
labelKey: 'name',
},
},
{
label: '角色',
field: 'selectedroles',
component: 'ApiSelect',
componentProps: {
mode: 'multiple',
api: getAllRolesListNoByTenant,
labelField: 'roleName',
valueField: 'id',
},
},
{
label: '所属部门',
field: 'selecteddeparts',
component: 'JSelectDept',
componentProps: ({ formActionType, formModel }) => {
return {
sync: false,
checkStrictly: true,
defaultExpandLevel: 2,
onSelect: (options, values) => {
const { updateSchema } = formActionType;
//所属部门修改后更新负责部门下拉框数据
updateSchema([
{
field: 'departIds',
componentProps: { options },
},
]);
//所属部门修改后更新负责部门数据
formModel.departIds && (formModel.departIds = formModel.departIds.filter((item) => values.value.indexOf(item) > -1));
},
};
},
},
{
label: '租户',
field: 'relTenantIds',
component: 'ApiSelect',
componentProps: {
mode: 'multiple',
api: getAllTenantList,
numberToString: true,
labelField: 'name',
valueField: 'id',
},
},
{
label: '身份',
field: 'userIdentity',
component: 'RadioGroup',
defaultValue: 1,
componentProps: ({ formModel }) => {
return {
options: [
{ label: '普通用户', value: 1, key: '1' },
{ label: '上级', value: 2, key: '2' },
],
onChange: () => {
formModel.userIdentity == 1 && (formModel.departIds = []);
},
};
},
},
{
label: '负责部门',
field: 'departIds',
component: 'Select',
componentProps: {
mode: 'multiple',
},
ifShow: ({ values }) => values.userIdentity == 2,
},
{
label: '头像',
field: 'avatar',
component: 'JImageUpload',
componentProps: {
fileMax: 1,
},
},
{
label: '生日',
field: 'birthday',
component: 'DatePicker',
},
{
label: '性别',
field: 'sex',
component: 'JDictSelectTag',
componentProps: {
dictCode: 'sex',
placeholder: '请选择性别',
stringToNumber: true,
},
},
{
label: '邮箱',
field: 'email',
component: 'Input',
dynamicRules: ({ model, schema }) => {
return [
{ ...rules.duplicateCheckRule('sys_user', 'email', model, schema, true)[0] },
{ ...rules.rule('email', false)[0] },
];
},
},
{
label: '手机号码',
field: 'phone',
component: 'Input',
dynamicRules: ({ model, schema }) => {
return [
{ ...rules.duplicateCheckRule('sys_user', 'phone', model, schema, true)[0] },
{ pattern: /^1[3456789]\d{9}$/, message: '手机号码格式有误' },
];
},
},
{
label: '座机',
field: 'telephone',
component: 'Input',
rules: [{ pattern: /^0\d{2,3}-[1-9]\d{6,7}$/, message: '请输入正确的座机号码' }],
},
{
label: '工作流引擎',
field: 'activitiSync',
defaultValue: 1,
component: 'JDictSelectTag',
componentProps: {
dictCode: 'activiti_sync',
type: 'radio',
stringToNumber: true,
},
},
{
label: '专家毕业院校',
field: 'expSc',
component: 'Input',
},
{
label: '专家履历',
field: 'expResume',
component: 'InputTextArea',
},
{
label: '专家学历',
field: 'expTitle',
component: 'Input',
},
{
label: '比赛',
field: 'compid',
component: 'Input',
show: false,
},
{
label: '比赛名称',
field: 'compName',
component: 'JPopup',
componentProps: ({ formActionType }) => {
const {setFieldsValue} = formActionType;
return{
setFieldsValue:setFieldsValue,
code:"comp_select",
fieldConfig: [
{ source: 'id', target: 'compid' },
{ source: 'comp_name', target: 'compName' },
],
multi:true
}
},
},
{
label: '状态',
field: 'stat',
component: 'JSwitch',
componentProps:{
},
},
];
export const formSchema: FormSchema[] = [
{

Loading…
Cancel
Save