Browse Source

Merge branch 'dev' into 特权藏品

licailing 4 years ago
parent
commit
a960539bb1

+ 4 - 0
src/main/java/com/izouma/nineth/annotations/Searchable.java

@@ -1,5 +1,7 @@
 package com.izouma.nineth.annotations;
 
+import com.izouma.nineth.enums.SearchMode;
+
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -9,4 +11,6 @@ import java.lang.annotation.Target;
 @Retention(RetentionPolicy.RUNTIME)
 public @interface Searchable {
     boolean value() default true;
+
+    SearchMode mode() default SearchMode.CONFIG;
 }

+ 1 - 0
src/main/java/com/izouma/nineth/config/CacheConfig.java

@@ -78,6 +78,7 @@ public class CacheConfig {
 //                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));
 //        return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);
 //    }
+
     @Bean
     public RedisCacheManager userRedisCacheManager(RedisTemplate redisTemplate) {
         Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<>(Object.class);

+ 2 - 0
src/main/java/com/izouma/nineth/config/EventNames.java

@@ -2,4 +2,6 @@ package com.izouma.nineth.config;
 
 public class EventNames {
     public final static String SWITCH_ACCOUNT = "switchAccount";
+
+    public final static String CONFIG_CHANGE = "configChange";
 }

+ 31 - 0
src/main/java/com/izouma/nineth/config/RocketMqConfig.java

@@ -0,0 +1,31 @@
+package com.izouma.nineth.config;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import org.apache.rocketmq.spring.support.RocketMQMessageConverter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.messaging.converter.CompositeMessageConverter;
+import org.springframework.messaging.converter.MappingJackson2MessageConverter;
+import org.springframework.messaging.converter.MessageConverter;
+
+import java.util.List;
+
+@Configuration
+public class RocketMqConfig {
+
+    @Bean
+    public RocketMQMessageConverter createRocketMQMessageConverter() {
+        RocketMQMessageConverter converter = new RocketMQMessageConverter();
+        CompositeMessageConverter compositeMessageConverter = (CompositeMessageConverter) converter.getMessageConverter();
+        List<MessageConverter> messageConverterList = compositeMessageConverter.getConverters();
+        for (MessageConverter messageConverter : messageConverterList) {
+            if (messageConverter instanceof MappingJackson2MessageConverter) {
+                MappingJackson2MessageConverter jackson2MessageConverter = (MappingJackson2MessageConverter) messageConverter;
+                ObjectMapper objectMapper = jackson2MessageConverter.getObjectMapper();
+                objectMapper.registerModules(new JavaTimeModule());
+            }
+        }
+        return converter;
+    }
+}

+ 8 - 2
src/main/java/com/izouma/nineth/domain/Collection.java

@@ -24,11 +24,15 @@ import java.util.List;
 @Data
 @Entity
 @Table(name = "collection_info", indexes = {
-        @Index(columnList = "type,source"),
+        @Index(columnList = "type"),
+        @Index(columnList = "source"),
         @Index(columnList = "minterId"),
         @Index(columnList = "onShelf"),
         @Index(columnList = "ownerId"),
-        @Index(columnList = "assetId")
+        @Index(columnList = "assetId"),
+        @Index(columnList = "salable"),
+        @Index(columnList = "del"),
+        @Index(columnList = "name")
 })
 @AllArgsConstructor
 @NoArgsConstructor
@@ -189,4 +193,6 @@ public class Collection extends BaseEntity {
     @ApiModelProperty("开启抢白名单")
     private Boolean openQuota;
 
+    @ApiModelProperty("最低消费")
+    private BigDecimal minimumCharge;
 }

+ 8 - 2
src/main/java/com/izouma/nineth/domain/User.java

@@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.izouma.nineth.JsonView.UserView;
 import com.izouma.nineth.annotations.Searchable;
 import com.izouma.nineth.enums.AuthStatus;
+import com.izouma.nineth.enums.SearchMode;
 import com.izouma.nineth.security.Authority;
 import com.izouma.nineth.utils.UserAuthoritySerializer;
 import io.swagger.annotations.ApiModel;
@@ -33,7 +34,9 @@ import java.util.Set;
         @Index(columnList = "admin"),
         @Index(columnList = "minter"),
         @Index(columnList = "createdAt"),
-        @Index(columnList = "settleAccountId")
+        @Index(columnList = "settleAccountId"),
+        @Index(columnList = "nickname"),
+        @Index(columnList = "del"),
 })
 @AllArgsConstructor
 @NoArgsConstructor
@@ -84,7 +87,7 @@ public class User extends BaseEntityNoID implements Serializable {
 
     private String country;
 
-    @Searchable
+    @Searchable(mode = SearchMode.EXACT)
     private String phone;
 
     private String email;
@@ -159,4 +162,7 @@ public class User extends BaseEntityNoID implements Serializable {
 
     @ApiModelProperty(value = "风险提示")
     private Boolean riskWarning;
+
+    @Column(columnDefinition = "int(11) default 0")
+    private boolean canSale = false;
 }

+ 9 - 0
src/main/java/com/izouma/nineth/enums/SearchMode.java

@@ -0,0 +1,9 @@
+package com.izouma.nineth.enums;
+
+public enum SearchMode {
+    PREFIX,
+    SUFFIX,
+    FULL,
+    EXACT,
+    CONFIG
+}

+ 12 - 0
src/main/java/com/izouma/nineth/listener/BroadcastEventListener.java

@@ -3,7 +3,9 @@ package com.izouma.nineth.listener;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.serializer.SerializerFeature;
 import com.izouma.nineth.config.EventNames;
+import com.izouma.nineth.enums.SearchMode;
 import com.izouma.nineth.service.AdapayMerchantService;
+import com.izouma.nineth.utils.JpaUtils;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.rocketmq.spring.annotation.ConsumeMode;
@@ -37,6 +39,16 @@ public class BroadcastEventListener implements RocketMQListener<JSONObject> {
                         log.error("event error", e);
                     }
                     break;
+                case EventNames.CONFIG_CHANGE:
+                    try {
+                        JSONObject data = message.getJSONObject("data");
+                        if ("default_search_mode".equals(data.getString("name"))) {
+                            SearchMode searchMode = SearchMode.valueOf(data.getString("value"));
+                            JpaUtils.setDefaultSearchMode(searchMode);
+                        }
+                    } catch (Exception e) {
+                        log.error("event error", e);
+                    }
             }
         }
     }

+ 2 - 1
src/main/java/com/izouma/nineth/repo/CollectionRepo.java

@@ -14,6 +14,7 @@ import org.springframework.data.jpa.repository.Query;
 
 import javax.annotation.Nonnull;
 import javax.transaction.Transactional;
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Optional;
@@ -40,7 +41,7 @@ public interface CollectionRepo extends JpaRepository<Collection, Long>, JpaSpec
                 String properties, String model3d, int maxCount, String countId, boolean scanCode,
                 boolean noSoldOut, int assignment, boolean couponPayment, String shareBg, String registerBg,
                 Integer vipQuota, Boolean timeDelay, LocalDateTime saleTime, Integer holdDays, Boolean openQuota,
-                Integer totalQuota);
+                Integer totalQuota, BigDecimal minimumCharge);
 
     @Cacheable("collection")
     Optional<Collection> findById(@Nonnull Long id);

+ 1 - 39
src/main/java/com/izouma/nineth/service/CollectionService.java

@@ -156,7 +156,7 @@ public class CollectionService {
                 record.getMaxCount(), record.getCountId(), record.isScanCode(), record.isNoSoldOut(),
                 record.getAssignment(), record.isCouponPayment(), record.getShareBg(), record.getRegisterBg(),
                 record.getVipQuota(), record.getTimeDelay(), record.getSaleTime(), record.getHoldDays(),
-                record.getOpenQuota(), record.getTotalQuota());
+                record.getOpenQuota(), record.getTotalQuota(), record.getMinimumCharge());
 
         record = collectionRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录"));
         onShelfTask(record);
@@ -542,44 +542,6 @@ public class CollectionService {
         log.info("邀请实名认证人量:{}", collect2.size());
 //        log.info("sql: update user set vip_point = 1 where id in ({})", longArrayConverter.convertToDatabaseColumn(collect2));
 
-        //只留库存数量
-//        List<PointDTO> result = dtos.stream()
-//                .sorted(Comparator.comparing(PointDTO::getCreatedAt))
-//                .collect(Collectors.toList());
-//        List<Long> userIds = result.stream().map(PointDTO::getId).collect(Collectors.toList());
-//        Map<Long, User> resultMap = userRepo.findAllById(userIds)
-//                .stream()
-//                .collect(Collectors.toMap(User::getId, user -> user));
-//
-//        List<PointDTO> result2 = new ArrayList<>();
-//        List<PointDTO> result3 = new ArrayList<>();
-//        result.forEach(dto -> {
-//            if (dto.getIdentitySum() > 0) {
-//                result2.add(dto);
-//            } else {
-//                result3.add(dto);
-//            }
-//        });
-//
-//        result2.addAll(result3);
-
-
-        //加积分,存记录
-//        result.forEach(pointDTO -> {
-//            User user = resultMap.get(pointDTO.getId());
-//            if (user.getVipPoint() <= 0) {
-//                user.setVipPoint(1);
-//                userRepo.save(user);
-//                pointRecordRepo.save(PointRecord.builder()
-//                        .collectionId(collectionId)
-//                        .userId(pointDTO.getId())
-//                        .type("VIP_POINT")
-//                        .point(1)
-//                        .build());
-//            }
-//
-//        });
-
         return dtos;
     }
 }

+ 14 - 1
src/main/java/com/izouma/nineth/service/OrderService.java

@@ -214,6 +214,15 @@ public class OrderService {
                     throw new BusinessException("限购" + collection.getMaxCount() + "件");
                 }
             }
+            User user = null;
+            if (ObjectUtils.isNotEmpty(collection.getMinimumCharge()) && collection.getMinimumCharge()
+                    .compareTo(BigDecimal.ZERO) > 0) {
+                user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
+                if (!user.isCanSale()) {
+                    throw new BusinessException("绿洲石不足");
+                }
+            }
+
 
             //查询是否有拉新任务,只算官方购买
             if (collection.getSource() != CollectionSource.TRANSFER && collection.getAssignment() > 0) {
@@ -223,7 +232,11 @@ public class OrderService {
                         throw new BusinessException("当前还未开售");
                     }
                 }
-                User user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
+
+                if (user == null) {
+                    user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
+                }
+
                 if (vip) {
                     int purchase = orderRepo.countByUserIdAndCollectionIdAndVipTrueAndStatusIn(userId, collectionId, Arrays.asList(OrderStatus.FINISH, OrderStatus.NOT_PAID, OrderStatus.PROCESSING));
                     if (user.getVipPurchase() - purchase <= 0) {

+ 15 - 4
src/main/java/com/izouma/nineth/service/SysConfigService.java

@@ -2,6 +2,7 @@ package com.izouma.nineth.service;
 
 import com.izouma.nineth.domain.SysConfig;
 import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.enums.SearchMode;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.repo.SysConfigRepo;
 import com.izouma.nineth.utils.JpaUtils;
@@ -49,7 +50,7 @@ public class SysConfigService {
 
     @PostConstruct
     public void init() {
-        if (!sysConfigRepo.findByName("gift_gas_fee").isPresent()) {
+        if (sysConfigRepo.findByName("gift_gas_fee").isEmpty()) {
             sysConfigRepo.save(SysConfig.builder()
                     .name("gift_gas_fee")
                     .desc("转赠gas费")
@@ -57,7 +58,7 @@ public class SysConfigService {
                     .value("1")
                     .build());
         }
-        if (!sysConfigRepo.findByName("enable_wx_pub").isPresent()) {
+        if (sysConfigRepo.findByName("enable_wx_pub").isEmpty()) {
             sysConfigRepo.save(SysConfig.builder()
                     .name("enable_wx_pub")
                     .desc("使用公众号支付")
@@ -65,7 +66,7 @@ public class SysConfigService {
                     .value("FALSE")
                     .build());
         }
-        if (!sysConfigRepo.findByName("enable_wx_lite").isPresent()) {
+        if (sysConfigRepo.findByName("enable_wx_lite").isEmpty()) {
             sysConfigRepo.save(SysConfig.builder()
                     .name("enable_wx_lite")
                     .desc("使用小程序支付")
@@ -73,7 +74,7 @@ public class SysConfigService {
                     .value("FALSE")
                     .build());
         }
-        if (!sysConfigRepo.findByName("hold_days").isPresent()) {
+        if (sysConfigRepo.findByName("hold_days").isEmpty()) {
             sysConfigRepo.save(SysConfig.builder()
                     .name("hold_days")
                     .desc("持有满几天可销售")
@@ -81,5 +82,15 @@ public class SysConfigService {
                     .value("5")
                     .build());
         }
+        if (sysConfigRepo.findByName("default_search_mode").isEmpty()) {
+            sysConfigRepo.save(SysConfig.builder()
+                    .name("default_search_mode")
+                    .desc("默认搜索方式")
+                    .type(SysConfig.ValueType.STRING)
+                    .value("FULL")
+                    .build());
+        }
+        SearchMode searchMode = SearchMode.valueOf(sysConfigRepo.findByName("default_search_mode").get().getValue());
+        JpaUtils.setDefaultSearchMode(searchMode);
     }
 }

+ 29 - 2
src/main/java/com/izouma/nineth/utils/JpaUtils.java

@@ -3,11 +3,13 @@ package com.izouma.nineth.utils;
 import com.izouma.nineth.annotations.Searchable;
 import com.izouma.nineth.annotations.SearchableOne;
 import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.enums.SearchMode;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Component;
 
 import javax.persistence.criteria.CriteriaBuilder;
 import javax.persistence.criteria.CriteriaQuery;
@@ -23,7 +25,15 @@ import java.util.regex.Pattern;
 
 @Slf4j
 @SuppressWarnings("ALL")
+@Component
 public class JpaUtils {
+
+    private static SearchMode defaultSearchMode = SearchMode.PREFIX;
+
+    public static void setDefaultSearchMode(SearchMode defaultSearchMode) {
+        JpaUtils.defaultSearchMode = defaultSearchMode;
+    }
+
     public static PageRequest toPageRequest(PageQuery pageQuery) {
         PageRequest pageRequest;
         if (StringUtils.isNotEmpty(pageQuery.getSort())) {
@@ -145,7 +155,7 @@ public class JpaUtils {
             } else if (String.class == fieldType) {
                 SearchableOne annotation = field.getAnnotation(SearchableOne.class);
                 if (annotation != null && annotation.value()) {
-                    and.add(criteriaBuilder.like(root.get(field.getName()), "%" + value + "%"));
+                    and.add(criteriaBuilder.like(root.get(field.getName()), value + "%"));
                 } else {
                     and.add(criteriaBuilder.and(criteriaBuilder.equal(root.get(property), value)));
                 }
@@ -171,8 +181,25 @@ public class JpaUtils {
                     continue;
                 }
 
+                SearchMode searchMode = annotation.mode();
+                if (searchMode == SearchMode.CONFIG) {
+                    searchMode = defaultSearchMode;
+                }
                 if (field.getType() == String.class) {
-                    or.add(criteriaBuilder.like(root.get(field.getName()), "%" + pageQuery.getSearch() + "%"));
+                    switch (searchMode) {
+                        case PREFIX:
+                            or.add(criteriaBuilder.like(root.get(field.getName()), pageQuery.getSearch() + "%"));
+                            break;
+                        case SUFFIX:
+                            or.add(criteriaBuilder.like(root.get(field.getName()), "%" + pageQuery.getSearch()));
+                            break;
+                        case FULL:
+                            or.add(criteriaBuilder.like(root.get(field.getName()), "%" + pageQuery.getSearch() + "%"));
+                            break;
+                        case EXACT:
+                            or.add(criteriaBuilder.equal(root.get(field.getName()), pageQuery.getSearch()));
+                            break;
+                    }
                 } else if (field.getType() == Long.class || field.getType() == long.class) {
                     try {
                         or.add(criteriaBuilder.equal(root.get(field.getName()), Long.parseLong(pageQuery.getSearch())));

+ 2 - 0
src/main/java/com/izouma/nineth/web/RecommendController.java

@@ -9,6 +9,7 @@ import com.izouma.nineth.service.RecommendService;
 import com.izouma.nineth.utils.ObjUtils;
 import com.izouma.nineth.utils.excel.ExcelUtils;
 import lombok.AllArgsConstructor;
+import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.data.domain.Page;
 import org.springframework.web.bind.annotation.*;
 
@@ -51,6 +52,7 @@ public class RecommendController extends BaseController {
         return recommendRepo.findById(id).orElseThrow(new BusinessException("无记录"));
     }
 
+    @CacheEvict(value = "recommend", key = "#id")
     @PostMapping("/del/{id}")
     public void del(@PathVariable Long id) {
         recommendRepo.deleteById(id);

+ 19 - 3
src/main/java/com/izouma/nineth/web/SysConfigController.java

@@ -1,5 +1,8 @@
 package com.izouma.nineth.web;
 
+import com.alibaba.fastjson.JSONObject;
+import com.izouma.nineth.config.EventNames;
+import com.izouma.nineth.config.GeneralProperties;
 import com.izouma.nineth.domain.SysConfig;
 import com.izouma.nineth.dto.PageQuery;
 import com.izouma.nineth.exception.BusinessException;
@@ -7,6 +10,7 @@ import com.izouma.nineth.repo.SysConfigRepo;
 import com.izouma.nineth.service.SysConfigService;
 import com.izouma.nineth.utils.excel.ExcelUtils;
 import lombok.AllArgsConstructor;
+import org.apache.rocketmq.spring.core.RocketMQTemplate;
 import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.data.domain.Page;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -21,14 +25,26 @@ import java.util.List;
 @RequestMapping("/sysConfig")
 @AllArgsConstructor
 public class SysConfigController extends BaseController {
-    private SysConfigService sysConfigService;
-    private SysConfigRepo    sysConfigRepo;
+    private SysConfigService  sysConfigService;
+    private SysConfigRepo     sysConfigRepo;
+    private RocketMQTemplate  rocketMQTemplate;
+    private GeneralProperties generalProperties;
 
     @PreAuthorize("hasRole('ADMIN')")
     @PostMapping("/save")
     @CacheEvict(value = {"SysConfigServiceGetBigDecimal", "SysConfigServiceGetTime", "SysConfigServiceGetBoolean", "SysConfigServiceGetInt"}, allEntries = true)
     public SysConfig save(@RequestBody SysConfig record) {
-        return sysConfigRepo.save(record);
+        record = sysConfigRepo.save(record);
+
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("name", EventNames.CONFIG_CHANGE);
+        JSONObject data = new JSONObject();
+        data.put("name", record.getName());
+        data.put("value", record.getValue());
+        jsonObject.put("data", data);
+        rocketMQTemplate.convertAndSend(generalProperties.getBroadcastEventTopic(), jsonObject);
+
+        return record;
     }
 
 

+ 3 - 1
src/main/vue/src/views/BannerEdit.vue

@@ -54,6 +54,7 @@
                     </el-form-item>
                     <el-form-item prop="linkContent" label="跳转内容" v-if="formData.link">
                         <el-input v-if="formData.linkType === 'collections'" v-model="formData.linkContent" placeholder="输入藏品名称"></el-input>
+                        <el-input v-else-if="formData.linkType === 'hyperlink'" v-model="formData.linkContent" placeholder="输入链接"></el-input>
                         <el-input v-else v-model="formData.linkContent" placeholder="输入ID"></el-input>
                     </el-form-item>
                     <el-form-item class="form-submit">
@@ -141,7 +142,8 @@ export default {
                 { label: '藏品/盲盒', value: 'collection' },
                 { label: '铸造者', value: 'user' },
                 { label: '活动', value: 'activity' },
-                { label: '多个藏品', value: 'collections' }
+                { label: '多个藏品', value: 'collections' },
+                { label: '指定链接', value: 'hyperlink' }
             ]
         };
     },

+ 2 - 1
src/main/vue/src/views/BannerList.vue

@@ -120,7 +120,8 @@ export default {
                 { label: '藏品/盲盒', value: 'collection' },
                 { label: '铸造者', value: 'user' },
                 { label: '活动', value: 'activity' },
-                { label: '多个藏品', value: 'collections' }
+                { label: '多个藏品', value: 'collections' },
+                { label: '指定链接', value: 'hyperlink' }
             ]
         };
     },

+ 14 - 1
src/main/vue/src/views/BlindBoxEdit.vue

@@ -191,9 +191,22 @@
                     </el-form-item>
 
                     <el-form-item prop="holdDays" label="持有天数">
-                        <el-input-number type="number" :min="0" :step="1" :max="2147483647" v-model="formData.holdDays" style="width: 180px"></el-input-number>
+                        <el-input-number
+                            type="number"
+                            :min="0"
+                            :step="1"
+                            :max="2147483647"
+                            v-model="formData.holdDays"
+                            style="width: 180px"
+                        ></el-input-number>
                         <div class="tip">持有多少天可转赠/转让。为空时,按系统设置天数</div>
                     </el-form-item>
+
+                    <el-form-item prop="minimumCharge" label="最低消费">
+                        <el-input-number type="number" :min="0" v-model="formData.minimumCharge" style="width: 180px">
+                        </el-input-number>
+                    </el-form-item>
+
                     <el-form-item prop="noSoldOut" label="售罄">
                         <el-radio v-model="formData.noSoldOut" :label="false">是</el-radio>
                         <el-radio v-model="formData.noSoldOut" :label="true">否</el-radio>

+ 9 - 3
src/main/vue/src/views/CollectionEdit.vue

@@ -238,6 +238,12 @@
                         ></el-input-number>
                         <div class="tip">持有多少天可转赠/转让。为空时,按系统设置天数。</div>
                     </el-form-item>
+
+                    <el-form-item prop="minimumCharge" label="最低消费">
+                        <el-input-number type="number" :min="0" v-model="formData.minimumCharge" style="width: 180px">
+                        </el-input-number>
+                    </el-form-item>
+
                     <el-form-item prop="noSoldOut" label="售罄">
                         <el-radio v-model="formData.noSoldOut" :label="false">是</el-radio>
                         <el-radio v-model="formData.noSoldOut" :label="true">否</el-radio>
@@ -248,13 +254,13 @@
                             <el-radio :label="false">支付宝/微信</el-radio>
                         </el-radio-group>
                     </el-form-item>
-                    
-                    <el-form-item prop="vip" label="享有特权">
+
+                    <!-- <el-form-item prop="vip" label="享有特权">
                         <el-radio-group v-model="formData.vip">
                             <el-radio :label="true">白名单权利</el-radio>
                             <el-radio :label="false">无特权</el-radio>
                         </el-radio-group>
-                    </el-form-item>
+                    </el-form-item> -->
 
                     <div class="inline-wrapper">
                         <el-form-item prop="assignment" label="拉新任务指标">