JAVA+VUE实现动态表单配置

功能描述:

资产管理系统中,在资产分类中,给同一种类型的资产配置定制化的表单项,并实现不同类型显示不同的数据,如图所示:

数据库设计部分:

1.表单项表

CREATE TABLE `dct_smp`.`t_asset_product_definitions`  (
  `id` bigint NOT NULL,
  `product_id` bigint NOT NULL COMMENT '分类',
  `name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '名称',
  `label` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '显示名称',
  `data_type` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '属性类型',
  `length` int NULL DEFAULT NULL COMMENT '长度',
  `ui_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '表单类型',
  `default_values` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '默认值',
  `required` int NOT NULL COMMENT '是否必填',
  `placeholder` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '提示信息',
  `dct_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '数字字典code值',
  `is_lock` int NULL DEFAULT NULL COMMENT '是否锁定',
  `remark` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注',
  `created_by` bigint NOT NULL COMMENT '创建人',
  `created_date` bigint NOT NULL COMMENT '创建时间',
  `modified_by` bigint NULL DEFAULT NULL COMMENT '修改人',
  `modified_date` bigint NULL DEFAULT NULL COMMENT '修改时间',
  `ip` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'IP',
  `priority` int NOT NULL DEFAULT 1 COMMENT '优先级,越大优先级越高',
  `status` tinyint NOT NULL DEFAULT 1 COMMENT '数据状态,1有效0删除',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '资产产品元素分类' ROW_FORMAT = Dynamic;

2.数据表:

CREATE TABLE `dct_smp`.`t_asset_product_metas`  (
  `id` bigint NOT NULL,
  `detail_id` bigint NULL DEFAULT NULL COMMENT '要素id',
  `asset_id` bigint NULL DEFAULT NULL COMMENT '资产id',
  `assets_no` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '资产编号',
  `meta_key` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '关联字段名称',
  `meta_value` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL COMMENT '关联字段内容',
  `meta_priority` int NULL DEFAULT 0 COMMENT '优先级',
  `created_by` bigint NOT NULL COMMENT '创建人',
  `created_date` bigint NOT NULL COMMENT '创建时间',
  `modified_by` bigint NULL DEFAULT NULL COMMENT '修改人',
  `modified_date` bigint NULL DEFAULT NULL COMMENT '修改时间',
  `ip` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'IP',
  `priority` int NOT NULL DEFAULT 1 COMMENT '优先级,越大优先级越高',
  `status` tinyint NOT NULL DEFAULT 1 COMMENT '数据状态,1有效0删除',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '资产产品元素扩展' ROW_FORMAT = Dynamic;

  

JAVA部分:

表单元素表

package com.cloudoer.dct.ams.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cloudoer.dct.ams.mapstruts.AssetProductDefinitionMapStruct;
import com.cloudoer.dct.ams.service.i.AssetProductDefinitionService;
import com.cloudoer.dct.ams.service.i.AssetProductMetaService;
import com.cloudoer.dct.core.controller.BaseController;
import com.cloudoer.dct.core.model.Page;
import com.cloudoer.dct.core.model.dto.ams.AssetProductDefinitionDTO;
import com.cloudoer.dct.core.model.entity.ams.AssetProductDefinition;
import com.cloudoer.dct.core.model.query.ams.AssetProductDefinitionQuery;
import com.cloudoer.dct.core.model.vo.ams.AssetProductDefinitionVO;
import com.cloudoer.dct.core.support.BeanUtil;
import com.cloudoer.dct.core.support.Condition;
import com.cloudoer.dct.core.support.QueryContext;
import com.cloudoer.framework.core.domain.RO;
import com.google.common.collect.Lists;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author cobot
 * @version 1.0.0
 * @since 2024-09-02
 */
@RestController
@RequestMapping("/asset/definitions")
@Slf4j
@Tag(name = "资产产品元素分类", description = "资产产品元素分类管理")
public class AssetProductDefinitionController extends BaseController<AssetProductDefinition> {

    @Autowired
    private AssetProductDefinitionService assetProductDefinitionService;

    @Autowired
    private AssetProductMetaService assetProductMetaService;

    @Autowired
    private AssetProductDefinitionMapStruct assetProductDefinitionMapStruct;

    @Operation(summary = "资产产品元素分类查询", description = "根据筛选条件分页查询,以及按照指定字段进行排序")
    @ApiResponses({
            @ApiResponse(responseCode = "100200", description = "成功", content = {@Content(schema = @Schema(implementation = AssetProductDefinitionVO.class))})
    })
    @GetMapping(name = "查询")
    public Object list(AssetProductDefinitionQuery assetProductDefinitionQuery, QueryContext queryContext) {
        QueryWrapper<AssetProductDefinition> queryWrapper = Condition.getQueryWrapper(assetProductDefinitionQuery, queryContext, AssetProductDefinition.class);
        Page<AssetProductDefinitionVO> page = assetProductDefinitionService.find(Condition.getPage(queryContext), queryWrapper);
        return RO.ok(page);
    }

    @Operation(summary = "资产产品元素分类详情", description = "根据ID获取资产产品元素分类详细信息")
    @Parameter(name = "id", description = "资产产品元素分类ID", in = ParameterIn.PATH, schema = @Schema(type = "Long"), required = true)
    @ApiResponses({
            @ApiResponse(responseCode = "100200", description = "成功", content = {@Content(schema = @Schema(implementation = AssetProductDefinitionVO.class))})
    })
    @GetMapping(value = "/{id}", name = "详情")
    public Object view(@PathVariable("id") Long id) {
        log.info("get AssetProductDefinition Id:{}", id);
        AssetProductDefinitionVO assetProductDefinitionVO = assetProductDefinitionService.find(id);
        return RO.ok(assetProductDefinitionVO);
    }

    @Operation(summary = "创建资产产品元素分类", description = "创建资产产品元素分类信息")
    @ApiResponses({
            @ApiResponse(responseCode = "100200", description = "成功", content = {@Content(schema = @Schema(implementation = AssetProductDefinition.class))})
    })
    @PostMapping(name = "创建")
    public Object create(@RequestBody AssetProductDefinitionDTO assetProductDefinitionDTO, ServerHttpRequest request) {
        log.info("add AssetProductDefinition DTO:{}", assetProductDefinitionDTO);
        AssetProductDefinition assetProductDefinition = new AssetProductDefinition();
        BeanUtil.copyProperties(assetProductDefinitionDTO, assetProductDefinition);
        this.packAddBaseProps(assetProductDefinition, request);
        boolean flag = assetProductDefinitionService.save(assetProductDefinition);
        return RO.status(flag, assetProductDefinition);
    }

    @Operation(summary = "复制资产产品元素分类", description = "根据ID复制资产产品元素分类")
    @Parameter(name = "id", description = "资产产品元素分类ID", in = ParameterIn.PATH, schema = @Schema(type = "Long"), required = true)
    @ApiResponses({
            @ApiResponse(responseCode = "100200", description = "成功", content = {@Content(schema = @Schema(implementation = AssetProductDefinition.class))})
    })
    @PostMapping(value = "/{id}", name = "复制")
    public Object copy(@PathVariable("id") Long id, ServerHttpRequest request) {
        AssetProductDefinition assetProductDefinition = assetProductDefinitionService.getById(id);
        if (assetProductDefinition == null) {
            return RO.fail("不存在的id");
        }
        assetProductDefinition.setId(null);
        //assetProductDefinition.setName(assetProductDefinition.getName() + "_副本");
        this.packAddBaseProps(assetProductDefinition, request);
        boolean flag = assetProductDefinitionService.save(assetProductDefinition);
        return RO.status(flag, assetProductDefinition);
    }

    @Operation(summary = "修改资产产品元素分类", description = "根据ID, 修改资产产品元素分类信息")
    @Parameter(name = "id", description = "资产产品元素分类ID", in = ParameterIn.PATH, schema = @Schema(type = "Long"), required = true)
    @ApiResponses({
            @ApiResponse(responseCode = "100200", description = "成功", content = {@Content(schema = @Schema(implementation = AssetProductDefinition.class))})
    })
    @PutMapping(value = "/{id}", name = "修改")
    public Object update(@PathVariable("id") Long id, @RequestBody AssetProductDefinitionDTO assetProductDefinitionDTO, ServerHttpRequest request) {
        log.info("put modify id:{}, AssetProductDefinition DTO:{}", id, assetProductDefinitionDTO);
        AssetProductDefinition assetProductDefinition = assetProductDefinitionService.getById(id);
        if (null == assetProductDefinition) {
            return RO.fail("不存在的id");
        }
        BeanUtil.copyProperties(assetProductDefinitionDTO, assetProductDefinition);
        this.packModifyBaseProps(assetProductDefinition, request);
        boolean flag = assetProductDefinitionService.updateById(assetProductDefinition);
        return RO.status(flag, assetProductDefinition);
    }

    @Operation(summary = "修改资产产品元素分类", description = "根据ID, 修改资产产品元素分类信息")
    @Parameter(name = "id", description = "资产产品元素分类ID", in = ParameterIn.PATH, schema = @Schema(type = "Long"), required = true)
    @ApiResponses({
            @ApiResponse(responseCode = "100200", description = "成功", content = {@Content(schema = @Schema(implementation = AssetProductDefinition.class))})
    })
    @PutMapping(value = "/saveOrUpdate/{id}", name = "修改")
    public Object saveOrUpdate(@PathVariable("id") Long id, @RequestBody List<AssetProductDefinitionDTO> assetProductDefinitionDTO, ServerHttpRequest request) {
        log.info("put modify id:{}, AssetProductDefinition DTO:{}", id, assetProductDefinitionDTO);
        List<AssetProductDefinitionDTO> unlockDTOS = assetProductDefinitionDTO.parallelStream().filter(t -> t.getIsLock() == null || t.getIsLock() == 0).collect(Collectors.toList());
        // 通过源数据和dto对比,找到多的数,并删除
        QueryWrapper<AssetProductDefinition> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_id", id);
        queryWrapper.eq("is_lock", 0);
        List<AssetProductDefinitionVO> assetProductDefinitionVOS = assetProductDefinitionService.find(queryWrapper);
        if (CollectionUtils.isNotEmpty(assetProductDefinitionVOS)) {
            List<AssetProductDefinitionVO> delList = assetProductDefinitionVOS.stream().filter(item -> unlockDTOS.stream().noneMatch(item2 -> item2.getId().equals(item.getId()) )).collect(Collectors.toList());
            boolean removeByIds = assetProductDefinitionService.removeByIds(delList);
            log.info("put modify id:{}, saveOrUpdate DTO:{}", id, removeByIds);
        }
        List<AssetProductDefinition> dataList = Lists.newArrayList();
        unlockDTOS.forEach(dto -> {
            AssetProductDefinition assetProductDefinition = assetProductDefinitionMapStruct.convertDTO(dto);
            assetProductDefinition.setIsLock(0);
            assetProductDefinition.setProductId(id);
            BeanUtil.packAddBaseProps(assetProductDefinition, request);
            dataList.add(assetProductDefinition);
        });
        boolean batch = assetProductDefinitionService.saveOrUpdateBatch(dataList);
        return RO.status(batch, dataList);
    }

    @Operation(summary = "删除资产产品元素分类", description = "根据ID, 删除资产产品元素分类信息")
    @Parameter(name = "id", description = "资产产品元素分类ID", in = ParameterIn.PATH, schema = @Schema(type = "Long"), required = true)
    @ApiResponses({
            @ApiResponse(responseCode = "100200", description = "成功")
    })
    @DeleteMapping(value = "/{id}", name = "删除")
    public Object remove(@PathVariable("id") Long id, ServerHttpRequest request) {
        log.info("delete AssetProductDefinition, id:{}", id);
        AssetProductDefinition assetProductDefinition = new AssetProductDefinition();
        assetProductDefinition.setId(id);
        this.packModifyBaseProps(assetProductDefinition, request);
        boolean flag = assetProductDefinitionService.delete(assetProductDefinition);
        return RO.status(flag);
    }

    @Operation(summary = "批量删除资产产品元素分类", description = "根据ID集合, 批量删除资产产品元素分类信息")
    @Parameter(name = "ids", description = "资产产品元素分类ID集合", in = ParameterIn.DEFAULT, schema = @Schema(type = "List"), required = true)
    @ApiResponses({
            @ApiResponse(responseCode = "100200", description = "成功")
    })
    @DeleteMapping(name = "批量删除")
    public Object remove(@RequestBody Map<String, Object> params, ServerHttpRequest request) {
        boolean flag = false;
        if (params.get("ids") != null) {
            List<String> ids = (List<String>) params.get("ids");
            if (CollectionUtils.isNotEmpty(ids)) {
                flag = assetProductDefinitionService.delete(ids, getUserId(request));
            }
        }
        return RO.status(flag);
    }

}

  

package com.cloudoer.dct.core.model.entity.ams;

import com.baomidou.mybatisplus.annotation.TableName;
import com.cloudoer.dct.core.model.entity.BaseEntity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import java.io.Serializable;

/**
 * @author cobot
 * @version 1.0.0
 * @since 2024-09-02
 */
@Schema(title = "资产产品元素分类")
@Data
@TableName("t_asset_product_definitions")
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class AssetProductDefinition extends BaseEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    @Schema(name = "productId", title = "分类")
    private Long productId;

    @Schema(name = "name", title = "名称")
    private String name;

    @Schema(name = "label", title = "显示名称")
    private String label;

    @Schema(name = "dataType", title = "属性类型")
    private String dataType;

    @Schema(name = "uiType", title = "表单类型")
    private String uiType;

    @Schema(name = "length", title = "长度")
    private Integer length;

    @Schema(name = "defaultValues", title = "默认值")
    private String defaultValues;

    @Schema(name = "required", title = "是否必填")
    private Integer required;

    @Schema(name = "placeholder", title = "提示信息")
    private String placeholder;

    @Schema(name = "isLock", title = "是否可以修改 0:可修改 1:不可修改")
    private Integer isLock;

    @Schema(name = "remark", title = "备注")
    private String remark;

    @Schema(name = "dctCode", title = "数字字典code值")
    private String dctCode;

}

  

package com.cloudoer.dct.core.model.dto.ams;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;

import java.io.Serializable;

/**
 * @author cobot
 * @version 1.0.0
 * @since 2024-09-02
 */
@Schema(title = "资产产品元素分类")
@Data
@ToString(callSuper = true)
@JsonIgnoreProperties(ignoreUnknown = true)
public class AssetProductDefinitionDTO implements Serializable {
    private static final long serialVersionUID = 1L;

    @Schema(name = "id", title = "主键ID")
    private Long id;

    @Schema(name = "productId", title = "分类")
    private Long productId;

    @Schema(name = "name", title = "名称")
    private String name;

    @Schema(name = "label", title = "显示名称")
    private String label;

    @Schema(name = "dataType", title = "属性类型")
    private String dataType;

    @Schema(name = "uiType", title = "表单类型")
    private String uiType;

    @Schema(name = "length", title = "长度")
    private Integer length;

    @Schema(name = "defaultValues", title = "默认值")
    private String defaultValues;

    @Schema(name = "required", title = "是否必填")
    private Integer required;

    @Schema(name = "placeholder", title = "提示信息")
    private String placeholder;

    @Schema(name = "isLock", title = "是否可以修改 0:可修改 1:不可修改")
    private Integer isLock;

    @Schema(name = "priority", title = "优先级")
    private Integer priority;

    @Schema(name = "remark", title = "备注")
    private String remark;

    @Schema(name = "dctCode", title = "数字字典code值")
    private String dctCode;

}

  

package com.cloudoer.dct.core.model.query.ams;

import com.cloudoer.dct.core.model.query.BaseQuery;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import java.io.Serializable;

/**
 * @author cobot
 * @version 1.0.0
 * @since 2024-09-02
 */
@Schema(title = "资产产品元素分类")
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class AssetProductDefinitionQuery extends BaseQuery implements Serializable {
    private static final long serialVersionUID = 1L;

    @Schema(name = "detailId", title = "申购ID")
    private Long detailId;

    @Schema(name = "productId", title = "分类")
    private String productId;

    @Schema(name = "name", title = "名称")
    private String name;

    @Schema(name = "label", title = "显示名称")
    private String label;

    @Schema(name = "dataType", title = "属性类型")
    private String dataType;

    @Schema(name = "uiType", title = "表单类型")
    private String uiType;

    @Schema(name = "length", title = "长度")
    private Integer length;

    @Schema(name = "defaultValues", title = "默认值")
    private String defaultValues;

    @Schema(name = "required", title = "是否必填")
    private String required;

    @Schema(name = "placeholder", title = "提示信息")
    private String placeholder;

    @Schema(name = "isLock", title = "是否可以修改 0:可修改 1:不可修改")
    private Integer isLock;

    @Schema(name = "remark", title = "备注")
    private String remark;

    @Schema(name = "dctCode", title = "数字字典code值")
    private String dctCode;

}

  

package com.cloudoer.dct.core.model.vo.ams;

import com.cloudoer.dct.core.model.vo.BaseVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import java.io.Serializable;

/**
 * @author cobot
 * @version 1.0.0
 * @since 2024-09-02
 */
@Schema(title = "资产产品元素分类")
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class AssetProductDefinitionVO extends BaseVO implements Serializable {
    private static final long serialVersionUID = 1L;

    @Schema(name = "productId", title = "分类")
    private Long productId;

    @Schema(name = "name", title = "名称")
    private String name;

    @Schema(name = "label", title = "显示名称")
    private String label;

    @Schema(name = "dataType", title = "属性类型")
    private String dataType;

    @Schema(name = "uiType", title = "表单类型")
    private String uiType;

    @Schema(name = "length", title = "长度")
    private Integer length;

    @Schema(name = "defaultValues", title = "默认值")
    private String defaultValues;

    @Schema(name = "required", title = "是否必填")
    private Integer required;

    @Schema(name = "placeholder", title = "提示信息")
    private String placeholder;

    @Schema(name = "isLock", title = "是否可以修改 0:可修改 1:不可修改")
    private Integer isLock;

    @Schema(name = "remark", title = "备注")
    private String remark;

    @Schema(name = "dctCode", title = "数字字典code值")
    private String dctCode;


}

  

package com.cloudoer.dct.ams.mapstruts;

import com.cloudoer.dct.core.model.dto.ams.AssetProductDefinitionDTO;
import com.cloudoer.dct.core.model.entity.ams.AssetProductDefinition;
import com.cloudoer.dct.core.model.vo.ams.AssetProductDefinitionVO;
import com.cloudoer.dct.core.model.vo.ams.AssetSubscriptionDetailVO;
import org.mapstruct.InjectionStrategy;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;

import java.util.List;

@Mapper(componentModel = "spring", injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public interface AssetProductDefinitionMapStruct {

    @Mappings({})
    AssetProductDefinition convertDTO(AssetProductDefinitionDTO dto);


    List<AssetProductDefinition> convertDTO(List<AssetProductDefinitionDTO> dtoList);

    @Mappings({})
    AssetProductDefinition convertVO(AssetProductDefinitionVO vo);


    List<AssetSubscriptionDetailVO> convertVO(List<AssetSubscriptionDetailVO> voList);

}

  

package com.cloudoer.dct.ams.service.i;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cloudoer.dct.core.constant.Constant;
import com.cloudoer.dct.core.model.Page;
import com.cloudoer.dct.core.model.entity.ams.AssetProductDefinition;
import com.cloudoer.dct.core.model.vo.BaseVO;
import com.cloudoer.dct.core.model.vo.ams.AssetProductDefinitionVO;
import com.cloudoer.dct.core.support.BeanUtil;
import com.cloudoer.dct.core.support.Condition;
import com.cloudoer.framework.core.domain.SortingContext;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author cobot
 * @version 1.0.0
 * @since 2024-09-02
 */
public interface AssetProductDefinitionService extends IService<AssetProductDefinition> {

    /**
     * 根据id查询一条资产产品元素分类。
     *
     * @param id 数据唯一id。
     * @return 查询到的资产产品元素分类数据。
     */
    default AssetProductDefinitionVO find(Long id){
        if(id == null){
            return null;
        }
        AssetProductDefinition assetProductDefinition = this.getById(id);
        if (null != assetProductDefinition) {
            return BeanUtil.copyProperties(assetProductDefinition, new AssetProductDefinitionVO());
        }
        return null;
    }

    /**
     * 根据id集合查询多条资产产品元素分类。
     *
     * @param ids id集合
     * @return 查询到的资产产品元素分类数据。
     */
    default List<AssetProductDefinitionVO> find(Collection<? extends Serializable> ids){
        if (CollectionUtils.isEmpty(ids)) {
            return null;
        }
        List<AssetProductDefinition> assetProductDefinitionList = listByIds(ids);
        if (CollectionUtils.isNotEmpty(assetProductDefinitionList)) {
            List<AssetProductDefinitionVO> list = new ArrayList<>(assetProductDefinitionList.size());
            for (AssetProductDefinition assetProductDefinition : assetProductDefinitionList) {
            list.add(BeanUtil.copyProperties(assetProductDefinition, new AssetProductDefinitionVO()));
            }
            return list;
        }
        return null;
    }


    /**
    * 根据id集合查询多条题目。
    *
    * @param ids id集合
    * @return 查询到的题目数据。
    */
    default Map<Long, AssetProductDefinitionVO> findMap(Collection<? extends Serializable> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return new HashMap<>();
        }
        List<AssetProductDefinitionVO> list = find(ids);
        if (CollectionUtils.isNotEmpty(list)) {
            Map<Long, AssetProductDefinitionVO> map = new LinkedHashMap<>(list.size());
            for (AssetProductDefinitionVO assetProductDefinitionVO : list) {
                map.put(assetProductDefinitionVO.getId(), assetProductDefinitionVO);
            }
            return map;
        }
        return new HashMap<>(0);
    }

    /**
    * 根据id集合查询多条题目。
    *
    * @param ids id集合
    * @return 查询到的题目数据。
    */
    default Map<Long, AssetProductDefinitionVO> findMap(String fieldName, Collection<? extends Serializable> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return new HashMap<>(0);
        }
        QueryWrapper<AssetProductDefinition> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", ids);
        return findMap(fieldName, ids);
    }

    /**
     * 根据查询条件得到数据列表
     *
     * @param queryWrapper 查询条件。
     * @return 查询结果的数据集合。
     */
    default List<AssetProductDefinitionVO> find(QueryWrapper<AssetProductDefinition> queryWrapper) {
        List<AssetProductDefinitionVO> records = null;
        List<AssetProductDefinition> list = list(queryWrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            records = new ArrayList<>(list.size());
            for (AssetProductDefinition assetProductDefinition : list) {
                records.add(BeanUtil.copyProperties(assetProductDefinition, new AssetProductDefinitionVO()));
            }
        }
        return records;
    }

    /**
     * 根据查询条件得到数据列表
     *
     * @param queryWrapper 查询条件。
     * @return 查询结果的数据集合。
     */
    default Map<Long, AssetProductDefinitionVO> findMap(QueryWrapper<AssetProductDefinition> queryWrapper) {
        List<AssetProductDefinitionVO> list = find(queryWrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            Map<Long, AssetProductDefinitionVO> map = new LinkedHashMap<>(list.size());
            for (AssetProductDefinitionVO assetProductDefinitionVO : list) {
                map.put(assetProductDefinitionVO.getId(), assetProductDefinitionVO);
            }
            return map;
        }
        return new HashMap<>(0);
    }

    /**
     * 根据查询指定字段
     *
     * @param fieldName    属性名称
     * @param queryWrapper 查询条件
     * @return 查询结果的数据集合
     */
    default Map<Long, String> findMap(String fieldName, QueryWrapper<AssetProductDefinition> queryWrapper) {
        queryWrapper.select("id", fieldName);
        List<Map<String, Object>> list = listMaps(queryWrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            Map<Long, String> map = new LinkedHashMap<>(list.size());
            for (Map<String, Object> data : list) {
                Object key = data.get("id");
                if (key != null && StringUtils.isNotBlank(key.toString())) {
                    String val = "";
                    if (data.get(fieldName) != null) {
                        val = data.get(fieldName).toString();
                    }
                    map.put(Long.valueOf(key.toString()), val);
                }
            }
            return map;
        }
        return new HashMap<>(0);
    }

    /**
     * 根据查询条件得到数据列表,包含分页和排序信息。
     *
     * @param queryWrapper 查询条件。
     * @param page 分页排序信息。
     * @return 查询结果的数据集合。
     */
    default Page<AssetProductDefinitionVO> find(IPage<AssetProductDefinition> page, QueryWrapper<AssetProductDefinition> queryWrapper){
        IPage<AssetProductDefinition> ipage = this.page(page, queryWrapper);
        Page<AssetProductDefinitionVO> dataPage = new Page(ipage.getTotal(), ipage.getCurrent(), ipage.getSize());
        List<AssetProductDefinition> assetProductDefinitionList = ipage.getRecords();
        if (CollectionUtils.isNotEmpty(assetProductDefinitionList)) {
            List<AssetProductDefinitionVO> records = new ArrayList<>(assetProductDefinitionList.size());
            for (AssetProductDefinition assetProductDefinition : assetProductDefinitionList) {
                records.add(BeanUtil.copyProperties(assetProductDefinition, new AssetProductDefinitionVO()));
            }
            dataPage.setRecords(records);
        }
        List<OrderItem> orders = ipage.orders();
        if (CollectionUtils.isNotEmpty(orders)) {
            Map<String, String> scs = new LinkedHashMap<>(orders.size());
            for (OrderItem orderItem : orders) {
                scs.put(orderItem.getColumn(), orderItem.isAsc() ? SortingContext.ASC.toLowerCase() : SortingContext.DESC.toLowerCase());
            }
            dataPage.setScs(scs);
        }
        return dataPage;
    }

    /**
     * 根据查询条件得到数据列表
     *
     * @param groupName    属性名称
     * @param queryWrapper 查询条件
     * @return 查询结果的数据集合
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    default Map<String, List<AssetProductDefinitionVO>> findGroupMap(String groupName, QueryWrapper<AssetProductDefinition> queryWrapper) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        List<AssetProductDefinitionVO> list = find(queryWrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            String methodName = "get".concat(groupName.substring(0, 1).toUpperCase()).concat(groupName.substring(1));
            Method method = AssetProductDefinitionVO.class.getMethod(methodName);
            Map<String, List<AssetProductDefinitionVO>> map = new LinkedHashMap<>(list.size());
            for (AssetProductDefinitionVO assetProductDefinitionVO : list) {
                Object key = method.invoke(assetProductDefinitionVO);
                if (key != null && StringUtils.isNotBlank(key.toString())) {
                    if (!map.containsKey(key.toString())) {
                        map.put(key.toString(), new ArrayList<>());
                    }
                    map.get(key.toString()).add(assetProductDefinitionVO);
                }
            }
            return map;
        }
        return new HashMap<>(0);
    }

        /**
         * @param params
         */
        default List<Map<String, Object>> udd(Map<String, Object> params) {
            List<Map<String, Object>> dataList = new ArrayList<>();
            QueryWrapper<AssetProductDefinition> queryWrapper = Condition.getQueryWrapper(params,  AssetProductDefinition.class);
            queryWrapper.select("id", "name");
            queryWrapper.orderByDesc("priority");
            queryWrapper.orderByDesc("id");
            List<AssetProductDefinition> list = list(queryWrapper);
            if (CollectionUtils.isEmpty(list)) {
                return dataList;
            }
            for (AssetProductDefinition obj : list) {
                Map<String, Object> dmap = new HashMap<>();
                dmap.put("key", obj.getId());
                //dmap.put("val", obj.getName());
                dataList.add(dmap);
            }
            return dataList;
        }

    /**
     * 修改某个字段的值
     *
     * @param id
     * @param key
     * @param value
     * @param userId
     * @return
     */
    default boolean update(Long id, String key, Object value, Long userId) {
        if (id != null && StringUtils.isNotBlank(key) && !Constant.DONT_UPDATE_COLUMNS.contains(key.toLowerCase()) && userId != null) {
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.set(key, value);
            updateWrapper.set("modified_by", userId);
            updateWrapper.set("modified_date", System.currentTimeMillis());
            updateWrapper.eq("id", id);
            return update(updateWrapper);
        }
        return false;
    }

    /**
     * 修改某个字段的值
     *
     * @param ids
     * @param key
     * @param value
     * @param userId
     * @return
     */
    default boolean update(Collection<? extends Serializable> ids, String key, Object value, Long userId) {
        if (CollectionUtils.isNotEmpty(ids) && StringUtils.isNotBlank(key) && !Constant.DONT_UPDATE_COLUMNS.contains(key.toLowerCase()) && userId != null) {
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.set(key, value);
            updateWrapper.set("modified_by", userId);
            updateWrapper.set("modified_date", System.currentTimeMillis());
            updateWrapper.in("id", ids);
            return update(updateWrapper);
        }
        return false;
    }

    /**
     * 修改多个字段的值
     *
     * @param id
     * @param data
     * @param userId
     * @return
     */
    default boolean update(Long id, Map<String, Object> data, Long userId) {
        if (id != null && MapUtils.isNotEmpty(data) && userId != null) {
            boolean update = false;
            UpdateWrapper updateWrapper = new UpdateWrapper();
                for (Map.Entry<String, Object> entry : data.entrySet()) {
                if (!Constant.DONT_UPDATE_COLUMNS.contains(entry.getKey().toLowerCase())) {
                    update = true;
                    updateWrapper.set(entry.getKey(), entry.getValue());
                }
            }
            if (update) {
                updateWrapper.set("modified_by", userId);
                updateWrapper.set("modified_date", System.currentTimeMillis());
                updateWrapper.eq("id", id);
                return update(updateWrapper);
            }
        }
        return false;
    }

    /**
     * 修改多个字段的值
     *
     * @param ids
     * @param data
     * @param userId
     * @return
     */
    default boolean update(Collection<? extends Serializable> ids, Map<String, Object> data, Long userId) {
        if (CollectionUtils.isNotEmpty(ids) && MapUtils.isNotEmpty(data) && userId != null) {
            boolean update = false;
            UpdateWrapper updateWrapper = new UpdateWrapper();
                for (Map.Entry<String, Object> entry : data.entrySet()) {
                if (!Constant.DONT_UPDATE_COLUMNS.contains(entry.getKey().toLowerCase())) {
                    update = true;
                    updateWrapper.set(entry.getKey(), entry.getValue());
                }
            }
            if (update) {
                updateWrapper.set("modified_by", userId);
                updateWrapper.set("modified_date", System.currentTimeMillis());
                updateWrapper.in("id", ids);
                return update(updateWrapper);
            }
        }
        return false;
    }

    /**
     * 逻辑删除
     *
     * @param assetProductDefinition
     * @return
     */
    default boolean delete(AssetProductDefinition assetProductDefinition) {
        if(assetProductDefinition != null && assetProductDefinition.getId() != null && assetProductDefinition.getModifiedBy() != null){
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.set("status", 0);
            updateWrapper.set("modified_by", assetProductDefinition.getModifiedBy());
            updateWrapper.set("modified_date", assetProductDefinition.getModifiedDate());
            updateWrapper.eq("id", assetProductDefinition.getId());
            return update(updateWrapper);
        }
        return false;
    }

    /**
     * 逻辑删除
     *
     * @param id
     * @param userId
     * @return
     */
    default boolean delete(Long id, Long userId) {
        if(id != null && userId != null){
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.set("status", 0);
            updateWrapper.set("modified_by", userId);
            updateWrapper.set("modified_date", System.currentTimeMillis());
            updateWrapper.eq("id", id);
            return update(updateWrapper);
        }
        return false;
    }

    /**
     * 逻辑删除
     *
     * @param ids
     * @param userId
     * @return
     */
    default boolean delete(Collection<? extends Serializable> ids, Long userId) {
        boolean flag = false;
        if(CollectionUtils.isNotEmpty(ids) && userId != null){
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.set("status", 0);
            updateWrapper.set("modified_by", userId);
            updateWrapper.set("modified_date", System.currentTimeMillis());
            updateWrapper.in("id", ids);
            return update(updateWrapper);
        }
        return false;
    }

        /**
         * @param list
         * @param field
         * @param targetField
         * @throws InvocationTargetException
         * @throws IllegalAccessException
         */
        default void inflate(Collection<? extends BaseVO> list, String field, String targetField) throws InvocationTargetException, IllegalAccessException {
            List objectIds = BeanUtil.getObjectIds(list, field);
            if (CollectionUtils.isEmpty(objectIds)) {
                return;
            }
            QueryWrapper<AssetProductDefinition> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("id", "name");
            queryWrapper.in("id", objectIds);
            List<AssetProductDefinition> dataList = list(queryWrapper);
            if (CollectionUtils.isEmpty(dataList)) {
                return;
            }
            Map<String, AssetProductDefinition> dataMap = dataList.stream().collect(Collectors.toMap(item -> item.getId().toString(), obj -> obj));
            String getMethodName = "get".concat(field.substring(0, 1).toUpperCase()).concat(field.substring(1));
            String setMethodName = "set".concat(targetField.substring(0, 1).toUpperCase()).concat(targetField.substring(1));
            for (BaseVO vo : list) {
                Method getMethod = BeanUtil.getObjectMethodByName(vo, getMethodName);
                if (getMethod == null) {
                    continue;
                }
                Object orgId = getMethod.invoke(vo);
                if (orgId == null) {
                    continue;
                }
                AssetProductDefinition obj = dataMap.getOrDefault(orgId.toString(), null);
                if (obj == null) {
                    continue;
                }
                Method setMethod = BeanUtil.getObjectMethodByName(vo, setMethodName, String.class);
                if (setMethod != null) {
                    //setMethod.invoke(vo, obj.getName());
                } else {
                    //vo.addAttribute(targetField, obj.getName());
                }
            }

        }

        /**
         * @param vo
         * @param field
         * @param targetField
         */
        default void inflate(BaseVO vo, String field, String targetField) throws InvocationTargetException, IllegalAccessException {
            Object objectId = BeanUtil.getObjectId(vo, field);
            if (objectId == null) {
                return;
            }
            QueryWrapper<AssetProductDefinition> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("id", "name");
            queryWrapper.eq("id", objectId);
            AssetProductDefinition obj = getOne(queryWrapper);
            if (obj == null) {
                return;
            }
            String setMethodName = "set".concat(targetField.substring(0, 1).toUpperCase()).concat(targetField.substring(1));
            Method setMethod = BeanUtil.getObjectMethodByName(vo, setMethodName, String.class);
            if (setMethod != null) {
                //setMethod.invoke(vo, obj.getName());
            } else {
                //vo.addAttribute(targetField, obj.getName());
            }
        }
}

  

<?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.cloudoer.dct.ams.dao.AssetProductDefinitionMapper">
    <resultMap type="com.cloudoer.dct.core.model.entity.ams.AssetProductDefinition" id="AssetProductDefinitionMap">
        <id property="id" column="id" jdbcType="BIGINT"/>
        <result property="productId" column="product_id" jdbcType="BIGINT"/>
        <result property="name" column="name" jdbcType="VARCHAR"/>
        <result property="label" column="label" jdbcType="VARCHAR"/>
        <result property="dataType" column="data_type" jdbcType="INTEGER"/>
        <result property="uiType" column="ui_type" jdbcType="INTEGER"/>
        <result property="defaultValues" column="default_values" jdbcType="VARCHAR"/>
        <result property="remark" column="remark" jdbcType="VARCHAR"/>
        <result property="required" column="required" jdbcType="INTEGER"/>
        <result property="isLock" column="is_lock" jdbcType="INTEGER"/>
        <result property="placeholder" column="placeholder" jdbcType="VARCHAR"/>
        <result property="dctCode" column="dct_code" jdbcType="VARCHAR"/>
        <result property="createdBy" column="created_by" jdbcType="BIGINT"/>
        <result property="createdDate" column="created_date" jdbcType="BIGINT"/>
        <result property="modifiedBy" column="modified_by" jdbcType="BIGINT"/>
        <result property="modifiedDate" column="modified_date" jdbcType="BIGINT"/>
        <result property="priority" column="priority" jdbcType="INTEGER"/>
        <result property="status" column="status" jdbcType="INTEGER"/>
    </resultMap>
</mapper>

  数据表

package com.cloudoer.dct.core.model.dto.ams;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;

import java.io.Serializable;

/**
 * @author cobot
 * @version 1.0.0
 * @since 2024-09-02
 */
@Schema(title = "资产产品元素扩展")
@Data
@ToString(callSuper = true)
@JsonIgnoreProperties(ignoreUnknown = true)
public class AssetProductMetaDTO implements Serializable {
    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "id")
    private Long id;

    @Schema(name = "assetsNo", title = "资产编号")
    private String assetsNo;

    @ApiModelProperty(value = "detailId")
    private Long detailId;

    @ApiModelProperty(value = "关联属性名称")
    private String metaKey;

    @ApiModelProperty(value = "关联属性内容")
    private String metaValue;

    @ApiModelProperty(value = "优先级")
    private Integer metaPriority;

}

  

package com.cloudoer.dct.core.model.entity.ams;

import com.baomidou.mybatisplus.annotation.TableName;
import com.cloudoer.dct.core.model.entity.BaseEntity;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import java.io.Serializable;

/**
 * @author cobot
 * @version 1.0.0
 * @since 2024-09-02
 */
@Schema(title = "资产产品元素扩展")
@Data
@TableName("t_asset_product_metas")
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class AssetProductMeta extends BaseEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "资产Id")
    private Long assetId;

    @Schema(name = "assetsNo", title = "资产编号")
    private String assetsNo;

    @ApiModelProperty(value = "detailId")
    private Long detailId;

    @ApiModelProperty(value = "关联属性名称")
    private String metaKey;

    @ApiModelProperty(value = "关联属性内容")
    private String metaValue;

    @ApiModelProperty(value = "优先级")
    private Integer metaPriority;
}

  

package com.cloudoer.dct.core.model.query.ams;

import com.cloudoer.dct.core.model.query.BaseQuery;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import java.io.Serializable;

/**
 * @author cobot
 * @version 1.0.0
 * @since 2024-09-02
 */
@Schema(title = "资产产品元素扩展")
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class AssetProductMetaQuery extends BaseQuery implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "detailId")
    private Long detailId;

    @Schema(name = "assetsNo", title = "资产编号")
    private String assetsNo;

    @ApiModelProperty(value = "关联属性名称")
    private String metaKey;

    @ApiModelProperty(value = "关联属性内容")
    private String metaValue;

    @ApiModelProperty(value = "优先级")
    private Integer metaPriority;
}

  

package com.cloudoer.dct.core.model.vo.ams;

import com.cloudoer.dct.core.model.vo.BaseVO;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import java.io.Serializable;

/**
 * @author cobot
 * @version 1.0.0
 * @since 2024-09-02
 */
@Schema(title = "资产产品元素扩展")
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class AssetProductMetaVO extends BaseVO implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "detailId")
    private Long detailId;

    @Schema(name = "assetsNo", title = "资产编号")
    private String assetsNo;

    @ApiModelProperty(value = "关联属性名称")
    private String metaKey;

    @ApiModelProperty(value = "关联属性内容")
    private String metaValue;

    @ApiModelProperty(value = "优先级")
    private Integer metaPriority;

}

  

package com.cloudoer.dct.ams.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cloudoer.dct.ams.service.i.AssetProductMetaService;
import com.cloudoer.dct.core.controller.BaseController;
import com.cloudoer.dct.core.model.Page;
import com.cloudoer.dct.core.model.dto.ams.AssetProductMetaDTO;
import com.cloudoer.dct.core.model.entity.ams.AssetProductMeta;
import com.cloudoer.dct.core.model.query.ams.AssetProductMetaQuery;
import com.cloudoer.dct.core.model.vo.ams.AssetProductMetaVO;
import com.cloudoer.dct.core.support.BeanUtil;
import com.cloudoer.dct.core.support.Condition;
import com.cloudoer.dct.core.support.QueryContext;
import com.cloudoer.framework.core.domain.RO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * @author cobot
 * @version 1.0.0
 * @since 2024-09-02
 */
@RestController
@RequestMapping("/asset/product/metas")
@Slf4j
@Tag(name = "资产产品元素扩展",description = "资产产品元素扩展管理")
public class AssetProductMetaController extends BaseController<AssetProductMeta> {

    @Autowired
    private AssetProductMetaService assetProductMetaService;

    @Operation(summary = "资产产品元素扩展查询", description = "根据筛选条件分页查询,以及按照指定字段进行排序")
    @ApiResponses({
        @ApiResponse(responseCode = "100200", description = "成功", content = {@Content(schema = @Schema(implementation = AssetProductMetaVO.class))})
    })
    @GetMapping(name = "查询")
    public Object list(AssetProductMetaQuery assetProductMetaQuery, QueryContext queryContext) {
       QueryWrapper<AssetProductMeta> queryWrapper = Condition.getQueryWrapper(assetProductMetaQuery, queryContext, AssetProductMeta.class);
       Page<AssetProductMetaVO> page = assetProductMetaService.find(Condition.getPage(queryContext), queryWrapper);
       return RO.ok(page);
    }

    @Operation(summary = "资产产品元素扩展详情", description = "根据ID获取资产产品元素扩展详细信息")
    @Parameter(name = "id", description = "资产产品元素扩展ID", in = ParameterIn.PATH, schema = @Schema(type = "Long"), required = true)
    @ApiResponses({
        @ApiResponse(responseCode = "100200", description = "成功", content = {@Content(schema = @Schema(implementation = AssetProductMetaVO.class))})
    })
    @GetMapping(value = "/{id}", name = "详情")
    public Object view(@PathVariable("id") Long id) {
        log.info("get AssetProductMeta Id:{}", id);
        AssetProductMetaVO assetProductMetaVO = assetProductMetaService.find(id);
        return RO.ok(assetProductMetaVO);
    }

    @Operation(summary = "创建资产产品元素扩展", description = "创建资产产品元素扩展信息")
    @ApiResponses({
        @ApiResponse(responseCode = "100200", description = "成功", content = {@Content(schema = @Schema(implementation = AssetProductMeta.class))})
    })
    @PostMapping(name = "创建")
    public Object create(@RequestBody AssetProductMetaDTO assetProductMetaDTO, ServerHttpRequest request) {
        log.info("add AssetProductMeta DTO:{}", assetProductMetaDTO);
        AssetProductMeta assetProductMeta = new AssetProductMeta();
        BeanUtil.copyProperties(assetProductMetaDTO, assetProductMeta);
        this.packAddBaseProps(assetProductMeta, request);
        boolean flag = assetProductMetaService.save(assetProductMeta);
        return RO.status(flag, assetProductMeta);
    }

    @Operation(summary = "复制资产产品元素扩展", description = "根据ID复制资产产品元素扩展")
    @Parameter(name = "id", description = "资产产品元素扩展ID", in = ParameterIn.PATH, schema = @Schema(type = "Long"), required = true)
    @ApiResponses({
        @ApiResponse(responseCode = "100200", description = "成功", content = {@Content(schema = @Schema(implementation = AssetProductMeta.class))})
    })
    @PostMapping(value = "/{id}", name = "复制")
    public Object copy(@PathVariable("id") Long id, ServerHttpRequest request) {
        AssetProductMeta assetProductMeta = assetProductMetaService.getById(id);
        if (assetProductMeta == null) {
            return RO.fail("不存在的id");
        }
        assetProductMeta.setId(null);
        //assetProductMeta.setName(assetProductMeta.getName() + "_副本");
        this.packAddBaseProps(assetProductMeta, request);
        boolean flag = assetProductMetaService.save(assetProductMeta);
        return RO.status(flag, assetProductMeta);
    }

    @Operation(summary = "修改资产产品元素扩展", description = "根据ID, 修改资产产品元素扩展信息")
    @Parameter(name = "id", description = "资产产品元素扩展ID", in = ParameterIn.PATH, schema = @Schema(type = "Long"), required = true)
    @ApiResponses({
        @ApiResponse(responseCode = "100200", description = "成功", content = {@Content(schema = @Schema(implementation = AssetProductMeta.class))})
    })
    @PutMapping(value = "/{id}", name = "修改")
    public Object update(@PathVariable("id") Long id, @RequestBody AssetProductMetaDTO assetProductMetaDTO, ServerHttpRequest request) {
        log.info("put modify id:{}, AssetProductMeta DTO:{}", id, assetProductMetaDTO);
        AssetProductMeta assetProductMeta = assetProductMetaService.getById(id);
        if (null == assetProductMeta){
            return RO.fail("不存在的id");
        }
        BeanUtil.copyProperties(assetProductMetaDTO, assetProductMeta);
        this.packModifyBaseProps(assetProductMeta, request);
        boolean flag = assetProductMetaService.updateById(assetProductMeta);
        return RO.status(flag, assetProductMeta);
    }

    @Operation(summary = "删除资产产品元素扩展", description = "根据ID, 删除资产产品元素扩展信息")
    @Parameter(name = "id", description = "资产产品元素扩展ID", in = ParameterIn.PATH, schema = @Schema(type = "Long"), required = true)
    @ApiResponses({
        @ApiResponse(responseCode = "100200", description = "成功")
    })
    @DeleteMapping(value = "/{id}", name = "删除")
    public Object remove(@PathVariable("id") Long id, ServerHttpRequest request) {
        log.info("delete AssetProductMeta, id:{}", id);
        AssetProductMeta assetProductMeta = new AssetProductMeta();
        assetProductMeta.setId(id);
        this.packModifyBaseProps(assetProductMeta, request);
        boolean flag = assetProductMetaService.delete(assetProductMeta);
        return RO.status(flag);
    }

    @Operation(summary = "批量删除资产产品元素扩展", description = "根据ID集合, 批量删除资产产品元素扩展信息")
    @Parameter(name = "ids", description = "资产产品元素扩展ID集合", in = ParameterIn.DEFAULT, schema = @Schema(type = "List"), required = true)
    @ApiResponses({
        @ApiResponse(responseCode = "100200", description = "成功")
    })
    @DeleteMapping(name = "批量删除")
    public Object remove(@RequestBody Map<String, Object> params, ServerHttpRequest request) {
        boolean flag = false;
        if(params.get("ids") != null){
            List<String> ids = (List<String>) params.get("ids");
            if (CollectionUtils.isNotEmpty(ids)) {
                flag = assetProductMetaService.delete(ids, getUserId(request));
            }
        }
        return RO.status(flag);
    }

}

  

package com.cloudoer.dct.ams.mapstruts;

import com.cloudoer.dct.core.model.dto.ams.AssetProductMetaDTO;
import com.cloudoer.dct.core.model.entity.ams.AssetProductMeta;
import com.cloudoer.dct.core.model.vo.ams.AssetProductMetaVO;
import org.mapstruct.InjectionStrategy;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;

import java.util.List;

@Mapper(componentModel = "spring", injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public interface AssetProductMetaMapStruct {

    @Mappings({})
    AssetProductMeta convert(AssetProductMetaDTO dto);

    List<AssetProductMeta> convert(List<AssetProductMetaDTO> dto);

    @Mappings({})
    AssetProductMetaDTO voConvert(AssetProductMetaVO vo);

    List<AssetProductMetaDTO> voConvert(List<AssetProductMetaVO> dto);

    AssetProductMeta listConvert(AssetProductMeta meta);

}

  

package com.cloudoer.dct.ams.service.i;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cloudoer.dct.core.constant.Constant;
import com.cloudoer.dct.core.model.Page;
import com.cloudoer.dct.core.model.entity.ams.AssetProductMeta;
import com.cloudoer.dct.core.model.vo.BaseVO;
import com.cloudoer.dct.core.model.vo.ams.AssetProductMetaVO;
import com.cloudoer.dct.core.support.BeanUtil;
import com.cloudoer.dct.core.support.Condition;
import com.cloudoer.framework.core.domain.SortingContext;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author cobot
 * @version 1.0.0
 * @since 2024-09-02
 */
public interface AssetProductMetaService extends IService<AssetProductMeta> {

    /**
     * 根据id查询一条资产产品元素扩展。
     *
     * @param id 数据唯一id。
     * @return 查询到的资产产品元素扩展数据。
     */
    default AssetProductMetaVO find(Long id){
        if(id == null){
            return null;
        }
        AssetProductMeta assetProductMeta = this.getById(id);
        if (null != assetProductMeta) {
            return BeanUtil.copyProperties(assetProductMeta, new AssetProductMetaVO());
        }
        return null;
    }

    /**
     * 根据id集合查询多条资产产品元素扩展。
     *
     * @param ids id集合
     * @return 查询到的资产产品元素扩展数据。
     */
    default List<AssetProductMetaVO> find(Collection<? extends Serializable> ids){
        if (CollectionUtils.isEmpty(ids)) {
            return null;
        }
        List<AssetProductMeta> assetProductMetaList = listByIds(ids);
        if (CollectionUtils.isNotEmpty(assetProductMetaList)) {
            List<AssetProductMetaVO> list = new ArrayList<>(assetProductMetaList.size());
            for (AssetProductMeta assetProductMeta : assetProductMetaList) {
            list.add(BeanUtil.copyProperties(assetProductMeta, new AssetProductMetaVO()));
            }
            return list;
        }
        return null;
    }


    /**
    * 根据id集合查询多条题目。
    *
    * @param ids id集合
    * @return 查询到的题目数据。
    */
    default Map<Long, AssetProductMetaVO> findMap(Collection<? extends Serializable> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return new HashMap<>();
        }
        List<AssetProductMetaVO> list = find(ids);
        if (CollectionUtils.isNotEmpty(list)) {
            Map<Long, AssetProductMetaVO> map = new LinkedHashMap<>(list.size());
            for (AssetProductMetaVO assetProductMetaVO : list) {
                map.put(assetProductMetaVO.getId(), assetProductMetaVO);
            }
            return map;
        }
        return new HashMap<>(0);
    }

    /**
    * 根据id集合查询多条题目。
    *
    * @param ids id集合
    * @return 查询到的题目数据。
    */
    default Map<Long, AssetProductMetaVO> findMap(String fieldName, Collection<? extends Serializable> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return new HashMap<>(0);
        }
        QueryWrapper<AssetProductMeta> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", ids);
        return findMap(fieldName, ids);
    }

    /**
     * 根据查询条件得到数据列表
     *
     * @param queryWrapper 查询条件。
     * @return 查询结果的数据集合。
     */
    default List<AssetProductMetaVO> find(QueryWrapper<AssetProductMeta> queryWrapper) {
        List<AssetProductMetaVO> records = null;
        List<AssetProductMeta> list = list(queryWrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            records = new ArrayList<>(list.size());
            for (AssetProductMeta assetProductMeta : list) {
                records.add(BeanUtil.copyProperties(assetProductMeta, new AssetProductMetaVO()));
            }
        }
        return records;
    }

    /**
     * 根据查询条件得到数据列表
     *
     * @param queryWrapper 查询条件。
     * @return 查询结果的数据集合。
     */
    default Map<Long, AssetProductMetaVO> findMap(QueryWrapper<AssetProductMeta> queryWrapper) {
        List<AssetProductMetaVO> list = find(queryWrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            Map<Long, AssetProductMetaVO> map = new LinkedHashMap<>(list.size());
            for (AssetProductMetaVO assetProductMetaVO : list) {
                map.put(assetProductMetaVO.getId(), assetProductMetaVO);
            }
            return map;
        }
        return new HashMap<>(0);
    }

    /**
     * 根据查询指定字段
     *
     * @param fieldName    属性名称
     * @param queryWrapper 查询条件
     * @return 查询结果的数据集合
     */
    default Map<Long, String> findMap(String fieldName, QueryWrapper<AssetProductMeta> queryWrapper) {
        queryWrapper.select("id", fieldName);
        List<Map<String, Object>> list = listMaps(queryWrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            Map<Long, String> map = new LinkedHashMap<>(list.size());
            for (Map<String, Object> data : list) {
                Object key = data.get("id");
                if (key != null && StringUtils.isNotBlank(key.toString())) {
                    String val = "";
                    if (data.get(fieldName) != null) {
                        val = data.get(fieldName).toString();
                    }
                    map.put(Long.valueOf(key.toString()), val);
                }
            }
            return map;
        }
        return new HashMap<>(0);
    }

    /**
     * 根据查询条件得到数据列表,包含分页和排序信息。
     *
     * @param queryWrapper 查询条件。
     * @param page 分页排序信息。
     * @return 查询结果的数据集合。
     */
    default Page<AssetProductMetaVO> find(IPage<AssetProductMeta> page, QueryWrapper<AssetProductMeta> queryWrapper){
        IPage<AssetProductMeta> ipage = this.page(page, queryWrapper);
        Page<AssetProductMetaVO> dataPage = new Page(ipage.getTotal(), ipage.getCurrent(), ipage.getSize());
        List<AssetProductMeta> assetProductMetaList = ipage.getRecords();
        if (CollectionUtils.isNotEmpty(assetProductMetaList)) {
            List<AssetProductMetaVO> records = new ArrayList<>(assetProductMetaList.size());
            for (AssetProductMeta assetProductMeta : assetProductMetaList) {
                records.add(BeanUtil.copyProperties(assetProductMeta, new AssetProductMetaVO()));
            }
            dataPage.setRecords(records);
        }
        List<OrderItem> orders = ipage.orders();
        if (CollectionUtils.isNotEmpty(orders)) {
            Map<String, String> scs = new LinkedHashMap<>(orders.size());
            for (OrderItem orderItem : orders) {
                scs.put(orderItem.getColumn(), orderItem.isAsc() ? SortingContext.ASC.toLowerCase() : SortingContext.DESC.toLowerCase());
            }
            dataPage.setScs(scs);
        }
        return dataPage;
    }

    /**
     * 根据查询条件得到数据列表
     *
     * @param groupName    属性名称
     * @param queryWrapper 查询条件
     * @return 查询结果的数据集合
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    default Map<String, List<AssetProductMetaVO>> findGroupMap(String groupName, QueryWrapper<AssetProductMeta> queryWrapper) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        List<AssetProductMetaVO> list = find(queryWrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            String methodName = "get".concat(groupName.substring(0, 1).toUpperCase()).concat(groupName.substring(1));
            Method method = AssetProductMetaVO.class.getMethod(methodName);
            Map<String, List<AssetProductMetaVO>> map = new LinkedHashMap<>(list.size());
            for (AssetProductMetaVO assetProductMetaVO : list) {
                Object key = method.invoke(assetProductMetaVO);
                if (key != null && StringUtils.isNotBlank(key.toString())) {
                    if (!map.containsKey(key.toString())) {
                        map.put(key.toString(), new ArrayList<>());
                    }
                    map.get(key.toString()).add(assetProductMetaVO);
                }
            }
            return map;
        }
        return new HashMap<>(0);
    }

        /**
         * @param params
         */
        default List<Map<String, Object>> udd(Map<String, Object> params) {
            List<Map<String, Object>> dataList = new ArrayList<>();
            QueryWrapper<AssetProductMeta> queryWrapper = Condition.getQueryWrapper(params,  AssetProductMeta.class);
            queryWrapper.select("id", "name");
            queryWrapper.orderByDesc("priority");
            queryWrapper.orderByDesc("id");
            List<AssetProductMeta> list = list(queryWrapper);
            if (CollectionUtils.isEmpty(list)) {
                return dataList;
            }
            for (AssetProductMeta obj : list) {
                Map<String, Object> dmap = new HashMap<>();
                dmap.put("key", obj.getId());
                //dmap.put("val", obj.getName());
                dataList.add(dmap);
            }
            return dataList;
        }

    /**
     * 修改某个字段的值
     *
     * @param id
     * @param key
     * @param value
     * @param userId
     * @return
     */
    default boolean update(Long id, String key, Object value, Long userId) {
        if (id != null && StringUtils.isNotBlank(key) && !Constant.DONT_UPDATE_COLUMNS.contains(key.toLowerCase()) && userId != null) {
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.set(key, value);
            updateWrapper.set("modified_by", userId);
            updateWrapper.set("modified_date", System.currentTimeMillis());
            updateWrapper.eq("id", id);
            return update(updateWrapper);
        }
        return false;
    }

    /**
     * 修改某个字段的值
     *
     * @param ids
     * @param key
     * @param value
     * @param userId
     * @return
     */
    default boolean update(Collection<? extends Serializable> ids, String key, Object value, Long userId) {
        if (CollectionUtils.isNotEmpty(ids) && StringUtils.isNotBlank(key) && !Constant.DONT_UPDATE_COLUMNS.contains(key.toLowerCase()) && userId != null) {
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.set(key, value);
            updateWrapper.set("modified_by", userId);
            updateWrapper.set("modified_date", System.currentTimeMillis());
            updateWrapper.in("id", ids);
            return update(updateWrapper);
        }
        return false;
    }

    /**
     * 修改多个字段的值
     *
     * @param id
     * @param data
     * @param userId
     * @return
     */
    default boolean update(Long id, Map<String, Object> data, Long userId) {
        if (id != null && MapUtils.isNotEmpty(data) && userId != null) {
            boolean update = false;
            UpdateWrapper updateWrapper = new UpdateWrapper();
                for (Map.Entry<String, Object> entry : data.entrySet()) {
                if (!Constant.DONT_UPDATE_COLUMNS.contains(entry.getKey().toLowerCase())) {
                    update = true;
                    updateWrapper.set(entry.getKey(), entry.getValue());
                }
            }
            if (update) {
                updateWrapper.set("modified_by", userId);
                updateWrapper.set("modified_date", System.currentTimeMillis());
                updateWrapper.eq("id", id);
                return update(updateWrapper);
            }
        }
        return false;
    }

    /**
     * 修改多个字段的值
     *
     * @param ids
     * @param data
     * @param userId
     * @return
     */
    default boolean update(Collection<? extends Serializable> ids, Map<String, Object> data, Long userId) {
        if (CollectionUtils.isNotEmpty(ids) && MapUtils.isNotEmpty(data) && userId != null) {
            boolean update = false;
            UpdateWrapper updateWrapper = new UpdateWrapper();
                for (Map.Entry<String, Object> entry : data.entrySet()) {
                if (!Constant.DONT_UPDATE_COLUMNS.contains(entry.getKey().toLowerCase())) {
                    update = true;
                    updateWrapper.set(entry.getKey(), entry.getValue());
                }
            }
            if (update) {
                updateWrapper.set("modified_by", userId);
                updateWrapper.set("modified_date", System.currentTimeMillis());
                updateWrapper.in("id", ids);
                return update(updateWrapper);
            }
        }
        return false;
    }

    /**
     * 逻辑删除
     *
     * @param assetProductMeta
     * @return
     */
    default boolean delete(AssetProductMeta assetProductMeta) {
        if(assetProductMeta != null && assetProductMeta.getId() != null && assetProductMeta.getModifiedBy() != null){
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.set("status", 0);
            updateWrapper.set("modified_by", assetProductMeta.getModifiedBy());
            updateWrapper.set("modified_date", assetProductMeta.getModifiedDate());
            updateWrapper.eq("id", assetProductMeta.getId());
            return update(updateWrapper);
        }
        return false;
    }

    /**
     * 逻辑删除
     *
     * @param id
     * @param userId
     * @return
     */
    default boolean delete(Long id, Long userId) {
        if(id != null && userId != null){
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.set("status", 0);
            updateWrapper.set("modified_by", userId);
            updateWrapper.set("modified_date", System.currentTimeMillis());
            updateWrapper.eq("id", id);
            return update(updateWrapper);
        }
        return false;
    }

    /**
     * 逻辑删除
     *
     * @param ids
     * @param userId
     * @return
     */
    default boolean delete(Collection<? extends Serializable> ids, Long userId) {
        boolean flag = false;
        if(CollectionUtils.isNotEmpty(ids) && userId != null){
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.set("status", 0);
            updateWrapper.set("modified_by", userId);
            updateWrapper.set("modified_date", System.currentTimeMillis());
            updateWrapper.in("id", ids);
            return update(updateWrapper);
        }
        return false;
    }

        /**
         * @param list
         * @param field
         * @param targetField
         * @throws InvocationTargetException
         * @throws IllegalAccessException
         */
        default void inflate(Collection<? extends BaseVO> list, String field, String targetField) throws InvocationTargetException, IllegalAccessException {
            List objectIds = BeanUtil.getObjectIds(list, field);
            if (CollectionUtils.isEmpty(objectIds)) {
                return;
            }
            QueryWrapper<AssetProductMeta> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("id", "name");
            queryWrapper.in("id", objectIds);
            List<AssetProductMeta> dataList = list(queryWrapper);
            if (CollectionUtils.isEmpty(dataList)) {
                return;
            }
            Map<String, AssetProductMeta> dataMap = dataList.stream().collect(Collectors.toMap(item -> item.getId().toString(), obj -> obj));
            String getMethodName = "get".concat(field.substring(0, 1).toUpperCase()).concat(field.substring(1));
            String setMethodName = "set".concat(targetField.substring(0, 1).toUpperCase()).concat(targetField.substring(1));
            for (BaseVO vo : list) {
                Method getMethod = BeanUtil.getObjectMethodByName(vo, getMethodName);
                if (getMethod == null) {
                    continue;
                }
                Object orgId = getMethod.invoke(vo);
                if (orgId == null) {
                    continue;
                }
                AssetProductMeta obj = dataMap.getOrDefault(orgId.toString(), null);
                if (obj == null) {
                    continue;
                }
                Method setMethod = BeanUtil.getObjectMethodByName(vo, setMethodName, String.class);
                if (setMethod != null) {
                    //setMethod.invoke(vo, obj.getName());
                } else {
                    //vo.addAttribute(targetField, obj.getName());
                }
            }

        }

        /**
         * @param vo
         * @param field
         * @param targetField
         */
        default void inflate(BaseVO vo, String field, String targetField) throws InvocationTargetException, IllegalAccessException {
            Object objectId = BeanUtil.getObjectId(vo, field);
            if (objectId == null) {
                return;
            }
            QueryWrapper<AssetProductMeta> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("id", "name");
            queryWrapper.eq("id", objectId);
            AssetProductMeta obj = getOne(queryWrapper);
            if (obj == null) {
                return;
            }
            String setMethodName = "set".concat(targetField.substring(0, 1).toUpperCase()).concat(targetField.substring(1));
            Method setMethod = BeanUtil.getObjectMethodByName(vo, setMethodName, String.class);
            if (setMethod != null) {
                //setMethod.invoke(vo, obj.getName());
            } else {
                //vo.addAttribute(targetField, obj.getName());
            }
        }
}

  

VUE部分:

 配置表单

<template>
  <!--  数据字典-->
  <!--  margin:'0 -12px'-->
  <div :style="{height: height + 'px',overflow:'hidden'}">
    <Split v-model="split" class="icb-split-left-240">
      <template #left>
        <div class="icb-split-left">
          <Card dis-hover :bordered="false" class="udd-tree-card">
            <p slot="title">
              <Icon type="ios-list" size="24" color="black" style="margin-left: -3px"></Icon>
              <span style="vertical-align: text-bottom">资产分类目录</span>
            </p>
            <Tree :data="treeData" @on-select-change="treeChange"
                  :style="{height: treeHeight + 'px',overflow:'auto',}"></Tree>
          </Card>
        </div>
      </template>
      <template #right>
        <Card dis-hover :bordered="false" :padding="0">
          <p slot="title">
            <Dropdown class="icb-dropdown" trigger="click">
              <Icon type="md-more"/>
              <DropdownMenu slot="list">
                <DropdownItem v-if="$checkAuth('-assetScrap-create')" @click.native="edit(null)">
                  <span class="iconx iconx-add-circle-outlined"></span>
                  <span>新建</span>
                </DropdownItem>
                <DropdownItem v-if="$checkAuth('-assetScrap-removeBatch')" @click.native="removeBatch">
                  <span class="iconx iconx-delete-outlined"></span>
                  <span>删除</span>
                </DropdownItem>
              </DropdownMenu>
            </Dropdown>
          </p>
          <Table
              :columns="tableColumns"
              :data="data"
              :loading="loading"
              :size="tableSize"
              :height="tableHeight"
              @on-sort-change="sort"
              :no-data-text="$gdata.tableNoDataText"
              @on-selection-change="tableSelectHandler">
            <template slot-scope="{ row }" slot="name">
              <a @click="showInfo(row)">{{ row.name }}</a>
            </template>
            <template slot-scope="{ row }" slot="action">
              <div class="icb-list-action">
            <span class="iconx iconx-edit-outlined" v-if="$checkAuth('-assetProductDefinition-update')"
                  @click="edit(row)"></span>
                <span class="icb-action-divider"></span>
                <Dropdown class="icb-dropdown" trigger="click" style="margin-left: 0;">
                  <a href="javascript:void(0)" class="icb-list-more">
                    <span class="iconx iconx-more-outlined"></span>
                  </a>
                  <DropdownMenu slot="list">
                    <DropdownItem @click.native="attach(row)">
                      <span class="iconx iconx-link-outlind"></span>
                      <span>附件</span>
                    </DropdownItem>
                    <DropdownItem @click.native="remove(row)" v-if="$checkAuth('-assetProductDefinition-remove')">
                      <span class="iconx iconx-delete-outlined"></span>
                      <span class="table-action">删除</span>
                    </DropdownItem>
                  </DropdownMenu>
                </Dropdown>
              </div>
            </template>
          </Table>
          <div class="ivu-text-right ivu-mt-8">
            <Page :total="pc.total" :current="pc.pageIndex" :page-size="pc.pageSize"
                  :page-size-opts="pageSizeOpts" :disabled="pageDisabled"
                  @on-change="changePage" @on-page-size-change="changePageSize"
                  show-total show-sizer transfer style="margin-left: auto"></Page>
          </div>
        </Card>
      </template>
    </Split>
    <Drawer :title="editorTitle" v-model="editorVisible" :mask-closable="false" :closable="true" width="750"
            class-name="icb-popup">
      <assetProductDefinitionEditor ref="assetProductDefinitionEditor" @on-success="editSuccessHandler"
                                    @on-close="closeHandle"/>
    </Drawer>
    <Drawer :title="infoTitle" v-model="infoVisible" width="750" class-name="icb-popup">
      <assetProductDefinitionInfo ref="assetProductDefinitionInfo"/>
    </Drawer>
    <Attachment ref="attachment"/>
  </div>
</template>
<script>
  import assetProductDefinitionEditor from './editor'
  import assetProductDefinitionInfo from './view'
  import dropdownCommon from '_c/dropdown/dropdown-common';
  import PriorityPoptip from '_c/priority-poptip/priority-poptip';
  import {
    getAssetProductDefinitionList,
    removeAssetProductDefinition,
    removeAssetProductDefinitionBatch,
    updateAssetProductDefinition,
  } from '@api/ams/assetProductDefinition'
  import { getTreeList } from '@api/ams/assetCategory'
  import $ from 'jquery'
  import config from '../config.json'
  import { getUddList } from '@/api/generic/udd';

  export default {
    name: 'udd-list',
    components: {
      assetProductDefinitionEditor,
      assetProductDefinitionInfo,
      dropdownCommon,
      PriorityPoptip
    },
    data () {
      return {
        udds: [],
        dataTypeDatas: [],
        infoTitle: '',
        infoVisible: false,
        ids: null,
        loading: false,
        drawer_styles: {
          height: 'calc(100% - 55px)',
          overflow: 'auto',
          paddingBottom: '53px',
          position: 'static',
          width: '920'
        },
        split: '320px',
        height: 0,
        data: [],
        editorTitle: '',
        editorVisible: false,
        treeData: [
          {
            code: '',
            title: '资产分类',
            expand: true,
            selected: true,
            children: []
          }
        ],
        parent: '/',
        pc: {
          pageIndex: 1,
          pageSize: 20,
          total: 0
        },
        pageDisabled: false,
        scs: [
          {
            priority: 'desc'
          },
          {
            created_date: 'desc'
          }
        ],
        columns: [
          {
            type: 'selection',
            show: true,
            width: 60,
            align: 'center'
          },
          {
            type: 'index',
            show: true,
            width: 60,
            align: 'right'
          },
          {
            title: '名称',
            key: 'name',
            show: true,
            tooltip: true,
            maxWidth: 350,
            slot: 'name',
            className: 'sort-col sort-name-col'
          },
          {
            title: '显示名称',
            key: 'label',
            show: true,
            tooltip: true,
            maxWidth: 350,
            className: 'sort-col sort-label-col'
          },
          {
            title: '属性类型',
            key: 'dataType',
            show: true,
            tooltip: true,
            maxWidth: 350,
            className: 'sort-col sort-dataType-col',
            render: (h, params) => {
              console.log('params.row.dctCode=====',params.row.dataType,this.dataTypeDatas)
              return h('span', config.dataTypeItems.filter(item => item.value === params.row.dataType)[0].label || '未知');
            }
          },
          {
            title: '表单类型',
            key: 'uiType',
            show: true,
            tooltip: true,
            maxWidth: 350,
            className: 'sort-col sort-uiType-col',
            render: (h, params) => {
              return h('span', config.metaTypes.filter(item => item.value === params.row.uiType)[0].label || '未知');
            }
          },
          {
            title: '长度',
            key: 'length',
            align: 'center',
            render: (h, params) => {
              return h('span', params.row.length);
            }
          },
          {
            title: '默认值',
            key: 'defaultValues',
            show: true,
            tooltip: true,
            maxWidth: 350,
            className: 'sort-col sort-defaultValues-col'
          },
          {
            title: '是否必填',
            key: 'required',
            show: true,
            tooltip: true,
            maxWidth: 350,
            className: 'sort-col sort-required-col'
          },
          {
            title: '数据字典',
            key: 'dctCode',
            show: true,
            tooltip: true,
            maxWidth: 350,
            className: 'sort-col sort-dctCode-col',
            render: (h, params) => {

              return h('span', this.udds.filter(item => item.code === params.row.dctCode)[0].name || '未知');
            }
          },
          {
            title: '提示信息',
            key: 'placeholder',
            show: true,
            tooltip: true,
            maxWidth: 350,
            className: 'sort-col sort-placeholder-col'
          },
          {
            title: '优先级',
            key: 'priority',
            show: true,
            tooltip: true,
            maxWidth: 350,
            className: 'sort-col sort-priority-col',
            render: (h, params) => {
              return h('div', {}, [
                h(PriorityPoptip, {
                  props: {
                    id: params.row.id,
                    priorityold: params.row.priority,
                    prioritynew: params.row.priority
                  },
                  on: {
                    priorityUpdated: (prioritynew, id) => {
                      this.savePriority(prioritynew, id);
                    }
                  }
                })
              ]);
            }
          },
          {
            title: '操作',
            key: 'action',
            show: true,
            align: 'center',
            slot: 'action',
            width: 100
          }
        ],
        dropitems: [
          {
            icon: '',
            action: 'udd_update',
            title: '修改',
            name: 'editor'
          },
          {
            icon: '',
            action: 'udd_del',
            title: '删除',
            name: 'del'
          }
        ],
        pageRefresh: true,
        pageSizeOpts: [10, 20, 50, 100],
        tableHeight: 0,
        treeHeight: 0,
        tableSize: 'default'
      }
    },
    watch: {
      'pc.pageIndex': function (curVal, oldVal) {
        if (curVal !== oldVal) {
          if (!this.pageRefresh) {
            return
          }
          this.load()
        }
      },
      'pc.pageSize': function (curVal, oldVal) {
        if (curVal !== oldVal) {
          if (!this.pageRefresh) {
            return
          }
          this.load()
        }
      },
      facets: {
        handler (newValue, oldValue) {
          this.load()
        },
        deep: true
      },
      $route: {
        handler () {
          if (this.$route.query.p) {
            if (this.$route.query.p - 0 !== this.pc.pageIndex) {
              this.pc.pageIndex = this.$route.query.p - 0
              this.load()
            }
          } else {
            this.pc.pageIndex = 1
            this.load()
          }
        },
        deep: true
      }
    },
    computed: {
      width () {
        return document.body.clientWidth
      },
      tableColumns () {
        const columns = [...this.columns]
        return columns.filter(item => item.show)
      }
    },
    mounted () {
      const self = this
      self.$nextTick(() => {
        self.autoHeight()
      })
      window.addEventListener('resize', this.autoHeight)
      if (self.$route.query.p) {
        self.pc.pageIndex = this.$route.query.p - 0
      }
      self.load();
      self.treeChange (this.treeData)
    },
    created () {
      this.loadMTIdDatas ();
      this.loadTree();
      this.getUddList ()
      this.load()
    },
    destroyed () {
      window.removeEventListener('resize', this.autoHeight)
    },
    methods: {
      getUddList () {
        const params = {}
        const self = this
        self.udds = []
        getUddList(params).then((res) => {
          console.log(111111,res.data)
          self.udds = res.data.records
        });
      },
      loadMTIdDatas () {
        // todo 此处调用元数据接口 /metatypes
        this.dataTypeDatas  =  [
          {id: '950763959593365504', name: '区域代码'},
          {id: '348648182', name: '文本类型'}
        ];
      },
        refreshSort () {
        this.scs.forEach(function (order, key) {
          let ascEl = $('th.sort-' + key + '-col').find('.ivu-icon-md-arrow-dropup')
          let descEl = $('th.sort-' + key + '-col').find('.ivu-icon-md-arrow-dropdown')
          if (order === 'asc') {
            $(ascEl).addClass('on')
            $(descEl).removeClass('on')
          } else if (order === 'desc') {
            $(ascEl).removeClass('on')
            $(descEl).addClass('on')
          } else {
            $(ascEl).removeClass('on')
            $(descEl).removeClass('on')
          }
        })
      },
      tableSelectHandler (selection) {
        const self = this
        self.ids = []
        if (selection != null && selection.length > 0) {
          selection.forEach(function (item) {
            self.ids.push(item.id)
          })
        }
      },
      buildParams () {
        const self = this
        let params = {
          p: this.pc.pageIndex,
          s: this.pc.pageSize
        }
        params.productId = self.parent;
        let scs = []
        this.scs.forEach(function (order, key) {
          scs.push(key + '(' + order + ')')
        })
        if ((this.scs == null || this.scs.size == 0) && this.defaultScs != null && Object.keys(this.defaultScs).length > 0) {
          Object.keys(this.defaultScs).forEach(function (key) {
            scs.push(key + '(' + self.defaultScs[key] + ')')
          })
        }
        Object.assign(params, this.filters, this.facets, { scs: scs.join(',') })
        return params
      },
      loadTree () {
        getTreeList({ scs: 'name(asc)' }).then((res) => {
          this.treeData[0].children = res.data;
        });
      },
      sort (sc) {
        let key = sc.key
        let order = sc.order
        if (key == null || key == undefined) {
          key = sc.column.slot
        }
        if (this.scs.has(key) && this.scs.get(key) === 'asc') {
          order = 'desc'
        }
        if (key != null && key != undefined && key != '') {
          if (sc.order !== 'normal') {
            this.scs.set(key, order)
          } else {
            this.scs.delete(key)
          }
          this.load()
        }
      },
      load () {
        const self = this
        getAssetProductDefinitionList(self.buildParams()).then((res) => {
          self.loading = false
          self.data = res.data.records
          if (res.data.records.length > 0) {
            self.pc.pageIndex = parseInt(res.data.pageIndex)
            self.pc.total = parseInt(res.data.total)
          } else {
            self.pc = {
              pageIndex: 1,
              pageSize: self.pc.pageSize,
              total: 0
            }
          }
          self.refreshSort()
          setTimeout(function () {
            self.pageRefresh = true
            self.pageDisabled = false
          }, 500)
        })
      },
      treeChange (data) {
        this.parent = data[0].code;

        this.load();
      },
      savePriority (prioritynew,id) {
        updateAssetProductDefinition({
          id: id,
          priority: prioritynew
        }).then((res) => {
          if (res.code === 100200) {
            this.$Message.success('修改成功!')
            this.load()
          }
        })
      },
      dropdown (tdata) {
        switch (tdata.name) {
          case 'editor':
            this.edit(tdata.data.code)
            break
          case 'del':
            this.del(tdata.data)
            break
        }
      },
      edit (data) {
        let id = 0
        if (data != null) {
          id = data.id
        }
        this.editorTitle = (id === 0 ? '新建' : '编辑') + '类型'
        this.editorVisible = true
        this.$refs.assetProductDefinitionEditor.load(id, this.parent)
      },
      editSuccessHandler (data, type) {
        this.editorVisible = false
        this.load()
        this.loadTree()
      },
      closeHandle () {
        this.editorVisible = false
      },
      del (data) {
        const params = {
          id: data.id
        }
        this.$Modal.confirm({
          content: '<p>确定删除吗?</p>',
          onOk: () => {
            removeAssetProductDefinition(params).then((res) => {
              if (res.code === 100200) {
                this.$Message.success('删除成功!')
                this.load()
              }
              this.loadTree()
            })
          },
          onCancel: () => {
          }
        })
      },
      removeBatch () {
        if (this.ids.length > 0) {
          let params = {
            ids: this.ids
          }
          this.$Modal.confirm({
            title: '提示',
            content: '<p>确定要删除选择的数据?</p>',
            cancelText: '取消',
            okText: '确定',
            onOk: () => {
              removeAssetProductDefinitionBatch(params).then((res) => {
                if (res.code === 100200) {
                  this.$Message.success('操作成功!')
                  this.load()
                } else {
                  this.$Message.error(res.message)
                }
              })
            },
            onCancel: () => {

            }
          })
        } else {
          this.$Message.error('请选择要删除的数据!')
        }
      },
      autoHeight () {
        // 42是顶部导航栏高度 32是tab栏高度 headerHeight是列表页顶部高度 12是外层边距,50是底部分页信息栏, 所有被减高度之和为206
        this.height = document.body.clientHeight - 84
        this.treeHeight = this.height - 98
      },
      changePage (page) {
        this.pc.pageIndex = parseInt(page)
      },
      changePageSize (num) {
        this.pc.pageSize = parseInt(num)
      },
      handleChangeTableSize (size) {
        this.tableSize = size
      }
    }
  }
</script>
<style lang="less" scoped>
::v-deep .ivu-table th {
  background: #fff !important;
}

::v-deep .ivu-card-head {
  border-bottom: 0;
}

.icb-split-left {

  ::v-deep .ivu-card-head {
    border-bottom: 1px solid #e8eaec;;
  }

}
</style>

  

<template>
  <div>
    <Form ref="assetProductDefinitionForm" :model="assetProductDefinition" :rules="ruleValidate"
          :label-width="labelWidth" :label-position="labelPosition">
      <Row>
        <Col span="12">
          <Form-item label="名称" prop="name">
            <Input v-model="assetProductDefinition.name" placeholder="名称"></Input>
          </Form-item>
        </Col>
        <Col span="12">
          <Form-item label="显示名称" prop="label">
            <Input v-model="assetProductDefinition.label" placeholder="显示名称"></Input>
          </Form-item>
        </Col>
      </Row>

      <Row>
        <Col span="12">
          <Form-item label="属性类型" prop="dataType">
            <Select v-model="assetProductDefinition.dataType" style="width:100%">
              <Option v-for="item in config.dataTypeItems" :key="item.value" :value="item.value" :label="item.label"></Option>
            </Select>
          </Form-item>
        </Col>
        <Col span="12">
          <Form-item label="表单类型" prop="uiType">
            <Select v-model="assetProductDefinition.uiType" style="width: 200px">
              <Option v-for="item in config.metaTypes" :key="item.value" :value="item.value" :label="item.label"></Option>
            </Select>
          </Form-item>
        </Col>
      </Row>

      <Row>
        <Col span="12">
          <Form-item label="默认值" prop="defaultValues">
            <Input v-model="assetProductDefinition.defaultValues" placeholder="默认值"></Input>
          </Form-item>
        </Col>
        <Col span="12">
          <Form-item label="是否必填" prop="required">
            <Switch v-model="assetProductDefinition.required" :false-value="0" :true-value="1"/>
          </Form-item>
        </Col>
      </Row>

      <Row>
        <Col span="12">
          <Form-item label="提示信息" prop="placeholder">
            <Input v-model="assetProductDefinition.placeholder" placeholder="提示信息"></Input>
          </Form-item>
        </Col>
        <Col span="12">
          <Form-item label="长度" prop="length">
            <InputNumber v-model="assetProductDefinition.length" :max="4096" :min="1" placeholder="长度" ></InputNumber>
          </Form-item>
        </Col>
      </Row>

      <Row>
        <Col span="12">
          <Form-item label="提示信息" prop="dctCode" v-if="assetProductDefinition.dataType === '4'">
            <Select v-model="assetProductDefinition.dctCode" style="width:100%">
              <Option v-for="(item,index) in udds" :key="index" :value="item.code" :label="item.name">
                {{ item.name }}
              </Option>
            </Select>
          </Form-item>
        </Col>
        <Col span="12">
        </Col>
      </Row>

      <Form-item label="备注" prop="remark">
        <tinyEditor class="editor" :value="assetProductDefinition.remark"
                    @input="(res)=> assetProductDefinition.remark = res"></tinyEditor>
      </Form-item>

    </Form>
    <div class="icb-editor-footer">
      <Button @click="cancelHandler">取消</Button>
      <Button type="primary" :loading="loading" @click="save">保存</Button>
    </div>
  </div>
</template>

<script>
  import {
    createAssetProductDefinition,
    getAssetProductDefinition,
    updateAssetProductDefinition
  } from '@api/ams/assetProductDefinition'
  import { mapState } from 'vuex'
  import tinyEditor from '_c/tinymce/index.vue';
  import config from '../config.json'
  import { getUddList } from '@/api/generic/udd';

  export default {
    name: 'asset-product-definition-editor',
    components: { tinyEditor },
    data () {
      return {
        udds: [],
        dataTypeDatas: [],
        config,
        loading: false,
        isNew: false,
        assetProductDefinition: {
          productId: null,
          name: null,
          label: null,
          length: null,
          dataType: null,
          uiType: null,
          defaultValues: null,
          required: null,
          placeholder: null,
          remark: null,
          isLock: 1,
          dctCode: null,
        },
        ruleValidate: {
          name: [
            {
              required: true,
              message: '名称不能为空',
              trigger: 'blur',
            }
          ],
          label: [
            {
              required: true,
              message: '显示名称不能为空',
              trigger: 'blur'
            }
          ],
          dataType: [
            {
              required: true,
              message: '属性类型不能为空',
              trigger: 'blur'
            }
          ],
          uiType: [
            {
              required: true,
              message: '表单类型不能为空',
              trigger: 'blur'
            }
          ],
          defaultValues: [
            {
              required: true,
              message: '默认值不能为空',
              trigger: 'blur'
            }
          ],
          // required: [
          //   {
          //     required: true,
          //     message: '是否必填不能为空',
          //     trigger: 'change',
          //     type: 'number'
          //   }
          // ],
          placeholder: [
            {
              required: true,
              message: '提示信息不能为空',
              trigger: 'blur'
            }
          ],
        }
      }
    },
    created () {

    },
    mounted () {
    },
    beforeDestroy () {
    },
    destroyed () {
    },
    computed: {
      ...mapState('admin/layout', [
        'isMobile'
      ]),
      labelWidth () {
        return this.isMobile ? undefined : 80
      },
      labelPosition () {
        return this.isMobile ? 'top' : 'right'
      }
    },
    watch: {},
    methods: {
      getUddList () {
        const params = {}
        const self = this
        self.udds = []
        getUddList(params).then((res) => {
          console.log(111111,res.data)
          self.udds = res.data.records
        });
      },
      loadMTIdDatas () {
        // todo 此处调用元数据接口 /metatypes
        this.dataTypeDatas = [
          {
            id: '950763959593365504',
            name: '区域代码'
          },
          {
            id: '348648182',
            name: '文本类型'
          },
          {
            id: '444444444444',
            name: '数据字典'
          }
        ];
      },
      load (id, productId) {
        this.loading = false
        this.$refs.assetProductDefinitionForm.resetFields()
        this.isNew = (id === 0)

        if (this.isNew) {
          this.assetProductDefinition = {}
        } else {
          let params = { id }
          getAssetProductDefinition(params).then((res) => {
            let assetProductDefinition = res.data
            this.assetProductDefinition = assetProductDefinition
          })
        }
        this.$set(this.assetProductDefinition, 'productId', productId)
        this.$set(this.assetProductDefinition, 'isLock', 1)
        console.log(this.assetProductDefinition, 9999999999)
        this.getUddList ();
        this.loadMTIdDatas();
      },
      save () {
        console.log(this.$parent, 444444444)
        this.$refs.assetProductDefinitionForm.validate((valid) => {
          // this.loading = true
          if (valid) {
            if (this.isNew) {
              this.create()
            } else {
              this.modify()
            }
          } else {
            this.$Message.error('信息校验失败,请根据页面提示纠正您所填写的信息!')
            this.loading = false
          }
        })
      },
      create () {
        createAssetProductDefinition(this.assetProductDefinition).then((res) => {
          if (res.code === 100200) {
            this.$Message.success('添加成功!')
            this.reset()
            this.$emit('on-success', res.data, 'create')
          } else {
            this.$Message.error('添加失败,请稍后重试!')
          }
          this.loading = false
        })
      },
      modify () {
        this.$Modal.confirm({
          title: '操作提示',
          content: '是否修改该数据?',
          okText: '修改',
          onCancel: () => {
            this.loading = false
          },
          onOk: () => {
            updateAssetProductDefinition(this.assetProductDefinition).then((res) => {
              if (res.code === 100200) {
                this.$Message.success('修改成功!')
                this.$emit('on-success', res.data, 'update')
              } else {
                this.$Message.error('修改失败!')
              }
              this.loading = false
            })
          }
        })
      },
      reset () {
        this.assetProductDefinition = {}
        this.$refs.assetProductDefinitionForm.resetFields()
      },
      cancelHandler () {
        this.$emit('on-close')
      }
    }
  }
</script>

  

<template>
  <div class="icb-list">
    <div class="icb-list-header" ref="cListHeader">
      <div class="icb-search">
        <div class="icb-search-item">
          <Input type="text" class="icb-search-input" v-model="filters.keyword" @on-enter="search" clearable
                 placeholder="根据关键字搜索" style="width: 100%;">
            <Icon type="ios-search" slot="prefix"/>
          </Input>
        </div>
        <div class="icb-search-item">
          <Button type="primary" @click="search" style="margin-right:8px;">查询</Button>
        </div>
      </div>
      <div class="icb-action" style="display: flex">
        <Dropdown class="icb-dropdown" trigger="click">
          <Icon type="md-more"/>
          <DropdownMenu slot="list">
            <DropdownItem v-if="$checkAuth('-assetAcceptance-create')" @click.native="edit(null)">
              <span class="iconx iconx-add-circle-outlined"></span>
              <span>新建</span>
            </DropdownItem>
            <DropdownItem v-if="$checkAuth('-assetAcceptance-removeBatch')" @click.native="removeBatch">
              <span class="iconx iconx-delete-outlined"></span>
              <span>删除</span>
            </DropdownItem>
          </DropdownMenu>
        </Dropdown>
      </div>
    </div>
    <Row style="margin: auto">
      <div>
        <Menu v-if="facets.isSuccess" :active-name="facets.approvalState" :theme="theme" class="hidden-bottom-line"
              mode="horizontal" style="width: 800px">
          <MenuItem v-for="item in assetStates" :key="item.state" :name="item.state === null ? '' : item.state"
                    @click.native="stateChange(item.state)">
            {{ item.name }}({{ item.value }})
          </MenuItem>
        </Menu>
      </div>
    </Row>
    <div class="icb-list-data">
      <Table
          :columns="tableColumns"
          :data="data"
          :loading="loading"
          :size="tableSize"
          :height="tableHeight"
          @on-sort-change="sort"
          :no-data-text="$gdata.tableNoDataText"
          @on-selection-change="tableSelectHandler">
        <template slot-scope="{ row }" slot="attchments">
          <span>{{ row.attchCount }}</span>
          <a style="margin-right: 20px" @click="showAttchments(row)" class="iconx iconx-preview2"></a>
        </template>
        <template slot-scope="{ row }" slot="name">
          <a @click="showInfo(row)">{{ row.name }}</a>
        </template>
        <template slot-scope="{ row }" slot="action">
          <div class="icb-list-action">
            <span class="iconx iconx-edit-outlined" v-if="$checkAuth('-assetAcceptance-update')"
                  @click="edit(row)"></span>
            <span class="icb-action-divider"></span>
            <Dropdown class="icb-dropdown" trigger="click" style="margin-left: 0;">
              <a href="javascript:void(0)" class="icb-list-more">
                <span class="iconx iconx-more-outlined"></span>
              </a>
              <DropdownMenu slot="list">
                <DropdownItem @click.native="attach(row)">
                  <span class="iconx iconx-link-outlind"></span>
                  <span>附件</span>
                </DropdownItem>
                <DropdownItem @click.native="copy(row)" v-if="$checkAuth('-assetAcceptance-copy')">
                  <span class="iconx iconx-copy-outlined"></span>
                  <span>复制</span>
                </DropdownItem>
                <DropdownItem @click.native="remove(row)" v-if="$checkAuth('-assetAcceptance-remove')">
                  <span class="iconx iconx-delete-outlined"></span>
                  <span class="table-action">删除</span>
                </DropdownItem>
              </DropdownMenu>
            </Dropdown>
          </div>
        </template>
      </Table>
      <div class="icb-list-footer" ref="cListFooter">
        <Page :total="pc.total" :current="pc.pageIndex" :page-size="pc.pageSize"
              :page-size-opts="pageSizeOpts" :disabled="pageDisabled"
              @on-change="changePage" @on-page-size-change="changePageSize"
              show-total show-sizer transfer></Page>
      </div>
    </div>
    <Drawer :title="editorTitle" v-model="editorVisible" :mask-closable="false" :closable="true" width="1200"
            class-name="icb-popup">
      <assetAcceptanceEditor ref="assetAcceptanceEditor" @list-event="parentMethod" @on-success="editSuccessHandler" @on-close="closeHandle"/>
    </Drawer>
    <MuseumCoverEditor ref="coverup" @remove="removeHandler" @uploaded="successUploadHandler" @on-close="cancelCoverDialog" :action="url"/>
    <Drawer :title="infoTitle" v-model="infoVisible" width="950" class-name="icb-popup">
      <assetAcceptanceInfo ref="assetAcceptanceInfo"/>
    </Drawer>
    <Drawer title="扩展字段信息" :closable="true"  v-model="metaDataVisible" width="1000" >
      <AccMetaData ref="accMetaData" @getMetas="getMetaDatas"/>
    </Drawer>
    <Cover ref="cover"/>
    <Attachment ref="attachment"/>
    <Modal v-model="checkVisible" :title="appTitle" @on-ok="saveCheck">
      <Form>
        <FormItem label="审核结果">
          <RadioGroup v-model="checkState">
            <Radio :label="1">审核通过</Radio>
            <Radio :label="-1">审核不通过</Radio>
          </RadioGroup>
        </FormItem>
        <FormItem label="审核意见">
          <Input v-model="checkRemark" type="textarea" placeholder="请输入审核意见"></Input>
        </FormItem>
      </Form>
    </Modal>
  </div>

</template>
<script>
  import {
    copyAssetAcceptance,
    getAssetAcceptanceList,
    removeAssetAcceptance,
    removeAssetAcceptanceBatch,
    updateAssetAcceptance,
    getStatesCount,
    approval
  } from '@api/ams/assetAcceptance'
  import assetAcceptanceEditor from './editor'
  import assetAcceptanceInfo from './view'
  import excel from '@/libs/excel'
  import * as moment from 'moment'
  import $ from 'jquery'
  import config from '../config.json'
  import expandRow from './expand'
  import MuseumCoverEditor from '@/components/cover/museumCover.vue'
  import AccMetaData from '../base/accMetaData'
  import { createUpload, removeFile } from '@api/ams/assetAttchments';
  import * as ax from '@/plugins/request'

  export default {
    name: 'asset-acceptance-list',
    components: {
      assetAcceptanceEditor,
      assetAcceptanceInfo,
      MuseumCoverEditor,
      AccMetaData
    },
    data () {
      const self = this
      return {
        url : ax.url + '/ams/asset/attachments',
        theme: 'light',
        assetStates: [],
        config,
        metaDataVisible: false,
        checkVisible: false,
        checkState: 1,
        checkType: 1,
        checkRemark: '',
        appTitle: '审核',
        data: [],
        ids: [],
        infoTitle: '',
        infoVisible: false,
        editorTitle: '',
        editorVisible: false,
        filters: {
          kcs: 'name',
          keyword: ''
        },
        facets: {
          approvalState: '',
          isSuccess: false,
        },
        pc: {
          pageIndex: 1,
          pageSize: 20,
          total: 0
        },
        scs: new Map(),
        defaultScs: {
          'priority': 'desc',
          'id': 'desc'
        },
        columns: [
          {
            type: 'expand',
            width: 50,
            show: true,
            render: (h, params) => {
              return this.$createElement(expandRow, {
                props: {
                  row: params.row
                },
                on: {
                  // 子组件$emit传递方法以及参数
                }
              })
            }
          },
          {
            type: 'selection',
            show: true,
            width: 60,
            align: 'center'
          },
          {
            type: 'index',
            show: true,
            width: 60,
            align: 'right'
          },
          {
            title: '验收编号',
            key: 'accNo',
            show: true,
            tooltip: true,
            maxWidth: 350,
            minWidth: 200,
            className: 'sort-col sort-accNo-col'
          },
          {
            title: '附件图片',
            key: 'attchCount',
            width: 120,
            show: true,
            render: (h, params) => {
              if (params.row.attchCount > 0) {
                return h('a', {
                  class: ['iconx', 'iconx-cover3'],
                  style: {},
                  on: {
                    click: () => {
                      this.showAttchments(params.row)
                    }
                  }
                }, ' ' + params.row.attchCount);
              } else {
                return h('a', {
                  style: {},
                  on: {
                    click: () => {
                      this.showAttchments(params.row)
                    }
                  }
                }, '暂无');
              }
            }
          },
          {
            title: '制单时间',
            key: 'createdDate',
            maxWidth: 350,
            minWidth: 150,
            render: (h, params) => {
              return h('div', {}, moment(params.row.createdDate - 0).format('YYYY-MM-DD HH:mm'))
            }
          },
          {
            title: '验收人',
            key: 'userName',
            show: true,
            tooltip: true,
            maxWidth: 350,
            minWidth: 100,
            className: 'sort-col sort-userName-col'
          },
          {
            title: '验收部门',
            key: 'dptName',
            show: true,
            tooltip: true,
            maxWidth: 350,
            minWidth: 100,
            className: 'sort-col sort-dptName-col'
          },
          {
            title: '购买时间',
            key: 'purchaseDate',
            render: (h, params) => {
              return h('div', {}, moment(params.row.purchaseDate - 0).format('YYYY-MM-DD HH:mm'))
            }
          },
          {
            title: '收据号',
            key: 'invoiceCode',
            show: true,
            tooltip: true,
            maxWidth: 350,
            minWidth: 100,
            className: 'sort-col sort-invoiceCode-col'
          },
          {
            title: '提交审核',
            key: 'submit',
            show: true,
            minWidth: 150,
            className: 'sort-col sort-approvalState-col',
            render: (h, params) => {
              if (params.row.approvalState === 0 ||
                  params.row.approvalState === -1) {
                return h('Button', {
                      props: {
                        type: 'primary',
                        style: { margin: '0 3px 0 3px' }
                      },
                      on: {
                        click: () => {
                          this.toSubmit(params.row)
                        }
                      }
                    }, [
                      h('span', '提交')
                    ]
                )
              } else if (params.row.approvalState === 2) {
                return h('span', {
                  class: 'row1',
                  style: { color: '#ffed3c' }
                }, '请审核该条记录')
              } else if (params.row.approvalState === 1) {
                return h('span', '')
              }
            }
          },
          {
            title: '审核状态',
            key: 'approvalState',
            show: true,
            tooltip: true,
            width: 150,
            filters: [],
            filterMultiple: false,
            filterRemote (value, row) {
              self.facets.approvalState = value.length > 0 ? value[0] : ''
            },
            className: 'sort-col sort-approvalState-col',
            render: (h, params) => {
              const approvalState = params.row.approvalState;
              let txt = ''
              const color = approvalState === 1 ? '#00ff00' : approvalState === -1 ? '#ff0000' : '#000000';
              if (approvalState != null) {
                const filterArr = config.checkStateData.filter(item => item.value === approvalState);
                console.log('========', approvalState, filterArr)
                if (filterArr && filterArr.length > 0) {
                  txt = filterArr[0].label
                }
              }
              const self = this
              if (approvalState === 2) {
                if (self.$checkAuth('approval-plans-solicitation')) {
                  return h('Button', {
                    props: { type: 'primary' },
                    style: { margin: '0 3px 0 3px' },
                    on: {
                      click: () => {
                        this.toCheck(params)
                      }
                    }
                  }, [
                    h('span', '审核')
                  ])
                }
              } else {
                if (params.row.remark != null && params.row.remark !== '') {
                  return h('Tooltip', {
                    props: {
                      content: params.row.remark,
                      transfer: true,
                      maxWidth: '300'
                    }
                  }, [h('span', {
                    class: 'row1',
                    style: { color: color }
                  }, txt)]);
                }
              }
              return h('span', {
                style: { color: color }
              }, txt)
            }
          },
          {
            title: '操作',
            key: 'action',
            show: true,
            align: 'center',
            slot: 'action',
            width: 100
          }
        ],
        loading: true,
        pageDisabled: false,
        pageRefresh: true,
        pageSizeOpts: [10, 20, 50, 100],
        tableHeight: 0,
        tableSize: 'default'
      }
    },
    watch: {
      'pc.pageIndex': function (curVal, oldVal) {
        if (curVal !== oldVal) {
          if (!this.pageRefresh) {
            return
          }
          this.load()
        }
      },
      'pc.pageSize': function (curVal, oldVal) {
        if (curVal !== oldVal) {
          if (!this.pageRefresh) {
            return
          }
          this.load()
        }
      },
      facets: {
        handler (newValue, oldValue) {
          this.load()
        },
        deep: true
      },
      $route: {
        handler () {
          if (this.$route.query.p) {
            if (this.$route.query.p - 0 !== this.pc.pageIndex) {
              this.pc.pageIndex = this.$route.query.p - 0
              this.load()
            }
          } else {
            this.pc.pageIndex = 1
            this.load()
          }
        },
        deep: true
      }
    },
    computed: {
      width () {
        return document.body.clientWidth
      },
      tableColumns () {
        const columns = [...this.columns]
        return columns.filter(item => item.show)
      }
    },
    mounted () {
      this.$nextTick(() => {
        this.autoHeight()
      })
      window.addEventListener('resize', this.autoHeight)
      if (this.$route.query.p) {
        this.pc.pageIndex = this.$route.query.p - 0
      }
      this.loadClueStatesCount();
      this.load()
    },
    created () {
    },
    methods: {
      getMetaDatas (data) {
        this.metaDataVisible = false;
        this.$refs.assetAcceptanceEditor.buildMetaData(data)
      },
      parentMethod (res) {
        console.log(res.data , res.data.detailId, ' @@@@@@@@@detailId@@@@@@@@@ ')
        this.metaDataVisible = true;
        this.$refs.accMetaData.loadMetaDataByDetailId(res.data.data)
      },
      // ==============上传===========================
      removeHandler (id) {
        const params = {
          id: id
        }
        removeFile(params).then((res) => {
          this.$Notice.success({
            title: '操作提示',
            desc: '封面删除成功'
          });
        })
      },
      successUploadHandler (res, file, oid) {
        console.log('22222222',res)
        const params = {
          objectId: oid,
          objectType: 1,
          url: res.data.url,
          fileId: res.data.id,
          content: res.data.content,
          type: 'pic'
        }
        createUpload(params).then((res) => {
          this.$Notice.success({
            title: '操作提示',
            desc: '添加成功'
          })
        })
      },
      cancelCoverDialog () {
        this.load()
      },
      showAttchments(data) {
        this.$refs.coverup.show({
          objectId: data.id,
          title: '图片上传'
        })
      },
      stateChange (state) {
        this.facets.approvalState = state
        console.log('~~~~~~~~~~~~~', state)
        this.load()
      },
      loadClueStatesCount () {
        this.facets.isSuccess = false;
        getStatesCount(this.buildParams()).then(res => {
          if (res.code === 100200) {
            res.data.forEach(item => {
              if (item.name === '全部') {
                item.state = ''
              }
            })
            this.assetStates = res.data;
            this.facets.approvalState = '';
            this.facets.isSuccess = true;
          }
        })
      },
      toSubmit (data) {
        if (!data) {
          return
        }
        this.$Modal.confirm({
          title: '提示',
          content: '<p>确定提交审核?</p>',
          cancelText: '取消',
          okText: '确定',
          onOk: () => {
            const param = {
              id: data.id,
              approvalStatus: 2,
            }
            approval(param).then((res) => {
              this.$Message.success('提交成功!')
              this.load()
            })
          },
          onCancel: () => {
          }
        })
      },
      saveCheck () {
        if (!this.checkData) {
          return
        }
        const param = {
          id: this.checkData.row.id,
          approvalRemark: this.checkRemark,
          approvalStatus: this.checkState,
          approvalLevel: this.checkType,
        }
        approval(param).then((res) => {
          this.$Message.success('提交成功!')
          this.load()
        })
      },
      toCheck (data, level) {
        console.log('0000000000000', data)
        this.checkData = data
        this.checkState = 1
        this.checkType = level
        this.checkRemark = ''
        this.appTitle = level === 1 ? '初级审批' : '复审';
        this.checkVisible = true
      },
      buildParams () {
        const self = this
        let params = {
          p: this.pc.pageIndex,
          s: this.pc.pageSize
        }
        let scs = []
        this.scs.forEach(function (order, key) {
          scs.push(key + '(' + order + ')')
        })
        if ((this.scs == null || this.scs.size == 0) && this.defaultScs != null && Object.keys(this.defaultScs).length > 0) {
          Object.keys(this.defaultScs).forEach(function (key) {
            scs.push(key + '(' + self.defaultScs[key] + ')')
          })
        }
        Object.assign(params, this.filters, this.facets, { scs: scs.join(',') })
        return params
      },
      resetParams () {
        this.filters = {
          kcs: 'name',
          keyword: ''
        }
        this.scs = new Map()
        this.facets = {
          approvalState: '',
        }
        $('th.sort-col').each(function () {
          $(this).find('.ivu-icon-md-arrow-dropup').removeClass('on')
          $(this).find('.ivu-icon-md-arrow-dropdown').removeClass('on')
        })
        this.load()
      },
      search () {
        this.pc.pageIndex = 1
        this.load()
      },
      load () {
        const self = this
        self.loading = true
        self.pageRefresh = false
        self.pageDisabled = true
        self.ids = []
        self.data = []
        getAssetAcceptanceList(self.buildParams()).then((res) => {
          self.loading = false
          self.data = res.data.records
          if (res.data.records.length > 0) {
            self.pc.pageIndex = parseInt(res.data.pageIndex)
            self.pc.total = parseInt(res.data.total)
          } else {
            self.pc = {
              pageIndex: 1,
              pageSize: this.pc.pageSize,
              total: 0
            }
          }
          self.refreshSort()
          setTimeout(function () {
            self.pageRefresh = true
            self.pageDisabled = false
          }, 500)
        })
      },
      exportExcel () {
        let params = this.buildParams()
        params.p = 1
        params.s = 10000
        getAssetAcceptanceList(params).then((res) => {
          let records = res.data.records
          if (res.data.records.length > 0) {
            records.forEach(function (item) {
            })
            let data = {
              title: ['验收编号', '名称', '验收人ID', '审核状态', '备注'],
              key: ['accNo', 'name', 'userId', 'approvalState', 'remark'],
              data: records,
              autoWidth: true,
              filename: '资产验收_' + moment().format('YYYYMMDDHHmmss')
            }
            excel.export_array_to_excel(data)
          } else {
            this.$Message.warning('无数据!')
          }
        })
      },
      sort (sc) {
        let key = sc.key
        let order = sc.order
        if (key == null || key === undefined) {
          key = sc.column.slot
        }
        if (this.scs.has(key) && this.scs.get(key) === 'asc') {
          order = 'desc'
        }
        if (key != null && key !== undefined && key !== '') {
          if (sc.order !== 'normal') {
            this.scs.set(key, order)
          } else {
            this.scs.delete(key)
          }
          this.load()
        }
      },
      refreshSort () {
        this.scs.forEach(function (order, key) {
          let ascEl = $('th.sort-' + key + '-col').find('.ivu-icon-md-arrow-dropup')
          let descEl = $('th.sort-' + key + '-col').find('.ivu-icon-md-arrow-dropdown')
          if (order === 'asc') {
            $(ascEl).addClass('on')
            $(descEl).removeClass('on')
          } else if (order === 'desc') {
            $(ascEl).removeClass('on')
            $(descEl).addClass('on')
          } else {
            $(ascEl).removeClass('on')
            $(descEl).removeClass('on')
          }
        })
      },
      showInfo (data) {
        this.infoTitle = '资产验收详情'
        this.infoVisible = true
        this.$refs.assetAcceptanceInfo.load(data.id)
      },
      edit (data) {
        let id = 0
        if (data != null) {
          id = data.id
        }
        this.editorTitle = (id === 0 ? '新建' : '修改') + '资产验收'
        this.$refs.assetAcceptanceEditor.load(id)
        this.editorVisible = true
      },
      editSuccessHandler (data, type) {
        this.editorVisible = false
        this.load()
      },
      closeHandle () {
        this.editorVisible = false
      },
      update (id, data, reload) {
        if (id != null && data != null) {
          let params = Object.assign(data, { id })
          updateAssetAcceptance(params).then((res) => {
            this.$Message.success('修改成功!')
            if (reload) {
              this.load()
            }
          })
        }
      },
      copy (data) {
        const params = {
          id: data.id
        }
        this.$Modal.confirm({
          title: '<p class="ivu-modal-confirm-title">确认要复制该数据吗?</p>',
          content: '<p class="ivu-modal-confirm-content">复制当前选中的数据项。</p>',
          iconClass: 'ios-alert',
          cancelText: '取消',
          okText: '确定',
          onOk: () => {
            copyAssetAcceptance(params).then((res) => {
              if (res.code === 100200) {
                this.$Message.success('复制成功!')
                this.load()
              } else {
                this.$Message.error(res.message);
              }
            })
          },
          onCancel: () => {

          }
        })
      },
      remove (data) {
        this.$Modal.confirm({
          title: '提示',
          content: '<p>确定删除?</p>',
          cancelText: '取消',
          okText: '确定',
          onOk: () => {
            removeAssetAcceptance({ id: data.id }).then((res) => {
              if (res.code === 100200) {
                this.$Message.success('删除成功!')
                this.load()
              } else {
                this.$Message.error(res.message)
              }
            })
          },
          onCancel: () => {
          }
        })
      },
      removeBatch () {
        if (this.ids.length > 0) {
          let params = {
            ids: this.ids
          }
          this.$Modal.confirm({
            title: '提示',
            content: '<p>确定要删除选择的数据?</p>',
            cancelText: '取消',
            okText: '确定',
            onOk: () => {
              removeAssetAcceptanceBatch(params).then((res) => {
                if (res.code === 100200) {
                  this.$Message.success('操作成功!')
                  this.load()
                } else {
                  this.$Message.error(res.message)
                }
              })
            },
            onCancel: () => {

            }
          })
        } else {
          this.$Message.error('请选择要删除的数据!')
        }
      },
      tableSelectHandler (selection) {
        const self = this
        self.ids = []
        if (selection != null && selection.length > 0) {
          selection.forEach(function (item) {
            self.ids.push(item.id)
          })
        }
      },
      autoHeight () {
        const headerHeight = this.$refs.cListHeader.offsetHeight ? this.$refs.cListHeader.offsetHeight:0;
        const footerHeight = this.$refs.cListFooter.offsetHeight
        this.tableHeight = document.body.clientHeight - headerHeight - footerHeight - 150
      },
      changePage (page) {
        this.pc.pageIndex = parseInt(page)
      },
      changePageSize (num) {
        this.pc.pageSize = parseInt(num)
      },
      handleChangeTableSize (size) {
        this.tableSize = size
      },
      attach (data) {
        this.$refs.attachment.show({
          objectId: data.id,
          objectType: 'assetAcceptance',
          title: data.name
        })
      },
      cover (data) {
        this.$refs.cover.show({
          objectId: data.id,
          objectType: 'assetAcceptance',
          title: data.name
        })
      },
    }
  }
</script>

  edit.vue

<template>
  <div>
    <Form ref="assetAcceptanceForm" :model="assetAcceptance" :rules="ruleValidate" :label-width="labelWidth"
          :label-position="labelPosition">
      <Row>
        <Col span="8">
          <Form-item label="验收编号" prop="accNo">
            <Input v-model="assetAcceptance.accNo" :disabled="true" placeholder="请输入验收编号" clearable
                   style="width: 100%"/>
          </Form-item>
        </Col>
        <Col :span="8">
          <Form-item label="验收人" prop="userId">
            <Select v-model="assetAcceptance.userId" placeholder="请选择验收人" style="width: 100%"
                    @on-change="(res) => getDeptName(res)">
              <Option v-for="item in employeeList" :key="item.id" :value="item.id">{{ item.name }}</Option>
            </Select>
          </Form-item>
        </Col>
        <Col :span="8">
          <Form-item label="验收部门" prop="dptName">
            <Input v-model="assetAcceptance.dptName" :disabled="true" placeholder="验收部门" clearable
                   style="width: 100%"/>
          </Form-item>
        </Col>
        <Col :span="8">
          <Form-item label="购入单位" prop="purchaseCompany">
            <Input v-model="assetAcceptance.purchaseCompany" placeholder="请输入购入单位" clearable
                   style="width: 100%"/>
          </Form-item>
        </Col>
        <Col :span="8">
          <Form-item label="购入日期" prop="purchaseDate">
            <DatePicker v-model="assetAcceptance.purchaseDate_dt" placeholder="请选择购入日期" type="date"
                        value-format="yyyy-MM-dd" clearable style="width: 100%"/>
          </Form-item>
        </Col>
        <Col :span="8">
          <Form-item label="收据号" prop="invoiceCode">
            <Input v-model="assetAcceptance.invoiceCode" placeholder="请输入收据号" clearable
                   style="width: 100%"/>
          </Form-item>
        </Col>
        <Col :span="24">
          <Form-item label="备注" prop="remark">
            <tinyEditor :showBtn="false" :value="assetAcceptance.remark" class="editor"
                        @input="(res)=> assetAcceptance.remark = res"></tinyEditor>
          </Form-item>
        </Col>
        <Col :span="24">

        </Col>
      </Row>
    </Form>
    <div class="form-detail" style="height: calc(100vh - 102px); overflow-y: auto">
      <AssetsTable ref="assetsTable" :accId="assetAcceptance.id" :tableDataOne="tableData" @editor-event="parentMethod" @value-changed="showMerchantEditor"/>
    </div>
    <div class="icb-editor-footer">
      <Button @click="cancelHandler">取消</Button>
      <Button type="primary" :loading="loading" @click="save">保存</Button>
    </div>
    <Modal v-model="checkVisible" :styles="drawer_styles" :title="appTitle" :mask-closable="false" :closable="true" width="700" footer-hide>
      <AssetMerchantEditor ref="assetMerchantEditor" :key="componentKey" :checkVisible="true" @on-success="editSuccessHandler" @on-close="closeHandle"/>
    </Modal>
  </div>
</template>

<script>
  import {
    acceptCode,
    createAssetAcceptance,
    getAssetAcceptance,
    updateAssetAcceptance
  } from '@api/ams/assetAcceptance'
  import AssetsTable from '../base/assetsTable';
  import { mapState } from 'vuex'
  import { getEmployeeList } from '@api/sems/employee';
  import tinyEditor from '_c/tinymce/index.vue';
  import {
    getAssetAcceptanceDetailList,
    updateAssetAcceptanceDetail,
    updateAssetAcceptanceDetailData
  } from '@api/ams/assetAcceptanceDetail';
  import AssetMerchantEditor from '../assetMerchant/editor'

  export default {
    name: 'asset-acceptance-editor',
    components: {
      AssetsTable,
      tinyEditor,
      AssetMerchantEditor
    },
    data () {
      return {
        componentKey: 0,
        drawer_styles: {
          height: 'calc(100% - 0px)',
          overflowY: 'auto',
          overflowX: 'auto',
          paddingBottom: '0px',
          position: 'static'
        },
        appTitle: '添加商户',
        checkVisible: false,
        employeeList: [],
        id: '',
        loading: false,
        isNew: false,
        tableData: [],
        assetAcceptance: {
          dptName: null,
          accNo: null,
          name: null,
          userId: null,
          approvalState: null,
          remark: null,
          purchaseDate: null,
          purchaseDate_dt: null,
          assetAcceptanceDetails: [],
          items: null,
        },
        ruleValidate: {
          accNo: [
            {
              required: true,
              message: '验收编号不能为空',
              trigger: 'blur'
            }
          ],
          name: [
            {
              required: true,
              message: '名称不能为空',
              trigger: 'blur'
            }
          ],
        }
      }
    },
    created () {

    },
    mounted () {
      this.loadEmployeeInfo()
    },
    beforeDestroy () {
    },
    destroyed () {
    },
    computed: {
      ...mapState('admin/layout', [
        'isMobile'
      ]),
      labelWidth () {
        return this.isMobile ? undefined : 80
      },
      labelPosition () {
        return this.isMobile ? 'top' : 'right'
      }
    },
    watch: {},
    methods: {
      buildMetaData (data) {
        if (data && data.length > 0){
          debugger
          var id = data[0].detailId;
          this.tableData.forEach(item => {
            const detailId = item.detailId;
            if (detailId === id){
              this.$set(item, 'assetLedgers',data)
              this.$set(item, 'metas',data.metas)
            }
          })
          console.log(this.tableData, data, 'Parent method 666666');

          // let params = {dtos : data}
          // let dtos = [];
          // data.forEach(item => {
          //   const obj = {};
          //   obj.id = item.id;
          //   obj.assetLedgers = item.assetLedgers;
          //   dtos.push(obj)
          // })
          updateAssetAcceptanceDetailData(data).then((res) => {
            this.$Message.success('修改成功!')

          })
        }
      },
      editSuccessHandler (data) {
        console.log(data, 'Parent method 2222222222');
        this.checkVisible = false
        this.$refs.assetsTable.loadMerchantList();
      },
      closeHandle () {
        console.log( 'Parent method 3333333333333');
        this.checkVisible = false
      },
      parentMethod (data) {
        console.log(data, 'Parent method called1111111');
        const self = this;
        self.$emit('list-event', { data: data });

      },
      showMerchantEditor () {
        this.checkVisible = true;
        this.componentKey += 1;
      },
      saveCheck () {
        // this.checkVisible = false;
        this.$refs.assetMerchantEditor.save();
        this.$refs.assetsTable.loadMerchantList();
      },
      editMetaData (accId) {
        console.log(accId, ' ----------!!-------- ')
        this.$emit('editMetaData', accId)
      },
      getAssetAcceptanceCode () {
        acceptCode().then((res) => {
          if (res.code === 100200) {
            console.log(res.message, 7777777777777777)
            this.$set(this.assetAcceptance, 'accNo', res.message);
          }
        });
      },
      getDetails () {
        const self = this
        self.loading = true
        const param = {
          p: 1,
          s: 1000,
          accId: this.accId
        }
        self.tableData = [];

        getAssetAcceptanceDetailList(param).then((res) => {
          self.loading = false
          if (res.code === 100200) {
            const data = res.data;
            if (data) {
              const records = data.records;
              records.forEach(item => {
                item.price = Number(item.price)
              })
              self.tableData = records;
            }
          }
        });
      },
      getDeptName (res) {
        console.log('!!!!!!!!!!!', res, this.employeeList)
        if (res) {
          this.assetAcceptance.dptName = this.employeeList.filter(item => item.id === res)[0].department || '未知'
        }
      },
      loadEmployeeInfo () {
        const params = {
          p: 1,
          s: 1000,
          state: 1
        }
        getEmployeeList(params).then((res) => {
          this.employeeList = res.data.records
        })
      },
      async load (id) {
        this.loading = false
        this.$refs.assetAcceptanceForm.resetFields()
        this.isNew = (id === 0)
        this.tableData = [];
        if (this.isNew) {
          this.assetAcceptance = {}
          this.tableData = [{
            num: 1,
            price: 0,
            name: '',
            model: '',
            productId: '',
            specList: []
          }]
          this.getAssetAcceptanceCode();
        } else {
          let params = { id }
          await getAssetAcceptance(params).then((res) => {
            let assetAcceptance = res.data
            this.assetAcceptance = assetAcceptance
            if (assetAcceptance.purchaseDate != null && !isNaN(assetAcceptance.purchaseDate)) {
              assetAcceptance.purchaseDate_dt = new Date(assetAcceptance.purchaseDate - 0)
            }
            // getDeptName(res)
            if (assetAcceptance.userId) {
               this.getDeptName(assetAcceptance.userId)
            }
            const assetAcceptanceDetails = this.assetAcceptance.assetAcceptanceDetails;
            console.log(assetAcceptanceDetails, 88888888888)
            if (assetAcceptanceDetails) {
              this.tableData = assetAcceptanceDetails;

              this.tableData.forEach(item => {
                item.price = Number(item.price)
              })
              console.log('zhixingl')
            }
          })
          this.$refs.assetsTable.loadProductSelect()
        }
      },
      isValidInvoiceNumber (invoiceNumber) {
        return /^\d{10}$/.test(invoiceNumber);
      },
      save () {
        const tableData = this.tableData;
        if (tableData.length < 1) {
          this.$Message.error('请添加验收资产数据');
          return false;
        }
        const find = tableData.find(item => !item.assetsName);
        if (find) {
          this.$Message.error('请填写完整资产名称');
          return false;
        }

        const find2 = tableData.find(item => !item.invoiceCode || (item.invoiceCode && !this.isValidInvoiceNumber(item.invoiceCode)));
        if (find2) {
          this.$Message.error('请填写正确的发票');
          return false;
        }

        const find3 = tableData.find(item => !item.merchantId);
        if (find3) {
          this.$Message.error('请填写完整商户');
          return false;
        }

        this.$refs.assetAcceptanceForm.validate((valid) => {
          // this.loading = true
          if (valid) {
            if (this.assetAcceptance.purchaseDate_dt != null) {
              this.assetAcceptance.purchaseDate = this.assetAcceptance.purchaseDate_dt.getTime()
            }
            this.assetAcceptance.assetAcceptanceDetails = tableData
            if (this.isNew) {
              this.create()
            } else {
              this.modify()
            }
          } else {
            this.$Message.error('信息校验失败,请根据页面提示纠正您所填写的信息!')
            this.loading = false
          }
        })
      },
      create () {
        createAssetAcceptance(this.assetAcceptance).then((res) => {
          if (res.code === 100200) {
            this.$Message.success('添加成功!')
            this.reset()
            this.$emit('on-success', res.data, 'create')
          } else {
            this.$Message.error('添加失败,请稍后重试!')
          }
          this.loading = false
        })
      },
      modify () {
        this.$Modal.confirm({
          title: '操作提示',
          content: '是否修改该数据?',
          okText: '修改',
          onCancel: () => {
            this.loading = false
          },
          onOk: () => {
            updateAssetAcceptance(this.assetAcceptance).then((res) => {
              if (res.code === 100200) {
                this.$Message.success('修改成功!')
                this.$emit('on-success', res.data, 'update')
              } else {
                this.$Message.error('修改失败!')
              }
              this.loading = false
            })
          }
        })
      },
      reset () {
        this.assetAcceptance = {}
        this.$refs.assetAcceptanceForm.resetFields()
      },
      cancelHandler () {
        this.$emit('on-close')
      }
    }
  }
</script>

  

<template>
  <div class="assets-table">
    <Table :columns="tableColumns"
           :data="subscriptionData"
           class="assets-tables"
           :size="tableSize"
           :height="tableHeight"
           :no-data-text="$gdata.tableNoDataText" border
           :header-cell-style="{background:'#F8F8F8',color:'black',padding:'3px'}" :cell-style="{padding:'0px'}">
      <template slot-scope="{ row,index }" slot="name">
        <Input type="text" v-model="row.assetsName" @input="(value) => dataChane(value,index,'assetsName')"/>
      </template>
      <template slot-scope="{ row ,index}" slot="category">
        <Select v-model="row.categoryId" @on-change="(value) => loadProducts(value,index)">
          <OptionGroup label="固定资产">
            <Option v-for="item in categoryList1.slice()" :key="item.id" :label="item.name" :value="item.id"/>
          </OptionGroup>
          <OptionGroup label="无形资产">
            <Option v-for="item in categoryList2.slice()" :key="item.id" :label="item.name" :value="item.id"/>
          </OptionGroup>
        </Select>
      </template>
      <template slot-scope="{ row, index }" slot="product">
        <Select v-model="row.productId" @on-change="value => dataChane(value,index,'productId')"
                :disabled="!row.categoryId">
          <Option v-for="item in row.specList" :key="item.id" :label="item.name" :value="item.id"/>
        </Select>
      </template>
      <template slot-scope="{ row, index }" slot="num">
        <Input-number @on-change="value => dataChane(value,index,'num')" v-model="row.num" :min="0"
                      controls-position="right"/>
      </template>
      <template slot-scope="{ row, index }" slot="price">
        <Input-number @on-change="value => dataChane(value,index,'price')" v-model="row.price" :min="0" :precision="2"
                      controls-position="right"/>
      </template>
      <template slot-scope="{ row,index }" slot="action">
        <Tooltip content="添加申购项">
          <Button @click="add" type="text" icon="md-add"/>
        </Tooltip>
        <Tooltip content="关联参数">
          <Button @click="bindMeta(row, index)" type="text" icon="ios-link"/>
        </Tooltip>
        <Tooltip content="删除申购项">
          <Button @click="remove(index)" type="text" icon="ios-trash" style="color: red"/>
        </Tooltip>
      </template>
    </Table>
    <!--    <Modal v-model="checkVisible" :styles="drawer_styles" :title="appTitle" @on-ok="saveCheck">-->
    <!--      <MetaData ref="metaData" :state="2" @value-changed="handleValueChange"/>-->
    <!--    </Modal>-->
  </div>
</template>

<script>
  import { getAssetCategoryList } from '@api/ams/assetCategory'
  import { getAssetProductList } from '@api/ams/assetProduct';
  import expandRow from './expand'
  import MetaData from './metaData'
  import edgers from '_p/ams/assetReturn/edgers.vue';

  export default {
    name: 'AssetsTable',
    components: {
      edgers,
      expandRow,
      MetaData
    },
    props: {
      subscriptionData: {
        type: Array,
        default: []
      },
    },
    data () {
      return {
        receivedValue: '',
        drawer_styles: {
          height: 'calc(100% - 200px)',
          overflowY: 'auto',
          overflowX: 'auto',
          paddingBottom: '0px',
          position: 'static'
        },
        checkVisible: false,
        appTitle: '',
        tableHeight: 0,
        tableSize: 'default',
        loading: true,
        columns: [
          {
            type: 'expand',
            width: 50,
            show: true,
            render: (h, params) => {
              return this.$createElement(expandRow, {
                props: {
                  row: params.row
                },
                on: {
                  // 子组件$emit传递方法以及参数
                }
              })
            }
          },
          {
            type: 'index',
            show: true,
            width: 60,
            align: 'right'
          },
          {
            title: '资产名称',
            key: 'assetsName',
            slot: 'name',
            show: true,
            tooltip: true,
            maxWidth: 350,
            minWidth: 150,
            className: 'sort-col sort-assetsName-col'
          },
          {
            title: '资产类型',
            key: 'categoryId',
            show: true,
            tooltip: true,
            maxWidth: 350,
            minWidth: 100,
            slot: 'category',
            className: 'sort-col sort-categoryId-col'
          },
          {
            title: '产品类型',
            key: 'productId',
            show: true,
            tooltip: true,
            maxWidth: 350,
            minWidth: 100,
            slot: 'product',
            className: 'sort-col sort-productId-col'
          },
          {
            title: '购买数量',
            key: 'num',
            show: true,
            tooltip: true,
            maxWidth: 350,
            minWidth: 100,
            slot: 'num',
            className: 'sort-col sort-assetNum-col'
          },
          {
            title: '询价(元)',
            key: 'price',
            show: true,
            tooltip: true,
            maxWidth: 350,
            minWidth: 120,
            slot: 'price',
            className: 'sort-col sort-price-col'
          },
          {
            title: '操作',
            key: 'action',
            show: true,
            align: 'center',
            slot: 'action',
            width: 150
          }
        ],
        categoryList1: [],
        categoryList2: [],
        detailsList: [],
        specList: [],
      }
    },
    watch: {},
    computed: {
      width () {
        return document.body.clientWidth
      },
      tableColumns () {
        const columns = [...this.columns]
        return columns.filter(item => item.show)
      },
    },
    mounted () {

      this.$nextTick(() => {
        this.autoHeight()
      })

      this.getClassifyGbIsIntangibles();
    },
    created () {
    },
    methods: {
      buildMetas (entityMetas) {

      },
      handleValueChange (newValue) {
        this.receivedValue = newValue;
        console.log('iiiiii======iiiiiiii', this.receivedValue)
        self.$emit('child-event', { data: this.receivedValue });
      },
      saveCheck () {

      },
      loadProductSelect () {
        console.log('iiiiiiiiiiiiii', this.subscriptionData)
        const self = this
        this.subscriptionData.forEach((item, index) => {
          const productId = item.productId;
          const categoryId = item.categoryId;
          self.loadProducts(categoryId, index);
          console.log(productId, index, self.subscriptionData[index], '*************');
          self.$set(self.subscriptionData[index], 'productId', productId)
        })
      },
      dataChane (value, index, name) {
        console.log(value, index, name)
        if (!value) return
        const subscriptionDataElement = this.subscriptionData[index];
        this.$set(this.subscriptionData[index], name, value)
        if (name === 'productId') {// 自动给名称赋值 name+model+productId
          subscriptionDataElement.specList.forEach(item => {
            if (value === item.id) {
              const assetsName = this.subscriptionData[index].assetsName || '';
              this.$set(this.subscriptionData[index], 'assetsName', assetsName.split('_')[0] + '_' + item.model + '-' + item.spec)
            }
          })
        }
      },
      async getClassifyGbIsIntangibles () {
        // 使用async/await等待两个方法完成
        this.categoryList1 = await this.getClassify(0);
        this.categoryList2 = await this.getClassify(1);
      },
      createProducts (value, index) {
        getAssetProductList({
          p: 1,
          s: 100,
          categoryId: value
        }).then((res) => {
          if (res.code === 100200) {
            this.$set(this.subscriptionData[index], 'specList', res.data.records)
          }
        });
      },
      loadProducts (value, index) {
        this.$set(this.subscriptionData[index], 'categoryId', value)
        this.$set(this.subscriptionData[index], 'productId', '')
        getAssetProductList({
          p: 1,
          s: 100,
          categoryId: value
        }).then((res) => {
          if (res.code === 100200) {
            console.log(this.subscriptionData[index], '*******11****');
            this.$set(this.subscriptionData[index], 'specList', res.data.records)
          }
        });
      },
      async getClassify (sign) {
        const param = {
          p: 1,
          s: 1000,
          isIntangibles: sign
        }
        return await getAssetCategoryList(param).then((res) => {
          if (res.code === 100200) {
            return res.data.records;
          }
        });
      },
      add () {
        this.subscriptionData.push({
          num: 1,
          price: 0,
          name: '',
          model: '',
          productId: '',
          metas: [],
          specList: []
        });
      },
      bindMeta (data, index) {
        console.log(data, this.subscriptionData, '*******22222****');
        if (!data || !data.productId) {
          this.$Message.error('请先选择产品类型信息!');
          return;
        }
        const self = this;
        this.$set(data, 'index', index);
        self.$emit('edit-event', {
          data: data
        });
        // this.$refs.metaData.loadMetaDataByProId(data.productId)
        // console.log(self.$emit.$parent('editMetaData', data.id))
      },
      remove (index) {
        if (this.subscriptionData.length < 2) {
          this.$Message.error('至少保留一条数据');
          return false;
        }
        this.subscriptionData.splice(index, 1);
      },
      handleChangeTableSize (size) {
        this.tableSize = size
      },
      autoHeight () {
        const headerHeight = this.$refs.cListHeader.offsetHeight
        const footerHeight = this.$refs.cListFooter.offsetHeight
        this.tableHeight = document.body.clientHeight - headerHeight - footerHeight - 80
      },
    }
  }
</script>

<style>
.assets-table .cell {
  padding-left: 0 !important;
  padding-right: 0 !important;
}

.assets-tables {
  overflow: unset !important;
}

.assets-table .Input__inner {
  border-radius: 0 !important;
  border: none !important;
}

.assets-table .Input-number {
  width: 100% !important;
}
</style>

  

<template>
  <div>
    <Form ref="assetMetaForm" :model="newobj" :rules="rules">
      <Row v-for="(definition,di) in assetProductDefinition" :key="di">
        <Col v-if="definition.uiType==='input'" span="24">
          <Form-item :label="definition.label" :prop="definition.name"
                     v-if="definition.dataType=== 'double'">
            <InputNumber v-model="newobj[definition.name]"
                         :placeholder="definition.placeholder"></InputNumber>
          </Form-item>
          <Form-item :label="definition.label" :prop="definition.name"
                     v-else-if="definition.dataType=== 'integer'">
            <InputNumber v-model="newobj[definition.name]"
                         :placeholder="definition.placeholder"></InputNumber>
          </Form-item>
          <Form-item :label="definition.label" :prop="definition.name" v-else-if="definition.dataType=== 'textarea'">
            <Input v-model="newobj[definition.name]" type="textarea" :rows="5"
                   :placeholder="definition.placeholder"></Input>
          </Form-item>
          <Form-item :label="definition.label" :prop="definition.name" v-else>
            <Input v-model="newobj[definition.name]" :placeholder="definition.placeholder"></Input>
          </Form-item>
        </Col>
        <Col v-if="definition.uiType==='select'" span="24">
          <Form-item :label="definition.label" :prop="definition.name">
            <select2 v-if="definition.dataType=== 'udd'" v-model="newobj[definition.name]"
                     :url="definition.dctCode"></select2>
            <select2 v-else v-model="newobj[definition.name]" :options="definition.dctCode"></select2>
          </Form-item>
        </Col>
        <Col v-if="definition.uiType==='multiple'" span="24">
          <Form-item :label="definition.label" :prop="definition.name">

            <select2 v-if="definition.dataType=== 'udd'" v-model="newobj[definition.name]"
                     :url="definition.dctCode" multiple></select2>
            <select2 v-else v-model="newobj[definition.name]" :options="definition.dctCode" multiple></select2>
          </Form-item>
        </Col>
        <Col v-if="definition.uiType==='datepicker'" span="24">
          <Form-item :label="definition.label" :prop="definition.name">
            <DatePicker v-model="newobj[definition.name]" type="date"
                        :placeholder="definition.placeholder" transfer></DatePicker>
          </Form-item>
        </Col>
        <Col v-if="definition.uiType==='datetimepicker'" span="24">
          <Form-item :label="definition.label" :prop="definition.name">
            <DatePicker v-model="newobj[definition.name]" type="datetime"
                        :placeholder="definition.placeholder" transfer></DatePicker>
          </Form-item>
        </Col>
        <Col v-if="definition.uiType==='summernote'" span="24">
          <Form-item :label="definition.label" :prop="definition.name">
            <tinyEditor class="editor" :value="newobj[definition.name]" :showBtn="true"
                        @input="(res)=> newobj[definition.name] = res"></tinyEditor>
          </Form-item>
        </Col>
        <Col v-if="definition.uiType==='radio'" span="24">
          <Form-item :label="definition.label" :prop="definition.name">
            <radio2 v-if="definition.dataType=== 'udd'" v-model="newobj[definition.name]"
                    :url="definition.dctCode"></radio2>
            <radio2 v-else v-model="newobj[definition.name]" :options="definition.dctCode"></radio2>
          </Form-item>
        </Col>
        <Col v-if="definition.uiType==='checkbox'" span="24">
          <Form-item :label="definition.label" :prop="definition.name">
            <checkbox2 v-if="definition.dataType=== 'udd'" v-model="newobj[definition.name]"
                       :url="definition.dctCode"></checkbox2>
            <checkbox2 v-else v-model="newobj[definition.name]" :options="definition.dctCode"></checkbox2>
          </Form-item>
        </Col>
      </Row>
      <div class="demo-drawer-footer" style="margin-left: 70%">
        <Button style="margin-right: 8px" @click="toCannel">取消</Button>
        <Button type="primary" :loading="loading" @click="toSubmit">完成填写</Button>
      </div>
    </Form>
  </div>
</template>

<script>
  import { clone } from '@/libs/tools';
  import select2 from '_c/select2/select2';
  import select3 from '_c/select2/select3';
  import checkbox2 from '_c/checkbox2/checkbox2';
  import radio2 from '_c/radio2/radio2';
  import tinyEditor from '_c/tinymce';
  import toolsView from '_c/toolsView';
  import { mapState } from 'vuex'
  import config from '../config.json'
  import poptip2 from '_c/poptip2/poptip2';
  import { getAssetProductDefinitionList, } from '@api/ams/assetProductDefinition'

  export default {
    name: 'meta-datum-editor',
    components: {
      select2,
      checkbox2,
      radio2,
      tinyEditor,
      toolsView,
      select3,
      poptip2
    },
    data () {
      return {
        productId: null,
        detailId: null,
        rowNum: null,
        loading: false,
        config,
        assetProductDefinition: [],
        newobj: {},
        rules: {},
      }
    },
    created () {
    },
    mounted () {
    },
    beforeDestroy () {
    },
    destroyed () {
    },
    computed: {
      ...mapState('admin/layout', [
        'isMobile'
      ]),
      labelWidth () {
        return this.isMobile ? undefined : 80;
      },
      labelPosition () {
        return this.isMobile ? 'top' : 'right';
      }
    },
    watch: {},
    methods: {
      toCannel () {
        this.$emit('on-close');
      },
      toSubmit () {
        console.log('66666666', this.newobj)
        this.$refs.assetMetaForm.validate((valid) => {
          // this.loading = true
          if (valid) {
            this.$Modal.confirm({
              title: '操作提示',
              content: '是否填写完成?',
              okText: '修改',
              onCancel: () => {
              },
              onOk: () => {
                this.save();
                this.$Message.success('完成填写!')
                this.$emit('on-close');
              }
            })
          } else {
            this.$Message.error('信息校验失败,请根据页面提示纠正您所填写的信息!')
            this.loading = false
          }
        })
      },
      save () {
        const requestData = clone(this.newobj);
        const entityMetas = [];
        const des = this.assetProductDefinition;
        for (let i = 0; i < des.length; i++) {
          if (this.newobj[des[i].name] instanceof Array) {
            requestData[des[i].name] = this.newobj[des[i].name].join(',');
          }
          const meta = {};
          console.log(des[i], '============des[i]============')
          // meta.id = des[i].id;
          meta.metaKey = des[i].name;
          meta.metaValue = requestData[des[i].name];
          meta.metaPriority = des[i].priority;
          entityMetas.push(meta);
        }

        requestData.entityMetas = entityMetas;
        requestData.productId = this.productId;
        requestData.detailId = this.detailId;
        requestData.rowNum = this.rowNum;
        console.log(entityMetas, requestData, '===========================')
        const self = this;
        console.log(self.$emit('getDefinition'), '==============11===========')
        // self.$emit('meta-event', { data: requestData.entityMetas })
        self.$emit('value-changed', requestData);
      },
      loadMetaDataByProId (data) {
        this.assetProductDefinition = [];
        this.newobj = {};
        this.rules = {};
        this.productId = data.productId;
        this.detailId = data.id;
        this.getDefinition(data)
      },
      getDefinition (data) {
        console.log(data, 9999999999)
        const productId = data.productId;
        const metas = data.metas;

        // const detailId = data.id;

        let params = {
          p: 0,
          s: 1000,
          productId: productId,
        }
        getAssetProductDefinitionList(params).then((res) => {
          let assetProductDefinition = res.data.records
          // this.assetProductDefinition = assetProductDefinition
          console.log(metas, assetProductDefinition, 888888888888888)
          for (let i = 0; i < assetProductDefinition.length; i++) {
            const d = assetProductDefinition[i];
            if (metas) {
              for (let j = 0; j < metas.length; j++) {

                const meta = metas[j];
                if (d.name === meta.metaKey) {
                  if (d.uiType === 'multiple' || d.uiType === 'checkbox') {
                    if (meta.metaValue !== null && meta.metaValue !== '') {
                      this.newobj[meta.metaKey] = meta.metaValue.split(',');
                    } else {
                      this.newobj[meta.metaKey] = meta.metaValue;
                    }
                  } else {
                    if (d.dataType === 'integer' || d.dataType === 'double') {
                      this.newobj[meta.metaKey] = meta.metaValue - 0;
                    } else {
                      this.newobj[meta.metaKey] = meta.metaValue;
                    }
                  }

                }
              }
            }

            console.log(this.newobj, 7777777777777)
            if (d.required === 1) {
              let dd = [];
              if (d.uiType === 'datepicker' || d.uiType === 'datetimepicker') {
                dd = [{
                  required: true,
                  type: 'date',
                  message: '请选择时间',
                  trigger: 'change'
                }];
              } else if (d.uiType === 'integer' || d.uiType === 'double') {
                dd = [{
                  required: true,
                  message: d.label + '不能为空',
                  trigger: 'change',
                  type: 'number'
                }];
              } else {
                dd = [{
                  required: true,
                  message: d.label + '不能为空',
                  trigger: 'blur'
                }];
              }
              this.rules[d.name] = dd;
            }
            this.rowNum = data.index;
            this.assetProductDefinition.push(d);
          }
        })
      },
    }
  }
</script>
<style>

</style>

  

 

posted @ 2024-09-10 17:10  蔡徐坤1987  阅读(16)  评论(0编辑  收藏  举报