xiongzhu před 4 roky
rodič
revize
7e8332d223
27 změnil soubory, kde provedl 936 přidání a 43 odebrání
  1. 61 0
      ci.gocd.yaml
  2. 32 0
      src/main/java/com/izouma/dangjian/domain/BusinessReq.java
  3. 1 1
      src/main/java/com/izouma/dangjian/domain/Commission.java
  4. 20 2
      src/main/java/com/izouma/dangjian/domain/Order.java
  5. 4 0
      src/main/java/com/izouma/dangjian/domain/User.java
  6. 57 0
      src/main/java/com/izouma/dangjian/dto/OrderImport.java
  7. 15 0
      src/main/java/com/izouma/dangjian/enums/OrderStatus.java
  8. 16 0
      src/main/java/com/izouma/dangjian/repo/BusinessReqRepo.java
  9. 1 0
      src/main/java/com/izouma/dangjian/security/WebSecurityConfig.java
  10. 63 0
      src/main/java/com/izouma/dangjian/service/BusinessReqService.java
  11. 4 3
      src/main/java/com/izouma/dangjian/utils/excel/ExcelUtils.java
  12. 42 0
      src/main/java/com/izouma/dangjian/utils/excel/OrderStatusConverter.java
  13. 54 0
      src/main/java/com/izouma/dangjian/web/BusinessReqController.java
  14. 2 1
      src/main/mobile/src/main.js
  15. 4 0
      src/main/mobile/src/views/article.vue
  16. 74 4
      src/main/mobile/src/views/home.vue
  17. 1 0
      src/main/resources/genjson/BusinessReq.json
  18. 32 0
      src/main/vue/src/components/RichText.vue
  19. 3 0
      src/main/vue/src/mixins/pageableTable.js
  20. 16 0
      src/main/vue/src/router.js
  21. 117 0
      src/main/vue/src/views/BusinessReqEdit.vue
  22. 166 0
      src/main/vue/src/views/BusinessReqList.vue
  23. 1 1
      src/main/vue/src/views/CommissionEdit.vue
  24. 39 6
      src/main/vue/src/views/OrderEdit.vue
  25. 65 10
      src/main/vue/src/views/OrderList.vue
  26. 42 3
      src/main/vue/src/views/UserEdit.vue
  27. 4 12
      src/main/vue/src/views/UserList.vue

+ 61 - 0
ci.gocd.yaml

@@ -0,0 +1,61 @@
+environments:
+  example:
+    environment_variables:
+      EXAMPLE_DEPLOYMENT: testing
+    pipelines:
+      - yaml-example
+pipelines:
+  yamlpipe1:
+    group: defaultGroup
+    materials:
+      dangjian: # this is the name of material
+        # says about type of material and url at once
+        git: http://git.izouma.com/xiongzhu/dangjian.git
+    stages:
+      - build: # name of stage
+          jobs:
+            build: # name of the job
+              tasks:
+                - exec: # indicates type of task
+                    command: make
+  "yaml-example": # definition of yaml-example pipeline
+    group: defaultGroup
+    label_template: "${dangjian[:8]}"
+    locking: off
+    materials:
+      mygit: # this is the name of material
+        # keyword git says about type of material and url at once
+        git: http://git.izouma.com/xiongzhu/dangjian.git
+        branch: ci
+      upstream:
+        # type is optional here, material type is implied based on presence of pipeline and stage fields
+        # type: dependency
+        pipeline: yamlpipe1
+        stage: build
+    stages: # list of stages in order
+      - build: # name of stage
+          clean_workspace: true
+          jobs:
+            csharp: # name of the job
+              resources:
+                - net45
+              artifacts:
+                - build:
+                    source: bin/
+                    destination: build
+                - test:
+                    source: tests/
+                    destination: test-reports/
+              tabs:
+                report: test-reports/index.html
+              tasks: # ordered list of tasks to execute in job csharp
+                - fetch:
+                    pipeline: yamlpipe1
+                    stage: build
+                    job: build
+                    source: test-bin/
+                    destination: bin/
+                - exec: # indicates type of task
+                    command: make
+                    arguments:
+                      - "VERBOSE=true"

+ 32 - 0
src/main/java/com/izouma/dangjian/domain/BusinessReq.java

@@ -0,0 +1,32 @@
+package com.izouma.dangjian.domain;
+
+import com.izouma.dangjian.annotations.Searchable;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Entity;
+
+@Data
+@Entity
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class BusinessReq extends BaseEntity {
+
+    private Long userId;
+
+    private Long invitor;
+
+    @Searchable
+    private String contactName;
+
+    @Searchable
+    private String phone;
+
+    @Searchable
+    private String org;
+
+    private String remark;
+}

+ 1 - 1
src/main/java/com/izouma/dangjian/domain/Commission.java

@@ -31,7 +31,7 @@ public class Commission extends BaseEntity {
     @ApiModelProperty("佣金金额")
     private BigDecimal commissionMoney;
 
-    @ApiModelProperty("返佣比例")
+    @ApiModelProperty("返佣完成")
     private boolean commissionFinish;
 
     @ApiModelProperty("开票")

+ 20 - 2
src/main/java/com/izouma/dangjian/domain/Order.java

@@ -1,13 +1,15 @@
 package com.izouma.dangjian.domain;
 
+import com.izouma.dangjian.converter.FileObjectConverter;
+import com.izouma.dangjian.enums.OrderStatus;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
-import javax.persistence.Entity;
-import javax.persistence.Table;
+import javax.persistence.*;
+import java.math.BigDecimal;
 
 @Data
 @Entity
@@ -17,6 +19,17 @@ import javax.persistence.Table;
 @Builder
 public class Order extends BaseEntity {
 
+    private String org;
+
+    private String account;
+
+    private BigDecimal money;
+
+    private String transactionNo;
+
+    @Enumerated(EnumType.STRING)
+    private OrderStatus status;
+
     @ApiModelProperty("物流公司")
     private String logisticsName;
 
@@ -40,4 +53,9 @@ public class Order extends BaseEntity {
 
     @ApiModelProperty("发货地址")
     private String fromAddress;
+
+    @Convert(converter = FileObjectConverter.class)
+    private FileObject attach;
+
+    private String sku;
 }

+ 4 - 0
src/main/java/com/izouma/dangjian/domain/User.java

@@ -80,4 +80,8 @@ public class User extends BaseEntity implements Serializable {
     private String address;
 
     private Long invitor;
+
+    private String org;
+
+    private String req;
 }

+ 57 - 0
src/main/java/com/izouma/dangjian/dto/OrderImport.java

@@ -0,0 +1,57 @@
+package com.izouma.dangjian.dto;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.izouma.dangjian.converter.FileObjectConverter;
+import com.izouma.dangjian.domain.FileObject;
+import com.izouma.dangjian.enums.OrderStatus;
+import io.swagger.annotations.ApiModelProperty;
+
+import javax.persistence.Convert;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import java.math.BigDecimal;
+
+public class OrderImport {
+
+    @ExcelProperty("公司名称")
+    private String org;
+
+    @ExcelProperty("交易金额")
+    private BigDecimal money;
+
+    @ExcelProperty("流水号")
+    private String transactionNo;
+
+    @ExcelProperty("交易账户")
+    private String account;
+
+    @ExcelProperty("联系人")
+    private String name;
+
+    @ExcelProperty("电话")
+    private String phone;
+
+    @ExcelProperty("订单状态")
+    private OrderStatus status;
+
+    @ExcelProperty("物流公司")
+    private String logisticsName;
+
+    @ExcelProperty("物流编号")
+    private String logisticsNo;
+
+    @ExcelProperty("地址")
+    private String address;
+
+    @ExcelProperty("录单员")
+    private String operator;
+
+    @ExcelProperty("用户")
+    private Long userId;
+
+    @ExcelProperty("发货地址")
+    private String fromAddress;
+
+    @ExcelProperty("商品sku")
+    private String sku;
+}

+ 15 - 0
src/main/java/com/izouma/dangjian/enums/OrderStatus.java

@@ -0,0 +1,15 @@
+package com.izouma.dangjian.enums;
+
+public enum OrderStatus {
+    FINISH("已完成"),
+    CANCEL("已取消");
+    private final String description;
+
+    OrderStatus(String description) {
+        this.description = description;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+}

+ 16 - 0
src/main/java/com/izouma/dangjian/repo/BusinessReqRepo.java

@@ -0,0 +1,16 @@
+package com.izouma.dangjian.repo;
+
+import com.izouma.dangjian.domain.BusinessReq;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+
+import javax.transaction.Transactional;
+
+public interface BusinessReqRepo extends JpaRepository<BusinessReq, Long>, JpaSpecificationExecutor<BusinessReq> {
+    @Query("update BusinessReq t set t.del = true where t.id = ?1")
+    @Modifying
+    @Transactional
+    void softDelete(Long id);
+}

+ 1 - 0
src/main/java/com/izouma/dangjian/security/WebSecurityConfig.java

@@ -85,6 +85,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
                 .antMatchers("/visitStat/**").permitAll()
                 .antMatchers("/user/registerPhone").permitAll()
                 .antMatchers("/user/resetPassword").permitAll()
+                .antMatchers("/businessReq/save").permitAll()
                 // all other requests need to be authenticated
                 .anyRequest().authenticated().and()
                 // make sure we use stateless session; session won't be used to

+ 63 - 0
src/main/java/com/izouma/dangjian/service/BusinessReqService.java

@@ -0,0 +1,63 @@
+package com.izouma.dangjian.service;
+
+import com.izouma.dangjian.config.Constants;
+import com.izouma.dangjian.domain.BusinessReq;
+import com.izouma.dangjian.domain.User;
+import com.izouma.dangjian.dto.PageQuery;
+import com.izouma.dangjian.exception.BusinessException;
+import com.izouma.dangjian.repo.BusinessReqRepo;
+import com.izouma.dangjian.repo.UserRepo;
+import com.izouma.dangjian.security.Authority;
+import com.izouma.dangjian.security.JwtTokenUtil;
+import com.izouma.dangjian.security.JwtUserFactory;
+import com.izouma.dangjian.utils.JpaUtils;
+import com.izouma.dangjian.utils.ObjUtils;
+import com.izouma.dangjian.utils.SecurityUtils;
+import lombok.AllArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.stereotype.Service;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+@Service
+@AllArgsConstructor
+public class BusinessReqService {
+
+    private BusinessReqRepo businessReqRepo;
+    private UserRepo        userRepo;
+    private JwtTokenUtil    jwtTokenUtil;
+
+    public Page<BusinessReq> all(PageQuery pageQuery) {
+        return businessReqRepo
+                .findAll(JpaUtils.toSpecification(pageQuery, BusinessReq.class), JpaUtils.toPageRequest(pageQuery));
+    }
+
+    public Object save(@RequestBody BusinessReq record) {
+        Map<String, Object> map = new HashMap<>();
+        User user = SecurityUtils.getAuthenticatedUser();
+        if (user == null) {
+            user = userRepo.findByPhoneAndDelFalse(record.getPhone());
+            if (user == null) {
+                user = User.builder()
+                        .username(record.getPhone())
+                        .nickname(record.getPhone())
+                        .phone(record.getPhone())
+                        .authorities(Collections.singleton(Authority.builder().name("ROLE_USER").build()))
+                        .avatar(Constants.DEFAULT_AVATAR)
+                        .invitor(record.getInvitor())
+                        .org(record.getOrg())
+                        .req(record.getRemark())
+                        .build();
+            }
+        }
+        user = userRepo.save(user);
+        map.put("token", jwtTokenUtil.generateToken(JwtUserFactory.create(user)));
+        record.setUserId(user.getId());
+        businessReqRepo.save(record);
+        return map;
+    }
+}

+ 4 - 3
src/main/java/com/izouma/dangjian/utils/excel/ExcelUtils.java

@@ -16,8 +16,9 @@ public class ExcelUtils<T> {
         response.setCharacterEncoding("utf-8");
         response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
         EasyExcel.write(response.getOutputStream(), data.get(0).getClass()).sheet("sheet")
-                 .registerConverter(new LocalDateConverter())
-                 .registerConverter(new LocalDateTimeConverter())
-                 .doWrite(data);
+                .registerConverter(new LocalDateConverter())
+                .registerConverter(new LocalDateTimeConverter())
+                .registerConverter(new OrderStatusConverter())
+                .doWrite(data);
     }
 }

+ 42 - 0
src/main/java/com/izouma/dangjian/utils/excel/OrderStatusConverter.java

@@ -0,0 +1,42 @@
+package com.izouma.dangjian.utils.excel;
+
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.CellData;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+import com.izouma.dangjian.enums.OrderStatus;
+import org.apache.commons.lang3.StringUtils;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+
+public class OrderStatusConverter implements Converter<OrderStatus> {
+    @Override
+    public Class supportJavaTypeKey() {
+        return OrderStatus.class;
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return CellDataTypeEnum.STRING;
+    }
+
+    @Override
+    public OrderStatus convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
+        if (OrderStatus.FINISH.getDescription().equals(cellData.getStringValue())) {
+            return OrderStatus.FINISH;
+        } else if (OrderStatus.CANCEL.getDescription().equals(cellData.getStringValue())) {
+            return OrderStatus.CANCEL;
+        }
+        return null;
+    }
+
+    @Override
+    public CellData convertToExcelData(OrderStatus orderStatus, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
+        if (orderStatus != null) {
+            return new CellData(orderStatus.getDescription());
+        }
+        return null;
+    }
+}

+ 54 - 0
src/main/java/com/izouma/dangjian/web/BusinessReqController.java

@@ -0,0 +1,54 @@
+package com.izouma.dangjian.web;
+import com.izouma.dangjian.domain.BusinessReq;
+import com.izouma.dangjian.service.BusinessReqService;
+import com.izouma.dangjian.dto.PageQuery;
+import com.izouma.dangjian.exception.BusinessException;
+import com.izouma.dangjian.repo.BusinessReqRepo;
+import com.izouma.dangjian.utils.ObjUtils;
+import com.izouma.dangjian.utils.excel.ExcelUtils;
+import lombok.AllArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+
+@RestController
+@RequestMapping("/businessReq")
+@AllArgsConstructor
+public class BusinessReqController extends BaseController {
+    private BusinessReqService businessReqService;
+    private BusinessReqRepo businessReqRepo;
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/save")
+    public Object save(@RequestBody BusinessReq record) {
+        return businessReqService.save(record);
+    }
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/all")
+    public Page<BusinessReq> all(@RequestBody PageQuery pageQuery) {
+        return businessReqService.all(pageQuery);
+    }
+
+    @GetMapping("/get/{id}")
+    public BusinessReq get(@PathVariable Long id) {
+        return businessReqRepo.findById(id).orElseThrow(new BusinessException("无记录"));
+    }
+
+    @PostMapping("/del/{id}")
+    public void del(@PathVariable Long id) {
+        businessReqRepo.softDelete(id);
+    }
+
+    @GetMapping("/excel")
+    @ResponseBody
+    public void excel(HttpServletResponse response, PageQuery pageQuery) throws IOException {
+        List<BusinessReq> data = all(pageQuery).getContent();
+        ExcelUtils.export(response, data);
+    }
+}
+

+ 2 - 1
src/main/mobile/src/main.js

@@ -49,8 +49,9 @@ const vm = new Vue({
     render: h => h(App)
 }).$mount('#app');
 store.dispatch('updateUserInfo');
-let invitor = new URLSearchParams(window.location.search).get('invitor');
+let invitor = new URLSearchParams(window.location.search).get('invitor') || localStorage.getItem('invitor');
 if (invitor) {
+    localStorage.getItem('invitor', invitor);
     invitor = invitor.replace(/\/$/, '');
     store.commit('setInvitor', invitor);
     vm.$http.get('/visitStat/add', { userId: invitor });

+ 4 - 0
src/main/mobile/src/views/article.vue

@@ -27,5 +27,9 @@ export default {
         width: 100%;
         height: auto;
     }
+    /deep/ video {
+        width: 100% !important;
+        height: auto !important;
+    }
 }
 </style>

+ 74 - 4
src/main/mobile/src/views/home.vue

@@ -9,7 +9,7 @@
             </van-swipe-item>
         </van-swipe>
         <div class="menus">
-            <div class="menu" @click="contact">
+            <div class="menu" @click="showContactDialog = true">
                 <img src="../assets/shakehand.png" class="icon" />
                 <div class="title">商务对接</div>
             </div>
@@ -17,10 +17,10 @@
                 <img src="../assets/promote.png" class="icon" />
                 <div class="title">我要推广</div>
             </div>
-            <div class="menu" @click="about">
+            <!-- <div class="menu" @click="about">
                 <img src="../assets/contact.png" class="icon" />
                 <div class="title">关于我们</div>
-            </div>
+            </div> -->
         </div>
         <div class="promote" v-if="showPromote">
             <div class="sub-title">MR智慧党建产品限时推广</div>
@@ -59,6 +59,51 @@
         <div class="placeholder"></div>
         <img src="../assets/top.png" class="top" @click="top" v-if="showTop" />
         <promote-dialog :visible.sync="showDialog"></promote-dialog>
+
+        <van-dialog v-model="showContactDialog" :show-confirm-button="false" close-on-click-overlay>
+            <van-form @submit="onSubmit">
+                <h4 style="text-align: center">商务对接</h4>
+                <van-field
+                    v-model="form.contactName"
+                    name="联系人"
+                    label="联系人"
+                    placeholder="联系人"
+                    :rules="[{ required: true, message: '请填写联系人' }]"
+                />
+                <van-field
+                    v-model="form.phone"
+                    type="tel"
+                    name="手机号"
+                    label="手机号"
+                    placeholder="手机号"
+                    :rules="[
+                        { required: true, message: '请填写手机号' },
+                        { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号' }
+                    ]"
+                />
+                <van-field
+                    v-model="form.org"
+                    name="公司名称"
+                    label="公司名称"
+                    placeholder="公司名称"
+                    :rules="[{ required: true, message: '请填写公司名称' }]"
+                />
+                <van-field v-model="form.remark" name="需求描述" label="需求描述" placeholder="需求描述" />
+                <div style="margin: 16px">
+                    <van-button
+                        round
+                        block
+                        type="info"
+                        native-type="submit"
+                        :loading="loading"
+                        :color="$theme.prim"
+                        :disabled="loading"
+                    >
+                        提交
+                    </van-button>
+                </div>
+            </van-form>
+        </van-dialog>
     </div>
 </template>
 <script>
@@ -80,7 +125,15 @@ export default {
             start: null,
             end: null,
             showDialog: false,
-            showTop: false
+            showTop: false,
+            showContactDialog: false,
+            form: {
+                contactName: '',
+                phone: '',
+                org: '',
+                remark: ''
+            },
+            loading: false
         };
     },
     created() {
@@ -189,6 +242,19 @@ export default {
             } else {
                 this.showTop = false;
             }
+        },
+        onSubmit() {
+            this.loading = true;
+            this.$http
+                .post('/businessReq/save', { ...this.form, invitor: this.$store.state.invitor }, { body: 'json' })
+                .then(res => {
+                    this.loading = false;
+                    this.showContactDialog = false;
+                    this.$toast('已提交信息');
+                })
+                .catch(e => {
+                    this.loading = false;
+                });
         }
     }
 };
@@ -283,6 +349,10 @@ export default {
         width: 100% !important;
         height: auto !important;
     }
+    /deep/ video {
+        width: 100% !important;
+        height: auto !important;
+    }
 }
 .more {
     padding: 10px 11px;

+ 1 - 0
src/main/resources/genjson/BusinessReq.json

@@ -0,0 +1 @@
+{"tableName":"BusinessReq","className":"BusinessReq","remark":"商务对接","genTable":true,"genClass":true,"genList":true,"genForm":true,"genRouter":true,"javaPath":"/Users/drew/Projects/Java/dangjian/src/main/java/com/izouma/dangjian","viewPath":"/Users/drew/Projects/Java/dangjian/src/main/vue/src/views","routerPath":"/Users/drew/Projects/Java/dangjian/src/main/vue/src","resourcesPath":"/Users/drew/Projects/Java/dangjian/src/main/resources","dataBaseType":"Mysql","fields":[{"name":"userId","modelName":"userId","remark":"用户ID","showInList":true,"showInForm":true,"formType":"number"},{"name":"contactName","modelName":"contactName","remark":"联系人","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"phone","modelName":"phone","remark":"手机","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"org","modelName":"org","remark":"公司","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"remark","modelName":"remark","remark":"需求描述","showInList":true,"showInForm":true,"formType":"singleLineText"}],"readTable":false,"dataSourceCode":"dataSource","genJson":"","subtables":[],"update":false,"basePackage":"com.izouma.dangjian","tablePackage":"com.izouma.dangjian.domain.BusinessReq"}

+ 32 - 0
src/main/vue/src/components/RichText.vue

@@ -51,6 +51,38 @@ export default {
                     'insertdatetime media table contextmenu paste code help imagetools'
                 ],
                 images_upload_url: this.$baseUrl + '/upload/file',
+                media_upload_url: this.$baseUrl + '/upload/file',
+                imagetools_cors_hosts: ['localhost', '192.168.50.210:8081', 'aliyuncs.com'],
+                imagetools_credentials_hosts: ['aliyuncs.com'],
+                file_picker_types: 'media',
+                relative_urls: false,
+                remove_script_host: false,
+                convert_urls: true,
+                file_picker_callback: (cb, value, meta) => {
+                    var input = document.createElement('input');
+                    input.setAttribute('type', 'file');
+                    input.setAttribute('accept', 'video/*');
+                    input.onchange = e => {
+                        var file = input.files[0];
+
+                        var reader = new FileReader();
+                        reader.readAsDataURL(file);
+                        reader.onload = () => {
+                            let formData = new FormData();
+                            formData.append('file', file);
+                            this.$axios
+                                .post('/upload/file', formData)
+                                .then(res => {
+                                    cb(res.data);
+                                })
+                                .catch(e => {
+                                    console.log(e);
+                                });
+                        };
+                    };
+
+                    input.click();
+                },
                 images_upload_handler: (blobInfo, success, failure) => {
                     let formData = new FormData();
                     formData.append('file', blobInfo.blob(), blobInfo.filename());

+ 3 - 0
src/main/vue/src/mixins/pageableTable.js

@@ -12,6 +12,9 @@ export default {
         };
     },
     created() {
+        if (this.beforeCreated) {
+            this.beforeCreated();
+        }
         this.page = Number(this.$route.query.page) || 1;
         if (this.$route.query.sort) {
             let sort = {};

+ 16 - 0
src/main/vue/src/router.js

@@ -182,6 +182,22 @@ const router = new Router({
                     meta: {
                         title: '佣金管理'
                     }
+                },
+                {
+                    path: '/businessReqEdit',
+                    name: 'BusinessReqEdit',
+                    component: () => import(/* webpackChunkName: "businessReqEdit" */ '@/views/BusinessReqEdit.vue'),
+                    meta: {
+                        title: '商务对接编辑'
+                    }
+                },
+                {
+                    path: '/businessReqList',
+                    name: 'BusinessReqList',
+                    component: () => import(/* webpackChunkName: "businessReqList" */ '@/views/BusinessReqList.vue'),
+                    meta: {
+                        title: '商务对接'
+                    }
                 }
                 /**INSERT_LOCATION**/
             ]

+ 117 - 0
src/main/vue/src/views/BusinessReqEdit.vue

@@ -0,0 +1,117 @@
+<template>
+    <div class="edit-view">
+        <page-title>
+            <el-button @click="$router.go(-1)">取消</el-button>
+            <el-button @click="del" :loading="$store.state.fetchingData" type="danger" v-if="formData.id">
+                删除
+            </el-button>
+            <el-button @click="onSave" :loading="$store.state.fetchingData" type="primary">保存</el-button>
+        </page-title>
+        <div class="edit-view__content-wrapper">
+            <div class="edit-view__content-section">
+                <el-form
+                    :model="formData"
+                    :rules="rules"
+                    ref="form"
+                    label-width="80px"
+                    label-position="right"
+                    size="small"
+                    style="max-width: 500px;"
+                >
+                    <el-form-item prop="userId" label="用户ID">
+                        <el-input-number type="number" v-model="formData.userId"></el-input-number>
+                    </el-form-item>
+                    <el-form-item prop="contactName" label="联系人">
+                        <el-input v-model="formData.contactName"></el-input>
+                    </el-form-item>
+                    <el-form-item prop="phone" label="手机">
+                        <el-input v-model="formData.phone"></el-input>
+                    </el-form-item>
+                    <el-form-item prop="org" label="公司">
+                        <el-input v-model="formData.org"></el-input>
+                    </el-form-item>
+                    <el-form-item prop="remark" label="需求描述">
+                        <el-input v-model="formData.remark"></el-input>
+                    </el-form-item>
+                    <el-form-item class="form-submit">
+                        <el-button @click="onSave" :loading="saving" type="primary">保存 </el-button>
+                        <el-button @click="onDelete" :loading="saving" type="danger" v-if="formData.id"
+                            >删除
+                        </el-button>
+                        <el-button @click="$router.go(-1)">取消</el-button>
+                    </el-form-item>
+                </el-form>
+            </div>
+        </div>
+    </div>
+</template>
+<script>
+export default {
+    name: 'BusinessReqEdit',
+    created() {
+        if (this.$route.query.id) {
+            this.$http
+                .get('businessReq/get/' + this.$route.query.id)
+                .then(res => {
+                    this.formData = res;
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.$message.error(e.error);
+                });
+        }
+    },
+    data() {
+        return {
+            saving: false,
+            formData: {},
+            rules: {}
+        };
+    },
+    methods: {
+        onSave() {
+            this.$refs.form.validate(valid => {
+                if (valid) {
+                    this.submit();
+                } else {
+                    return false;
+                }
+            });
+        },
+        submit() {
+            let data = { ...this.formData };
+
+            this.saving = true;
+            this.$http
+                .post('/businessReq/save', data, { body: 'json' })
+                .then(res => {
+                    this.saving = false;
+                    this.$message.success('成功');
+                    this.$router.go(-1);
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.saving = false;
+                    this.$message.error(e.error);
+                });
+        },
+        onDelete() {
+            this.$alert('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
+                .then(() => {
+                    return this.$http.post(`/businessReq/del/${this.formData.id}`);
+                })
+                .then(() => {
+                    this.$message.success('删除成功');
+                    this.$router.go(-1);
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
+                        console.log(e);
+                        this.$message.error((e || {}).error || '删除失败');
+                    }
+                });
+        }
+    }
+};
+</script>
+<style lang="less" scoped></style>

+ 166 - 0
src/main/vue/src/views/BusinessReqList.vue

@@ -0,0 +1,166 @@
+<template>
+    <div class="list-view">
+        <page-title>
+            <el-button @click="addRow" type="primary" icon="el-icon-plus" :loading="downloading" class="filter-item">
+                新增
+            </el-button>
+            <el-button @click="download" icon="el-icon-upload2" :loading="downloading" class="filter-item">
+                导出
+            </el-button>
+        </page-title>
+        <div class="filters-container">
+            <el-input
+                placeholder="搜索..."
+                v-model="search"
+                clearable
+                class="filter-item search"
+                @keyup.enter.native="getData"
+            >
+                <el-button @click="getData" slot="append" icon="el-icon-search"> </el-button>
+            </el-input>
+        </div>
+        <el-table
+            :data="tableData"
+            row-key="id"
+            ref="table"
+            header-row-class-name="table-header-row"
+            header-cell-class-name="table-header-cell"
+            row-class-name="table-row"
+            cell-class-name="table-cell"
+            :height="tableHeight"
+        >
+            <el-table-column v-if="multipleMode" align="center" type="selection" width="50"> </el-table-column>
+            <el-table-column prop="id" label="ID" width="100"> </el-table-column>
+            <!-- <el-table-column prop="userId" label="用户ID"> </el-table-column> -->
+            <el-table-column prop="contactName" label="联系人"> </el-table-column>
+            <el-table-column prop="phone" label="手机"> </el-table-column>
+            <el-table-column prop="org" label="公司"> </el-table-column>
+            <el-table-column prop="remark" label="需求描述" show-overflow-tooltip> </el-table-column>
+            <el-table-column label="操作" align="center" fixed="right" min-width="150">
+                <template slot-scope="{ row }">
+                    <el-button @click="editRow(row)" type="primary" size="mini" plain>编辑</el-button>
+                    <el-button @click="deleteRow(row)" type="danger" size="mini" plain>删除</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div class="pagination-wrapper">
+            <!-- <div class="multiple-mode-wrapper">
+                <el-button v-if="!multipleMode" @click="toggleMultipleMode(true)">批量编辑</el-button>
+                <el-button-group v-else>
+                    <el-button @click="operation1">批量操作1</el-button>
+                    <el-button @click="operation2">批量操作2</el-button>
+                    <el-button @click="toggleMultipleMode(false)">取消</el-button>
+                </el-button-group>
+            </div> -->
+            <el-pagination
+                background
+                @size-change="onSizeChange"
+                @current-change="onCurrentChange"
+                :current-page="page"
+                :page-sizes="[10, 20, 30, 40, 50]"
+                :page-size="pageSize"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="totalElements"
+            >
+            </el-pagination>
+        </div>
+    </div>
+</template>
+<script>
+import { mapState } from 'vuex';
+import pageableTable from '@/mixins/pageableTable';
+
+export default {
+    name: 'BusinessReqList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/businessReq/all',
+            downloading: false
+        };
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    methods: {
+        beforeGetData() {
+            return { search: this.search };
+        },
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
+            }
+        },
+        addRow() {
+            this.$router.push({
+                path: '/businessReqEdit',
+                query: {
+                    ...this.$route.query
+                }
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: '/businessReqEdit',
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/businessReq/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000 }
+                })
+                .then(res => {
+                    console.log(res);
+                    this.downloading = false;
+                    const downloadUrl = window.URL.createObjectURL(new Blob([res.data]));
+                    const link = document.createElement('a');
+                    link.href = downloadUrl;
+                    link.setAttribute('download', res.headers['content-disposition'].split('filename=')[1]);
+                    document.body.appendChild(link);
+                    link.click();
+                    link.remove();
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.downloading = false;
+                    this.$message.error(e.error);
+                });
+        },
+        operation1() {
+            this.$notify({
+                title: '提示',
+                message: this.selection
+            });
+        },
+        operation2() {
+            this.$message('操作2');
+        },
+        deleteRow(row) {
+            this.$alert('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
+                .then(() => {
+                    return this.$http.post(`/businessReq/del/${row.id}`);
+                })
+                .then(() => {
+                    this.$message.success('删除成功');
+                    this.getData();
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
+                        this.$message.error(e.error);
+                    }
+                });
+        }
+    }
+};
+</script>
+<style lang="less" scoped></style>

+ 1 - 1
src/main/vue/src/views/CommissionEdit.vue

@@ -42,7 +42,7 @@
                     <el-form-item prop="commissionMoney" label="佣金金额">
                         <el-input-number type="number" v-model="formData.commissionMoney"></el-input-number>
                     </el-form-item>
-                    <el-form-item prop="commissionFinish" label="返佣比例">
+                    <el-form-item prop="commissionFinish" label="返佣完成">
                         <el-switch v-model="formData.commissionFinish"></el-switch>
                     </el-form-item>
                     <el-form-item prop="invoice" label="开票">

+ 39 - 6
src/main/vue/src/views/OrderEdit.vue

@@ -18,18 +18,36 @@
                     size="small"
                     style="max-width: 500px;"
                 >
-                    <el-form-item prop="logisticsName" label="物流公司">
-                        <el-input v-model="formData.logisticsName"></el-input>
+                    <el-form-item prop="org" label="公司名称">
+                        <el-input v-model="formData.org"></el-input>
                     </el-form-item>
-                    <el-form-item prop="logisticsNo" label="物流编号">
-                        <el-input v-model="formData.logisticsNo"></el-input>
+                    <el-form-item prop="money" label="交易金额">
+                        <el-input-number v-model="formData.money"></el-input-number>
+                    </el-form-item>
+                    <el-form-item prop="transactionNo" label="流水号">
+                        <el-input v-model="formData.transactionNo"></el-input>
                     </el-form-item>
-                    <el-form-item prop="name" label="收货人">
+                    <el-form-item prop="account" label="交易账户">
+                        <el-input v-model="formData.account"></el-input>
+                    </el-form-item>
+                    <el-form-item prop="name" label="联系人">
                         <el-input v-model="formData.name"></el-input>
                     </el-form-item>
                     <el-form-item prop="phone" label="电话">
                         <el-input v-model="formData.phone"></el-input>
                     </el-form-item>
+                    <el-form-item prop="status" label="订单状态">
+                        <el-select v-model="formData.status">
+                            <el-option label="已完成" value="FINISH"></el-option>
+                            <el-option label="已取消" value="CANCEL"></el-option>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item prop="logisticsName" label="物流公司">
+                        <el-input v-model="formData.logisticsName"></el-input>
+                    </el-form-item>
+                    <el-form-item prop="logisticsNo" label="物流编号">
+                        <el-input v-model="formData.logisticsNo"></el-input>
+                    </el-form-item>
                     <el-form-item prop="address" label="地址">
                         <el-input v-model="formData.address"></el-input>
                     </el-form-item>
@@ -52,6 +70,15 @@
                     <el-form-item prop="fromAddress" label="发货地址">
                         <el-input v-model="formData.fromAddress"></el-input>
                     </el-form-item>
+                    <el-form-item prop="fromAddress" label="发货地址">
+                        <el-input v-model="formData.fromAddress"></el-input>
+                    </el-form-item>
+                    <el-form-item prop="sku" label="商品sku">
+                        <el-input v-model="formData.fromAddress"></el-input>
+                    </el-form-item>
+                    <el-form-item prop="attach" label="打款凭证">
+                        <file-upload single v-model="formData.attach"></file-upload>
+                    </el-form-item>
                     <el-form-item class="form-submit">
                         <el-button @click="onSave" :loading="saving" type="primary">保存 </el-button>
                         <el-button @click="onDelete" :loading="saving" type="danger" v-if="formData.id"
@@ -85,6 +112,12 @@ export default {
             saving: false,
             formData: {},
             rules: {
+                org: [{ required: true, message: '请输入公司名称', trigger: 'blur' }],
+                money: [{ required: true, message: '请输入交易金额', trigger: 'blur' }],
+                transactionNo: [{ required: true, message: '请输入交易流水号', trigger: 'blur' }],
+                account: [{ required: true, message: '请输入交易账户', trigger: 'blur' }],
+                status: [{ required: true, message: '请选择订单状态', trigger: 'blur' }],
+                sku: [{ required: true, message: '请输入商品sku', trigger: 'blur' }],
                 logisticsName: [
                     {
                         required: true,
@@ -102,7 +135,7 @@ export default {
                 name: [
                     {
                         required: true,
-                        message: '请输入收货人',
+                        message: '请输入联系人',
                         trigger: 'blur'
                     }
                 ],

+ 65 - 10
src/main/vue/src/views/OrderList.vue

@@ -9,6 +9,20 @@
             </el-button>
         </page-title>
         <div class="filters-container">
+            <el-radio-group class="filter-item" v-model="dateRadio" size="small">
+                <el-radio-button :label="1">全部</el-radio-button>
+                <el-radio-button :label="2">上月</el-radio-button>
+                <el-radio-button :label="3">本月</el-radio-button>
+                <el-radio-button :label="4">自定义</el-radio-button>
+            </el-radio-group>
+            <el-date-picker
+                style="vertical-align: middle;"
+                class="filter-item"
+                v-model="date"
+                type="datetimerange"
+                value-format="yyyy-MM-dd HH:mm:ss"
+                :disabled="dateRadio !== 4"
+            ></el-date-picker>
             <el-input
                 placeholder="搜索..."
                 v-model="search"
@@ -31,15 +45,15 @@
         >
             <el-table-column v-if="multipleMode" align="center" type="selection" width="50"> </el-table-column>
             <el-table-column prop="id" label="ID" width="100"> </el-table-column>
-            <el-table-column prop="logisticsName" label="物流公司"> </el-table-column>
-            <el-table-column prop="logisticsNo" label="物流编号"> </el-table-column>
-            <el-table-column prop="name" label="收货人"> </el-table-column>
+            <el-table-column prop="org" label="公司名称"> </el-table-column>
+            <el-table-column prop="money" label="交易金额"> </el-table-column>
+            <el-table-column prop="transactionNo" label="流水号"> </el-table-column>
+            <el-table-column prop="account" label="交易账户"> </el-table-column>
+            <el-table-column prop="name" label="联系人"> </el-table-column>
             <el-table-column prop="phone" label="电话"> </el-table-column>
-            <el-table-column prop="address" label="地址"> </el-table-column>
-            <el-table-column prop="operator" label="录单员"> </el-table-column>
-            <el-table-column prop="userId" label="用户"> </el-table-column>
-            <el-table-column prop="fromAddress" label="发货地址"> </el-table-column>
-            <el-table-column label="操作" align="center" fixed="right" min-width="150">
+            <el-table-column prop="status" label="订单状态" :formatter="statusFormatter"> </el-table-column>
+            <el-table-column prop="createdAt" label="创建时间" width="150"> </el-table-column>
+            <el-table-column label="操作" align="center" fixed="right" width="150">
                 <template slot-scope="{ row }">
                     <el-button @click="editRow(row)" type="primary" size="mini" plain>编辑</el-button>
                     <el-button @click="deleteRow(row)" type="danger" size="mini" plain>删除</el-button>
@@ -72,6 +86,7 @@
 <script>
 import { mapState } from 'vuex';
 import pageableTable from '@/mixins/pageableTable';
+import { startOfMonth, endOfMonth, addMonths, format } from 'date-fns';
 
 export default {
     name: 'OrderList',
@@ -81,7 +96,14 @@ export default {
             multipleMode: false,
             search: '',
             url: '/order/all',
-            downloading: false
+            downloading: false,
+            statusOptions: [
+                { label: '已完成', value: 'FINISH' },
+                { label: '已取消', value: 'CANCEL' }
+            ],
+            sortStr: 'createdAt,desc',
+            dateRadio: 1,
+            date: null
         };
     },
     computed: {
@@ -90,8 +112,23 @@ export default {
         }
     },
     methods: {
+        beforeCreated() {
+            this.date = [
+                format(startOfMonth(new Date()), 'yyyy-MM-dd HH:mm:ss'),
+                format(endOfMonth(new Date()), 'yyyy-MM-dd HH:mm:ss')
+            ];
+        },
+        statusFormatter(row, column, value) {
+            return (this.statusOptions.find(i => i.value === value) || {}).label;
+        },
         beforeGetData() {
-            return { search: this.search };
+            let data = { search: this.search, query: {} };
+            if (this.dateRadio !== 1) {
+                if (this.date && this.date.length === 2) {
+                    data.query.createdAt = this.date.join();
+                }
+            }
+            return data;
         },
         toggleMultipleMode(multipleMode) {
             this.multipleMode = multipleMode;
@@ -163,6 +200,24 @@ export default {
                     }
                 });
         }
+    },
+    watch: {
+        dateRadio(val) {
+            if (val === 2) {
+                this.date = [
+                    format(startOfMonth(addMonths(new Date(), -1)), 'yyyy-MM-dd HH:mm:ss'),
+                    format(endOfMonth(addMonths(new Date(), -1)), 'yyyy-MM-dd HH:mm:ss')
+                ];
+            } else if (val === 3) {
+                this.date = [
+                    format(startOfMonth(new Date()), 'yyyy-MM-dd HH:mm:ss'),
+                    format(endOfMonth(new Date()), 'yyyy-MM-dd HH:mm:ss')
+                ];
+            }
+        },
+        date() {
+            this.getData();
+        }
     }
 };
 </script>

+ 42 - 3
src/main/vue/src/views/UserEdit.vue

@@ -21,9 +21,9 @@
                     label-position="right"
                     style="max-width: 500px;"
                 >
-                    <el-form-item prop="avatar" label="头像">
+                    <!-- <el-form-item prop="avatar" label="头像">
                         <crop-upload v-model="formData.avatar"></crop-upload>
-                    </el-form-item>
+                    </el-form-item> -->
                     <el-form-item prop="username" label="用户名">
                         <el-input v-model="formData.username"></el-input>
                         <div class="gen" @dblclick="gen"></div>
@@ -67,6 +67,15 @@
                     <el-form-item prop="email" label="邮箱">
                         <el-input v-model="formData.email"></el-input>
                     </el-form-item>
+                    <el-form-item prop="org" label="公司名称">
+                        <el-input v-model="formData.org"></el-input>
+                    </el-form-item>
+                    <el-form-item prop="req" label="需求描述">
+                        <el-input v-model="formData.req"></el-input>
+                    </el-form-item>
+                    <el-form-item prop="receiver" label="收件人姓名">
+                        <el-input v-model="formData.receiver"></el-input>
+                    </el-form-item>
                     <el-form-item prop="receiver" label="收件人姓名">
                         <el-input v-model="formData.receiver"></el-input>
                     </el-form-item>
@@ -76,6 +85,19 @@
                     <el-form-item prop="address" label="收件地址">
                         <el-input v-model="formData.address"></el-input>
                     </el-form-item>
+                    <el-form-item prop="invitor" label="绑定上级">
+                        <el-select
+                            v-model="formData.invitor"
+                            filterable
+                            placeholder="输入用户名或手机号搜索"
+                            remote
+                            :remote-method="searchUser"
+                            :loading="searching"
+                        >
+                            <el-option v-for="item in users" :key="item.id" :label="item.nickname" :value="item.id">
+                            </el-option>
+                        </el-select>
+                    </el-form-item>
                     <el-form-item>
                         <el-button @click="onSave" :loading="saving" type="primary">保存</el-button>
                         <el-button @click="del" :disabled="saving" type="danger" v-if="formData.id && formData.id !== 1"
@@ -144,7 +166,8 @@ export default {
                 authorities: [{ required: true, message: '请选择角色', trigger: 'blur' }],
                 saving: false
             },
-            authorities: []
+            authorities: [],
+            users: []
         };
     },
     methods: {
@@ -230,6 +253,22 @@ export default {
             this.formData.phone = card.phone;
             this.$message('ok');
             console.log(card);
+        },
+        searchUser(queryString, cb) {
+            if (queryString !== '') {
+                this.searching = true;
+                this.$http
+                    .post('/user/all', { search: queryString }, { body: 'json' })
+                    .then(res => {
+                        this.searching = false;
+                        this.users = res.content;
+                    })
+                    .catch(e => {
+                        this.searching = false;
+                    });
+            } else {
+                this.users = [];
+            }
         }
     }
 };

+ 4 - 12
src/main/vue/src/views/UserList.vue

@@ -28,17 +28,8 @@
             <el-table-column prop="username" label="用户名" min-width="200"> </el-table-column>
             <el-table-column prop="nickname" label="昵称" min-width="200"> </el-table-column>
             <el-table-column prop="phone" label="手机" min-width="200"> </el-table-column>
-            <el-table-column prop="invitor" label="推广链接所属用户ID" width="200"> </el-table-column>
-            <el-table-column label="头像" width="200">
-                <template slot-scope="{ row }">
-                    <el-image
-                        style="width: 30px; height: 30px;"
-                        :src="row.avatar"
-                        fit="cover"
-                        :preview-src-list="[row.avatar]"
-                    ></el-image>
-                </template>
-            </el-table-column>
+            <el-table-column prop="invitor" label="上级" width="200"> </el-table-column>
+            <el-table-column prop="org" label="公司" width="200" show-overflow-tooltip> </el-table-column>
             <el-table-column label="操作" align="center" fixed="right">
                 <template slot-scope="{ row }">
                     <el-button @click="editRow(row)" type="primary" size="mini" plain>编辑</el-button>
@@ -72,7 +63,8 @@ export default {
             multipleMode: false,
             search: '',
             url: '/user/all',
-            downloading: false
+            downloading: false,
+            sortStr: 'createdAt,desc'
         };
     },
     computed: {