Browse Source

Merge branch 'dev' of ssh://10.10.100.21/source/saas-platform into dev

zhuth 7 years ago
parent
commit
826c4f1305
24 changed files with 632 additions and 32 deletions
  1. 11 1
      base-servers/account/account-dto/src/main/java/com/usoftchina/saas/account/dto/CompanyDTO.java
  2. 65 0
      base-servers/account/account-dto/src/main/java/com/usoftchina/saas/account/dto/CompanyRegDTO.java
  3. 41 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/controller/AccountController.java
  4. 18 5
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/controller/CompanyController.java
  5. 16 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/mapper/AccountMapper.java
  6. 9 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/po/Account.java
  7. 14 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/AccountService.java
  8. 16 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/impl/AccountServiceImpl.java
  9. 1 1
      base-servers/account/account-server/src/main/resources/mapper/AccountCompanyMapper.xml
  10. 17 4
      base-servers/account/account-server/src/main/resources/mapper/AccountMapper.xml
  11. 118 0
      base-servers/account/account-server/src/test/java/com/usoftchina/saas/account/controller/AccountControllerTest.java
  12. 75 0
      base-servers/account/account-server/src/test/java/com/usoftchina/saas/account/controller/CompanyControllerTest.java
  13. 8 8
      base-servers/account/account-server/src/test/java/com/usoftchina/saas/account/service/AccountServiceTest.java
  14. 4 6
      base-servers/account/account-server/src/test/java/com/usoftchina/saas/account/service/CompanyServiceTest.java
  15. 22 0
      framework/core/src/main/java/com/usoftchina/saas/base/Result.java
  16. 1 0
      framework/core/src/main/java/com/usoftchina/saas/exception/ExceptionCode.java
  17. 12 0
      framework/core/src/main/java/com/usoftchina/saas/utils/JsonUtils.java
  18. 17 1
      framework/server-starter/src/main/java/com/usoftchina/saas/server/ServerAutoConfiguration.java
  19. 22 0
      framework/test-starter/pom.xml
  20. 118 0
      framework/test-starter/src/main/java/com.usoftchina.saas.test/BaseControllerTest.java
  21. 16 0
      framework/test-starter/src/main/java/com.usoftchina.saas.test/TestConstant.java
  22. 3 3
      framework/test-starter/src/main/java/com.usoftchina.saas.test/TestContextListener.java
  23. 1 1
      framework/test-starter/src/main/resources/META-INF/spring.factories
  24. 7 2
      script/mysql/init/account.sql

+ 11 - 1
base-servers/account/account-dto/src/main/java/com/usoftchina/saas/account/dto/CompanyDTO.java

@@ -10,6 +10,7 @@ import java.io.Serializable;
  */
  */
 @ApiModel(value = "Company", description = "公司信息")
 @ApiModel(value = "Company", description = "公司信息")
 public class CompanyDTO implements Serializable{
 public class CompanyDTO implements Serializable{
+    private Long id;
     /**
     /**
      * 唯一名称
      * 唯一名称
      */
      */
@@ -21,6 +22,14 @@ public class CompanyDTO implements Serializable{
     private String address;
     private String address;
     private String logoUrl;
     private String logoUrl;
 
 
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
     public String getName() {
     public String getName() {
         return name;
         return name;
     }
     }
@@ -56,7 +65,8 @@ public class CompanyDTO implements Serializable{
     @Override
     @Override
     public String toString() {
     public String toString() {
         return "CompanyDTO{" +
         return "CompanyDTO{" +
-                "name='" + name + '\'' +
+                "id=" + id +
+                ", name='" + name + '\'' +
                 ", businessCode='" + businessCode + '\'' +
                 ", businessCode='" + businessCode + '\'' +
                 ", address='" + address + '\'' +
                 ", address='" + address + '\'' +
                 ", logoUrl='" + logoUrl + '\'' +
                 ", logoUrl='" + logoUrl + '\'' +

+ 65 - 0
base-servers/account/account-dto/src/main/java/com/usoftchina/saas/account/dto/CompanyRegDTO.java

@@ -0,0 +1,65 @@
+package com.usoftchina.saas.account.dto;
+
+import io.swagger.annotations.ApiModel;
+
+import java.io.Serializable;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+@ApiModel(value = "CompanyReg", description = "公司注册信息")
+public class CompanyRegDTO implements Serializable{
+    /**
+     * 唯一名称
+     */
+    private String name;
+    /**
+     * 商业登记证号
+     */
+    private String businessCode;
+    private String address;
+    private String logoUrl;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getBusinessCode() {
+        return businessCode;
+    }
+
+    public void setBusinessCode(String businessCode) {
+        this.businessCode = businessCode;
+    }
+
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    public String getLogoUrl() {
+        return logoUrl;
+    }
+
+    public void setLogoUrl(String logoUrl) {
+        this.logoUrl = logoUrl;
+    }
+
+    @Override
+    public String toString() {
+        return "CompanyRegDTO{" +
+                "name='" + name + '\'' +
+                ", businessCode='" + businessCode + '\'' +
+                ", address='" + address + '\'' +
+                ", logoUrl='" + logoUrl + '\'' +
+                '}';
+    }
+}

+ 41 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/controller/AccountController.java

@@ -53,6 +53,7 @@ public class AccountController {
         }
         }
 
 
         account = BeanMapper.map(accountRegDTO, Account.class);
         account = BeanMapper.map(accountRegDTO, Account.class);
+        account.setEnabled(true);
         account.setSalt(account.getMobile());
         account.setSalt(account.getMobile());
         account.setPassword(accountService.getEncryptedPassword(account.getPassword(), account.getSalt()));
         account.setPassword(accountService.getEncryptedPassword(account.getPassword(), account.getSalt()));
         accountService.save(account);
         accountService.save(account);
@@ -74,6 +75,10 @@ public class AccountController {
             return Result.error(ExceptionCode.USER_NOT_EXIST);
             return Result.error(ExceptionCode.USER_NOT_EXIST);
         }
         }
 
 
+        if (!account.isEnabled()) {
+            return Result.error(ExceptionCode.USER_NOT_ENABLE);
+        }
+
         boolean checked = accountService.checkPwd(account, password);
         boolean checked = accountService.checkPwd(account, password);
         if (!checked) {
         if (!checked) {
             return Result.error(ExceptionCode.USER_PWD_ERROR);
             return Result.error(ExceptionCode.USER_PWD_ERROR);
@@ -171,4 +176,40 @@ public class AccountController {
         accountService.unbindRole(accountId, roleId);
         accountService.unbindRole(accountId, roleId);
         return Result.success();
         return Result.success();
     }
     }
+
+    /**
+     * 账户禁用
+     *
+     * @param accountId
+     * @return
+     */
+    @PostMapping("/disable")
+    public Result disableAccount(@RequestParam long accountId) {
+        accountService.disable(accountId);
+        return Result.success();
+    }
+
+    /**
+     * 账户启用
+     *
+     * @param accountId
+     * @return
+     */
+    @PostMapping("/enable")
+    public Result enableAccount(@RequestParam long accountId) {
+        accountService.enable(accountId);
+        return Result.success();
+    }
+
+    /**
+     * 账户删除
+     *
+     * @param accountId
+     * @return
+     */
+    @PostMapping("/delete")
+    public Result deleteAccount(@RequestParam long accountId) {
+        accountService.removeByPrimaryKey(accountId);
+        return Result.success();
+    }
 }
 }

+ 18 - 5
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/controller/CompanyController.java

@@ -1,6 +1,7 @@
 package com.usoftchina.saas.account.controller;
 package com.usoftchina.saas.account.controller;
 
 
 import com.usoftchina.saas.account.dto.CompanyDTO;
 import com.usoftchina.saas.account.dto.CompanyDTO;
+import com.usoftchina.saas.account.dto.CompanyRegDTO;
 import com.usoftchina.saas.account.po.Company;
 import com.usoftchina.saas.account.po.Company;
 import com.usoftchina.saas.account.service.CompanyService;
 import com.usoftchina.saas.account.service.CompanyService;
 import com.usoftchina.saas.base.Result;
 import com.usoftchina.saas.base.Result;
@@ -23,22 +24,22 @@ public class CompanyController {
     /**
     /**
      * 注册
      * 注册
      *
      *
-     * @param companyDTO
+     * @param companyRegDTO
      * @return
      * @return
      */
      */
     @PostMapping("/register")
     @PostMapping("/register")
-    public Result register(@RequestBody CompanyDTO companyDTO) {
+    public Result register(@RequestBody CompanyRegDTO companyRegDTO) {
         // 判断是否已注册
         // 判断是否已注册
-        Company company = companyService.findByName(companyDTO.getName());
+        Company company = companyService.findByName(companyRegDTO.getName());
         if (null != company) {
         if (null != company) {
             return Result.error(ExceptionCode.COMPANY_NAME_EXIST);
             return Result.error(ExceptionCode.COMPANY_NAME_EXIST);
         }
         }
-        company = companyService.findByBusinessCode(companyDTO.getBusinessCode());
+        company = companyService.findByBusinessCode(companyRegDTO.getBusinessCode());
         if (null != company) {
         if (null != company) {
             return Result.error(ExceptionCode.COMPANY_CODE_EXIST);
             return Result.error(ExceptionCode.COMPANY_CODE_EXIST);
         }
         }
 
 
-        company = BeanMapper.map(companyDTO, Company.class);
+        company = BeanMapper.map(companyRegDTO, Company.class);
         companyService.save(company);
         companyService.save(company);
 
 
         return Result.success();
         return Result.success();
@@ -75,4 +76,16 @@ public class CompanyController {
         }
         }
         return Result.error(ExceptionCode.COMPANY_NOT_EXIST);
         return Result.error(ExceptionCode.COMPANY_NOT_EXIST);
     }
     }
+
+    /**
+     * 删除
+     *
+     * @param companyId
+     * @return
+     */
+    @PostMapping("/delete")
+    public Result delete(@RequestParam Long companyId) {
+        companyService.removeByPrimaryKey(companyId);
+        return Result.success();
+    }
 }
 }

+ 16 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/mapper/AccountMapper.java

@@ -24,6 +24,14 @@ public interface AccountMapper {
      */
      */
     int insertSelective(Account account);
     int insertSelective(Account account);
 
 
+    /**
+     * 按ID查找
+     *
+     * @param id
+     * @return
+     */
+    Account selectByPrimaryKey(@Param("id") Long id);
+
     /**
     /**
      * 按用户名查找
      * 按用户名查找
      *
      *
@@ -55,4 +63,12 @@ public interface AccountMapper {
      * @return
      * @return
      */
      */
     int deleteByPrimaryKey(@Param("id") Long id);
     int deleteByPrimaryKey(@Param("id") Long id);
+
+    /**
+     * 更新启用状态
+     *
+     * @param id
+     * @param enabled
+     */
+    void updateEnabled(@Param("id") Long id, @Param("enabled") Boolean enabled);
 }
 }

+ 9 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/po/Account.java

@@ -21,6 +21,7 @@ public class Account implements Serializable {
      * 账号类型 0 - 管理员
      * 账号类型 0 - 管理员
      */
      */
     private Integer type;
     private Integer type;
+    private boolean enabled;
     protected Date createTime;
     protected Date createTime;
     protected long creatorId;
     protected long creatorId;
     protected Date updateTime;
     protected Date updateTime;
@@ -82,6 +83,14 @@ public class Account implements Serializable {
         this.type = type;
         this.type = type;
     }
     }
 
 
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
     public Long getId() {
     public Long getId() {
         return id;
         return id;
     }
     }

+ 14 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/AccountService.java

@@ -97,4 +97,18 @@ public interface AccountService {
      */
      */
     boolean removeByPrimaryKey(Long id);
     boolean removeByPrimaryKey(Long id);
 
 
+    /**
+     * 禁用
+     *
+     * @param accountId
+     */
+    void disable(Long accountId);
+
+    /**
+     * 启用
+     *
+     * @param accountId
+     */
+    void enable(Long accountId);
+
 }
 }

+ 16 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/impl/AccountServiceImpl.java

@@ -88,4 +88,20 @@ public class AccountServiceImpl implements AccountService {
         accountCompanyMapper.deleteByAccountId(id);
         accountCompanyMapper.deleteByAccountId(id);
         return accountMapper.deleteByPrimaryKey(id) > 0;
         return accountMapper.deleteByPrimaryKey(id) > 0;
     }
     }
+
+    @Override
+    public void enable(Long accountId) {
+        Account account = accountMapper.selectByPrimaryKey(accountId);
+        if (null != account && !account.isEnabled()) {
+            accountMapper.updateEnabled(accountId, true);
+        }
+    }
+
+    @Override
+    public void disable(Long accountId) {
+        Account account = accountMapper.selectByPrimaryKey(accountId);
+        if (null != account && account.isEnabled()) {
+            accountMapper.updateEnabled(accountId, false);
+        }
+    }
 }
 }

+ 1 - 1
base-servers/account/account-server/src/main/resources/mapper/AccountCompanyMapper.xml

@@ -5,7 +5,7 @@
         insert into ac_account_company(account_id,company_id) values (#{accountId}, #{companyId})
         insert into ac_account_company(account_id,company_id) values (#{accountId}, #{companyId})
     </insert>
     </insert>
     <delete id="delete">
     <delete id="delete">
-        delete from ac_account_company where account_id=#{accountId} and companyId=#{companyId}
+        delete from ac_account_company where account_id=#{accountId} and company_id=#{companyId}
     </delete>
     </delete>
     <delete id="deleteByAccountId" parameterType="java.lang.Long">
     <delete id="deleteByAccountId" parameterType="java.lang.Long">
         delete from ac_account_company where account_id=#{accountId}
         delete from ac_account_company where account_id=#{accountId}

+ 17 - 4
base-servers/account/account-server/src/main/resources/mapper/AccountMapper.xml

@@ -10,18 +10,19 @@
         <result column="email" jdbcType="VARCHAR" property="email"/>
         <result column="email" jdbcType="VARCHAR" property="email"/>
         <result column="mobile" jdbcType="VARCHAR" property="mobile"/>
         <result column="mobile" jdbcType="VARCHAR" property="mobile"/>
         <result column="type" jdbcType="INTEGER" property="type"/>
         <result column="type" jdbcType="INTEGER" property="type"/>
+        <result column="enabled" jdbcType="BOOLEAN" property="enabled"/>
         <result column="creator_id" jdbcType="BIGINT" property="creatorId"/>
         <result column="creator_id" jdbcType="BIGINT" property="creatorId"/>
         <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
         <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
         <result column="updater_id" jdbcType="BIGINT" property="updaterId"/>
         <result column="updater_id" jdbcType="BIGINT" property="updaterId"/>
         <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
         <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
     </resultMap>
     </resultMap>
     <sql id="baseColumns">
     <sql id="baseColumns">
-        id,username,password,salt,realname,email,mobile,type,creator_id,create_time,updater_id,update_time
+        id,username,password,salt,realname,email,mobile,type,enabled,creator_id,create_time,updater_id,update_time
     </sql>
     </sql>
     <insert id="insert" parameterType="com.usoftchina.saas.account.po.Account">
     <insert id="insert" parameterType="com.usoftchina.saas.account.po.Account">
-        insert into ac_account(username,password,salt,realname,email,mobile,type,creator_id,create_time,updater_id,update_time)
+        insert into ac_account(username,password,salt,realname,email,mobile,type,enabled,creator_id,create_time,updater_id,update_time)
         values (#{username,jdbcType=VARCHAR},#{password,jdbcType=VARCHAR}, #{salt,jdbcType=VARCHAR},
         values (#{username,jdbcType=VARCHAR},#{password,jdbcType=VARCHAR}, #{salt,jdbcType=VARCHAR},
-        #{realname,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR}, #{mobile,jdbcType=VARCHAR}, #{type,jdbcType=INTEGER},
+        #{realname,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR}, #{mobile,jdbcType=VARCHAR}, #{type,jdbcType=INTEGER}, #{enabled,jdbcType=BOOLEAN},
         #{creatorId,jdbcType=BIGINT}, #{createTime,jdbcType=TIMESTAMP}, #{updaterId,jdbcType=BIGINT}, #{updateTime,jdbcType=TIMESTAMP})
         #{creatorId,jdbcType=BIGINT}, #{createTime,jdbcType=TIMESTAMP}, #{updaterId,jdbcType=BIGINT}, #{updateTime,jdbcType=TIMESTAMP})
     </insert>
     </insert>
     <insert id="insertSelective" parameterType="com.usoftchina.saas.account.po.Account">
     <insert id="insertSelective" parameterType="com.usoftchina.saas.account.po.Account">
@@ -48,6 +49,9 @@
             <if test="type != null">
             <if test="type != null">
                 type,
                 type,
             </if>
             </if>
+            <if test="enabled != null">
+                enabled,
+            </if>
             <if test="creatorId != null">
             <if test="creatorId != null">
                 creator_id,
                 creator_id,
             </if>
             </if>
@@ -81,7 +85,10 @@
                 #{mobile,jdbcType=VARCHAR},
                 #{mobile,jdbcType=VARCHAR},
             </if>
             </if>
             <if test="type != null">
             <if test="type != null">
-                #{type,jdbcType=INT},
+                #{type,jdbcType=INTEGER},
+            </if>
+            <if test="enabled != null">
+                #{enabled,jdbcType=BOOLEAN},
             </if>
             </if>
             <if test="creatorId != null">
             <if test="creatorId != null">
                 #{creatorId,jdbcType=BIGINT},
                 #{creatorId,jdbcType=BIGINT},
@@ -97,6 +104,9 @@
             </if>
             </if>
         </trim>
         </trim>
     </insert>
     </insert>
+    <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
+        select <include refid="baseColumns"/> from ac_account where id=#{id}
+    </select>
     <select id="selectByUsername" parameterType="java.lang.String" resultMap="BaseResultMap">
     <select id="selectByUsername" parameterType="java.lang.String" resultMap="BaseResultMap">
         select <include refid="baseColumns"/> from ac_account where username=#{username}
         select <include refid="baseColumns"/> from ac_account where username=#{username}
     </select>
     </select>
@@ -109,4 +119,7 @@
     <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
     <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
         delete from ac_account where id=#{id}
         delete from ac_account where id=#{id}
     </delete>
     </delete>
+    <update id="updateEnabled">
+        update ac_account set enabled=#{enabled,jdbcType=BOOLEAN} where id=#{id,jdbcType=BIGINT}
+    </update>
 </mapper>
 </mapper>

+ 118 - 0
base-servers/account/account-server/src/test/java/com/usoftchina/saas/account/controller/AccountControllerTest.java

@@ -0,0 +1,118 @@
+package com.usoftchina.saas.account.controller;
+
+import com.usoftchina.saas.account.constant.AccountType;
+import com.usoftchina.saas.account.dto.AccountDTO;
+import com.usoftchina.saas.account.dto.AccountRegDTO;
+import com.usoftchina.saas.base.Result;
+import com.usoftchina.saas.test.BaseControllerTest;
+import com.usoftchina.saas.test.TestConstant;
+import org.junit.*;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MvcResult;
+//import org.springframework.transaction.annotation.Transactional;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+//@Transactional
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class AccountControllerTest extends BaseControllerTest {
+
+    private final String mobile = "13500000000";
+
+    private final String password = "select111***";
+
+    @Test
+    public void testA_register() throws Exception {
+        AccountRegDTO accountRegDTO = new AccountRegDTO();
+        accountRegDTO.setUsername(mobile);
+        accountRegDTO.setMobile(mobile);
+        accountRegDTO.setEmail("jack-ma@mxhichina.com");
+        accountRegDTO.setRealname("Jack Ma");
+        accountRegDTO.setPassword(password);
+        accountRegDTO.setType(AccountType.ADMIN.getType());
+
+        mockMvc.perform(requestBody("/account/register", accountRegDTO))
+                .andExpect(isSuccess());
+    }
+
+    @Test
+    public void testB_validByUsernameAndPwd() throws Exception {
+        MvcResult mvcResult = mockMvc.perform(get("/account/pwd/check")
+                .param("username", mobile)
+                .param("password", password))
+                .andExpect(isSuccess())
+                .andReturn();
+        Result<AccountDTO> result = result(mvcResult, AccountDTO.class);
+        System.out.println(result.getData());
+        Assert.assertEquals(result.getData().getMobile(), mobile);
+    }
+
+    @Test
+    public void testC_validByUsernameAndErrorPwd() throws Exception {
+        mockMvc.perform(get("/account/pwd/check")
+                .param("username", mobile)
+                .param("password", "1"))
+                .andExpect(isFail());
+    }
+
+    @Test
+    public void testD_getAccount() throws Exception {
+        AccountDTO accountDTO = getAccountDTO();
+        Assert.assertEquals(accountDTO.getMobile(), mobile);
+    }
+
+    private AccountDTO getAccountDTO() throws Exception {
+        MvcResult mvcResult = mockMvc.perform(get("/account")
+                .param("username", mobile))
+                .andExpect(isSuccess())
+                .andReturn();
+        Result<AccountDTO> result = result(mvcResult, AccountDTO.class);
+        System.out.println(result.getData());
+        return result.getData();
+    }
+
+    @Test
+    public void testE_bindCompany() throws Exception {
+        AccountDTO accountDTO = getAccountDTO();
+        mockMvc.perform(post("/account/bind/company")
+                .param("accountId", String.valueOf(accountDTO.getId()))
+                .param("companyId", String.valueOf(TestConstant.DEFAULT_COMPANY_ID)))
+                .andExpect(isSuccess());
+    }
+
+    @Test
+    public void testF_unbindCompany() throws Exception {
+        AccountDTO accountDTO = getAccountDTO();
+        mockMvc.perform(post("/account/unbind/company")
+                .param("accountId", String.valueOf(accountDTO.getId()))
+                .param("companyId", String.valueOf(TestConstant.DEFAULT_COMPANY_ID)))
+                .andExpect(isSuccess());
+    }
+
+    @Test
+    public void testG_disableAccount() throws Exception {
+        AccountDTO accountDTO = getAccountDTO();
+        mockMvc.perform(post("/account/disable")
+                .param("accountId", String.valueOf(accountDTO.getId())))
+                .andExpect(isSuccess());
+    }
+
+    @Test
+    public void testH_enableAccount() throws Exception {
+        AccountDTO accountDTO = getAccountDTO();
+        mockMvc.perform(post("/account/enable")
+                .param("accountId", String.valueOf(accountDTO.getId())))
+                .andExpect(isSuccess());
+    }
+
+    @Test
+    public void testI_deleteAccount() throws Exception {
+        AccountDTO accountDTO = getAccountDTO();
+        mockMvc.perform(post("/account/delete")
+                .param("accountId", String.valueOf(accountDTO.getId())))
+                .andExpect(isSuccess());
+    }
+}

+ 75 - 0
base-servers/account/account-server/src/test/java/com/usoftchina/saas/account/controller/CompanyControllerTest.java

@@ -0,0 +1,75 @@
+package com.usoftchina.saas.account.controller;
+
+import com.usoftchina.saas.account.dto.CompanyDTO;
+import com.usoftchina.saas.base.Result;
+import com.usoftchina.saas.test.BaseControllerTest;
+import org.junit.Assert;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MvcResult;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class CompanyControllerTest extends BaseControllerTest {
+
+    private final String name = "spring.test";
+    private final String businessCode = "T00000000000000000";
+
+    @Test
+    public void testA_register() throws Exception {
+        CompanyDTO companyDTO = new CompanyDTO();
+        companyDTO.setName(name);
+        companyDTO.setBusinessCode(businessCode);
+        companyDTO.setAddress("深圳市南山区粤海街道高新技术产业园科技南五路英唐大厦六楼");
+        companyDTO.setLogoUrl("https://co-image.qichacha.com/CompanyImage/104eb3c232bbac93393a5e204d6a47d1.jpg?x-oss-process=style/qcc_cmp");
+
+        mockMvc.perform(requestBody("/company/register", companyDTO))
+                .andExpect(isSuccess());
+    }
+
+    @Test
+    public void testB_getByName() throws Exception {
+        CompanyDTO companyDTO = getByName();
+        Assert.assertEquals(companyDTO.getBusinessCode(), businessCode);
+    }
+
+    private CompanyDTO getByName() throws Exception {
+        MvcResult mvcResult = mockMvc.perform(get("/company")
+                .param("name", name))
+                .andExpect(isSuccess())
+                .andReturn();
+        Result<CompanyDTO> result = result(mvcResult, CompanyDTO.class);
+        System.out.println(result.getData());
+        return result.getData();
+    }
+
+    private CompanyDTO getByBusinessCode() throws Exception {
+        MvcResult mvcResult = mockMvc.perform(get("/company")
+                .param("businessCode", businessCode))
+                .andExpect(isSuccess())
+                .andReturn();
+        Result<CompanyDTO> result = result(mvcResult, CompanyDTO.class);
+        System.out.println(result.getData());
+        return result.getData();
+    }
+
+    @Test
+    public void testC_getByBusinessCode() throws Exception {
+        CompanyDTO companyDTO = getByBusinessCode();
+        Assert.assertEquals(companyDTO.getName(), name);
+    }
+
+    @Test
+    public void testD_delete() throws Exception {
+        CompanyDTO companyDTO = getByName();
+        mockMvc.perform(post("/company/delete")
+                .param("companyId", String.valueOf(companyDTO.getId())))
+                .andExpect(isSuccess());
+    }
+
+}

+ 8 - 8
base-servers/account/account-server/src/test/java/com/usoftchina/saas/account/service/AccountServiceTest.java

@@ -2,18 +2,18 @@ package com.usoftchina.saas.account.service;
 
 
 import com.usoftchina.saas.account.constant.AccountType;
 import com.usoftchina.saas.account.constant.AccountType;
 import com.usoftchina.saas.account.po.Account;
 import com.usoftchina.saas.account.po.Account;
-import org.junit.Assert;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
+import org.junit.*;
 import org.junit.runner.RunWith;
 import org.junit.runner.RunWith;
 import org.junit.runners.MethodSorters;
 import org.junit.runners.MethodSorters;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.junit4.SpringRunner;
 import org.springframework.test.context.junit4.SpringRunner;
+//import org.springframework.transaction.annotation.Transactional;
 
 
 @RunWith(SpringRunner.class)
 @RunWith(SpringRunner.class)
 @SpringBootTest
 @SpringBootTest
-@FixMethodOrder(MethodSorters.JVM)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+//@Transactional
 public class AccountServiceTest {
 public class AccountServiceTest {
 
 
     @Autowired
     @Autowired
@@ -24,12 +24,12 @@ public class AccountServiceTest {
     private final String password = "select111***";
     private final String password = "select111***";
 
 
     @Test
     @Test
-    public void save() throws Exception {
+    public void testA_save() throws Exception {
         Account account = new Account();
         Account account = new Account();
         account.setMobile(mobile);
         account.setMobile(mobile);
         account.setUsername(mobile);
         account.setUsername(mobile);
         account.setSalt(mobile);
         account.setSalt(mobile);
-        account.setEmail("mayun@mxhichina.com");
+        account.setEmail("jack-ma@mxhichina.com");
         account.setPassword(accountService.getEncryptedPassword(password, account.getSalt()));
         account.setPassword(accountService.getEncryptedPassword(password, account.getSalt()));
         account.setRealname("Jack Ma");
         account.setRealname("Jack Ma");
         account.setType(AccountType.ADMIN.getType());
         account.setType(AccountType.ADMIN.getType());
@@ -39,7 +39,7 @@ public class AccountServiceTest {
     }
     }
 
 
     @Test
     @Test
-    public void checkPwd() throws Exception {
+    public void testB_checkPwd() throws Exception {
         Account account = accountService.findByMobile(mobile);
         Account account = accountService.findByMobile(mobile);
         Assert.assertNotNull(account);
         Assert.assertNotNull(account);
         boolean checked = accountService.checkPwd(account, password);
         boolean checked = accountService.checkPwd(account, password);
@@ -47,7 +47,7 @@ public class AccountServiceTest {
     }
     }
 
 
     @Test
     @Test
-    public void removeByPrimaryKey() throws Exception {
+    public void testC_removeByPrimaryKey() throws Exception {
         Account account = accountService.findByMobile(mobile);
         Account account = accountService.findByMobile(mobile);
         Assert.assertNotNull(account);
         Assert.assertNotNull(account);
         boolean removed = accountService.removeByPrimaryKey(account.getId());
         boolean removed = accountService.removeByPrimaryKey(account.getId());

+ 4 - 6
base-servers/account/account-server/src/test/java/com/usoftchina/saas/account/service/CompanyServiceTest.java

@@ -1,9 +1,7 @@
 package com.usoftchina.saas.account.service;
 package com.usoftchina.saas.account.service;
 
 
 import com.usoftchina.saas.account.po.Company;
 import com.usoftchina.saas.account.po.Company;
-import org.junit.Assert;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
+import org.junit.*;
 import org.junit.runner.RunWith;
 import org.junit.runner.RunWith;
 import org.junit.runners.MethodSorters;
 import org.junit.runners.MethodSorters;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -16,7 +14,7 @@ import org.springframework.test.context.junit4.SpringRunner;
  */
  */
 @RunWith(SpringRunner.class)
 @RunWith(SpringRunner.class)
 @SpringBootTest
 @SpringBootTest
-@FixMethodOrder(MethodSorters.JVM)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class CompanyServiceTest {
 public class CompanyServiceTest {
 
 
     @Autowired
     @Autowired
@@ -25,7 +23,7 @@ public class CompanyServiceTest {
     private final String name = "spring.test";
     private final String name = "spring.test";
 
 
     @Test
     @Test
-    public void save() {
+    public void testA_save() {
         Company company = new Company();
         Company company = new Company();
         company.setName(name);
         company.setName(name);
         company.setBusinessCode("T00000000000000000");
         company.setBusinessCode("T00000000000000000");
@@ -37,7 +35,7 @@ public class CompanyServiceTest {
     }
     }
 
 
     @Test
     @Test
-    public void removeByPrimaryKey() {
+    public void testB_removeByPrimaryKey() {
         Company company = companyService.findByName(name);
         Company company = companyService.findByName(name);
         Assert.assertNotNull(company);
         Assert.assertNotNull(company);
         boolean removed = companyService.removeByPrimaryKey(company.getId());
         boolean removed = companyService.removeByPrimaryKey(company.getId());

+ 22 - 0
framework/core/src/main/java/com/usoftchina/saas/base/Result.java

@@ -1,9 +1,13 @@
 package com.usoftchina.saas.base;
 package com.usoftchina.saas.base;
 
 
+import com.fasterxml.jackson.core.type.TypeReference;
 import com.usoftchina.saas.exception.BaseException;
 import com.usoftchina.saas.exception.BaseException;
 import com.usoftchina.saas.exception.BaseExceptionCode;
 import com.usoftchina.saas.exception.BaseExceptionCode;
+import com.usoftchina.saas.utils.JsonUtils;
+import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
 
 
 import java.io.Serializable;
 import java.io.Serializable;
+import java.lang.reflect.Type;
 
 
 /**
 /**
  * 结果
  * 结果
@@ -122,4 +126,22 @@ public class Result<T> implements Serializable {
         result.setMessage(e.getMessage());
         result.setMessage(e.getMessage());
         return result;
         return result;
     }
     }
+
+    /**
+     * json字符串转换Result对象
+     *
+     * @param jsonString
+     * @param <T>
+     * @return
+     */
+    public static <T> Result<T> fromJsonString(String jsonString, Class<T> targetCls) {
+        Type[] types = new Type[]{targetCls};
+        final ParameterizedTypeImpl type = ParameterizedTypeImpl.make(Result.class, types, Result.class.getDeclaringClass());
+        return JsonUtils.fromJsonString(jsonString, new TypeReference<Result<T>>() {
+            @Override
+            public Type getType() {
+                return type;
+            }
+        });
+    }
 }
 }

+ 1 - 0
framework/core/src/main/java/com/usoftchina/saas/exception/ExceptionCode.java

@@ -32,6 +32,7 @@ public enum ExceptionCode implements BaseExceptionCode {
     USER_PWD_ERROR(53003, "密码错误"),
     USER_PWD_ERROR(53003, "密码错误"),
     USER_PWD_NOT_EQUALS(53004, "密码与确认密码不一致"),
     USER_PWD_NOT_EQUALS(53004, "密码与确认密码不一致"),
     USER_NOT_EXIST(53005, "用户不存在"),
     USER_NOT_EXIST(53005, "用户不存在"),
+    USER_NOT_ENABLE(53006, "用户禁止使用"),
 
 
     // 文件相关
     // 文件相关
     FOLDER_NULL(55000, "文件夹为空"),
     FOLDER_NULL(55000, "文件夹为空"),

+ 12 - 0
framework/core/src/main/java/com/usoftchina/saas/utils/JsonUtils.java

@@ -1,5 +1,6 @@
 package com.usoftchina.saas.utils;
 package com.usoftchina.saas.utils;
 
 
+import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.springframework.util.StringUtils;
 import org.springframework.util.StringUtils;
 
 
@@ -29,4 +30,15 @@ public class JsonUtils {
             return null;
             return null;
         }
         }
     }
     }
+
+    public static <T> T fromJsonString(String json, TypeReference valueTypeRef) {
+        if (StringUtils.isEmpty(json)) {
+            return null;
+        }
+        try {
+            return mapper.readValue(json, valueTypeRef);
+        } catch (Exception e) {
+            return null;
+        }
+    }
 }
 }

+ 17 - 1
framework/server-starter/src/main/java/com/usoftchina/saas/server/ServerAutoConfiguration.java

@@ -1,14 +1,20 @@
 package com.usoftchina.saas.server;
 package com.usoftchina.saas.server;
 
 
+import com.usoftchina.saas.server.error.ServletErrorUtils;
+import com.usoftchina.saas.server.error.UnCaughtErrorFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.lang.Nullable;
 import org.springframework.lang.Nullable;
 import org.springframework.web.servlet.HandlerExceptionResolver;
 import org.springframework.web.servlet.HandlerExceptionResolver;
 import org.springframework.web.servlet.ModelAndView;
 import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.util.NestedServletException;
 
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
 
 
 /**
 /**
  * @author yingp
  * @author yingp
@@ -18,13 +24,23 @@ import javax.servlet.http.HttpServletResponse;
 @ComponentScan(basePackages = {"com.usoftchina.saas.server"})
 @ComponentScan(basePackages = {"com.usoftchina.saas.server"})
 public class ServerAutoConfiguration {
 public class ServerAutoConfiguration {
 
 
+    private Logger logger = LoggerFactory.getLogger(UnCaughtErrorFilter.class);
+
     @Bean
     @Bean
     public HandlerExceptionResolver handlerExceptionResolver() {
     public HandlerExceptionResolver handlerExceptionResolver() {
         return new HandlerExceptionResolver(){
         return new HandlerExceptionResolver(){
             @Nullable
             @Nullable
             @Override
             @Override
             public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, @Nullable Object o, Exception e) {
             public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, @Nullable Object o, Exception e) {
-                System.err.println("############" + request.getRequestURI() + "#" + response.getStatus());
+                Throwable cause = e;
+                if (e instanceof NestedServletException) {
+                    cause = ((NestedServletException) e).getRootCause();
+                }
+                logger.error(ServletErrorUtils.buildMessage(request, cause), cause);
+                try {
+                    ServletErrorUtils.writerErrorResult(response, cause);
+                } catch (IOException ex) {
+                }
                 return null;
                 return null;
             }
             }
         };
         };

+ 22 - 0
framework/test-starter/pom.xml

@@ -21,5 +21,27 @@
             <groupId>com.usoftchina.saas</groupId>
             <groupId>com.usoftchina.saas</groupId>
             <artifactId>core</artifactId>
             <artifactId>core</artifactId>
         </dependency>
         </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <scope>provided</scope>
+        </dependency>
     </dependencies>
     </dependencies>
 </project>
 </project>

+ 118 - 0
framework/test-starter/src/main/java/com.usoftchina.saas.test/BaseControllerTest.java

@@ -0,0 +1,118 @@
+package com.usoftchina.saas.test;
+
+import com.usoftchina.saas.base.Result;
+import com.usoftchina.saas.utils.JsonUtils;
+import org.junit.Before;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+import org.springframework.test.web.servlet.ResultMatcher;
+import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
+
+/**
+ * @author yingp
+ * @date 2018/10/23
+ */
+public abstract class BaseControllerTest {
+    @Autowired
+    protected WebApplicationContext context;
+
+    protected MockMvc mockMvc;
+
+    @Before
+    public void setup() {
+        this.mockMvc = MockMvcBuilders.webAppContextSetup(context)
+                .alwaysDo(print())
+                .alwaysExpect(isOk())
+                .alwaysExpect(isJson())
+                .build();
+    }
+
+    /**
+     * GET请求
+     *
+     * @param urlTemplate
+     * @return
+     */
+    public static MockHttpServletRequestBuilder get(String urlTemplate) {
+        return MockMvcRequestBuilders.get(urlTemplate);
+    }
+
+    /**
+     * POST form方式请求
+     *
+     * @param urlTemplate
+     * @return
+     */
+    public static MockHttpServletRequestBuilder post(String urlTemplate) {
+        return MockMvcRequestBuilders.post(urlTemplate);
+    }
+
+    /**
+     * POST Payload方式请求,使用@RequestBody注解情况下
+     *
+     * @param object
+     * @return
+     */
+    public static MockHttpServletRequestBuilder requestBody(String urlTemplate, Object object) {
+        return post(urlTemplate).contentType(MediaType.APPLICATION_JSON_UTF8)
+                .content(JsonUtils.toJsonString(object));
+    }
+
+    /**
+     * 是否返回 http status: 200
+     *
+     * @return
+     */
+    public static ResultMatcher isOk() {
+        return status().isOk();
+    }
+
+    /**
+     * 是否返回json格式
+     *
+     * @return
+     */
+    public static ResultMatcher isJson() {
+        return content().contentType(MediaType.APPLICATION_JSON_UTF8);
+    }
+
+    /**
+     * 是否执行成功 {"success": true}
+     *
+     * @return
+     */
+    public static ResultMatcher isSuccess() {
+        return jsonPath("success").value(true);
+    }
+
+    /**
+     * 是否执行失败 {"success": false}
+     *
+     * @return
+     */
+    public static ResultMatcher isFail() {
+        return jsonPath("success").value(false);
+    }
+
+    /**
+     * Result转换
+     *
+     * @param mvcResult
+     * @param <T>
+     * @return
+     * @throws Exception
+     */
+    public static <T> Result<T> result(MvcResult mvcResult, Class<T> targetCls) throws Exception {
+        String content = mvcResult.getResponse().getContentAsString();
+        return Result.fromJsonString(content, targetCls);
+    }
+
+}

+ 16 - 0
framework/test-starter/src/main/java/com.usoftchina.saas.test/TestConstant.java

@@ -0,0 +1,16 @@
+package com.usoftchina.saas.test;
+
+/**
+ * @author yingp
+ * @date 2018/10/22
+ */
+public class TestConstant {
+    /**
+     * 默认企业ID
+     */
+    public static final long DEFAULT_COMPANY_ID = 1;
+    /**
+     * 默认账户ID
+     */
+    public static final long DEFAULT_ACCOUNT_ID = 1;
+}

+ 3 - 3
framework/test-starter/src/main/java/com.usoftchina.saas.test/DefaultContextHolderListener.java → framework/test-starter/src/main/java/com.usoftchina.saas.test/TestContextListener.java

@@ -8,11 +8,11 @@ import org.springframework.test.context.support.AbstractTestExecutionListener;
  * @author yingp
  * @author yingp
  * @date 2018/10/22
  * @date 2018/10/22
  */
  */
-public class DefaultContextHolderListener extends AbstractTestExecutionListener {
+public class TestContextListener extends AbstractTestExecutionListener {
     @Override
     @Override
     public void beforeTestClass(TestContext testContext) throws Exception {
     public void beforeTestClass(TestContext testContext) throws Exception {
         // 设置测试环境默认用户
         // 设置测试环境默认用户
-        BaseContextHolder.setCompanyId(1);
-        BaseContextHolder.setUserId(1);
+        BaseContextHolder.setCompanyId(TestConstant.DEFAULT_COMPANY_ID);
+        BaseContextHolder.setUserId(TestConstant.DEFAULT_ACCOUNT_ID);
     }
     }
 }
 }

+ 1 - 1
framework/test-starter/src/main/resources/META-INF/spring.factories

@@ -1,3 +1,3 @@
 # Test Execution Listeners
 # Test Execution Listeners
 org.springframework.test.context.TestExecutionListener=\
 org.springframework.test.context.TestExecutionListener=\
-com.usoftchina.saas.test.DefaultContextHolderListener
+com.usoftchina.saas.test.TestContextListener

+ 7 - 2
script/mysql/init/account.sql

@@ -22,6 +22,7 @@ create table `ac_account` (
   email varchar(100) comment '邮箱',
   email varchar(100) comment '邮箱',
   mobile varchar(100) not null comment '手机号',
   mobile varchar(100) not null comment '手机号',
   type int comment '账户类型 0, 1',
   type int comment '账户类型 0, 1',
+  enabled bool comment '是否启用',
   creator_id int unsigned,
   creator_id int unsigned,
   create_time datetime,
   create_time datetime,
   updater_id int unsigned,
   updater_id int unsigned,
@@ -71,12 +72,16 @@ create table `ac_role_resource` (
   resource_id int unsigned
   resource_id int unsigned
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色绑定资源';
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色绑定资源';
 
 
-insert into ac_account(id,username,password,salt,realname,email,mobile,type,
+insert into ac_account(id,username,password,salt,realname,email,mobile,type,enabled,
                        creator_id,create_time,updater_id,update_time)
                        creator_id,create_time,updater_id,update_time)
 values (1,'18888888888','3e8451e274a8ee847872194e584a4145','18888888888','Administrator',
 values (1,'18888888888','3e8451e274a8ee847872194e584a4145','18888888888','Administrator',
-          'admin@usoftchina.com', '18888888888', 0, 1, now(), 1, now());
+          'admin@usoftchina.com', '18888888888', 0, 1, 1, now(), 1, now());
 
 
 insert into ac_company(name, business_code, address, logo_url, creator_id, create_time, updater_id, update_time)
 insert into ac_company(name, business_code, address, logo_url, creator_id, create_time, updater_id, update_time)
 values ('测试账套', '000000000000000000','深圳市南山区粤海街道高新技术产业园科技南五路英唐大厦六楼',
 values ('测试账套', '000000000000000000','深圳市南山区粤海街道高新技术产业园科技南五路英唐大厦六楼',
         'https://co-image.qichacha.com/CompanyImage/104eb3c232bbac93393a5e204d6a47d1.jpg?x-oss-process=style/qcc_cmp',
         'https://co-image.qichacha.com/CompanyImage/104eb3c232bbac93393a5e204d6a47d1.jpg?x-oss-process=style/qcc_cmp',
         1, now(), 1, now());
         1, now(), 1, now());
+
+insert into ac_account_company(account_id, company_id) values (1, 1);
+
+