package com.stylefeng.guns.modular.api; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.intuit.ipp.core.IEntity; import com.intuit.ipp.data.*; import com.intuit.ipp.exception.FMSException; import com.intuit.ipp.services.DataService; import com.intuit.ipp.services.QueryResult; import com.intuit.oauth2.data.BearerTokenResponse; import com.intuit.oauth2.exception.OAuthException; import com.stylefeng.guns.core.base.controller.BaseController; import com.stylefeng.guns.core.base.tips.ErrorTip; import com.stylefeng.guns.core.common.constant.factory.ConstantFactory; import com.stylefeng.guns.core.common.exception.BizExceptionEnum; import com.stylefeng.guns.core.exception.GunsException; import com.stylefeng.guns.core.shiro.ShiroUser; import com.stylefeng.guns.core.util.Convert; import com.stylefeng.guns.core.util.JwtTokenUtil; import com.stylefeng.guns.core.util.MD5Util; import com.stylefeng.guns.core.util.ToolUtil; import com.stylefeng.guns.modular.system.dao.TCompanyMapper; import com.stylefeng.guns.modular.system.dao.UserMapper; import com.stylefeng.guns.modular.system.model.TCompany; import com.stylefeng.guns.modular.system.model.User; import com.stylefeng.guns.modular.system.model.UserInfo; import com.stylefeng.guns.modular.system.utils.EmailUtil; import com.stylefeng.guns.modular.system.utils.InvoicesDataUploadUtil; import com.stylefeng.guns.modular.system.utils.RedisUtil; import com.stylefeng.guns.modular.system.utils.tips.SuccessTip; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.RandomStringUtils; import org.json.JSONObject; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpSession; import java.math.BigDecimal; import java.util.*; /** * 接口控制器提供 * * @author stylefeng * @Date 2018/7/20 23:39 */ @RestController @Api(tags = "登录") @RequestMapping("/gunsApi") @Slf4j public class ApiController extends BaseController { @Autowired private UserMapper userMapper; @Resource private TCompanyMapper companyMapper; @Autowired private RedisUtil redisUtil; private final String INVOICE_DATA = "CARINVOICE:"; private static final String ACCOUNT_QUERY = "select * from Account where AccountType='%s' maxresults 1"; /** * api登录接口,通过账号密码获取token */ @PostMapping("/companyLogin") @ApiOperation(value = "卡车公司登录", notes = "卡车公司登录") @ApiImplicitParams({ @ApiImplicitParam(name = "username", value = "用户账号", required = true, dataType = "String"), @ApiImplicitParam(name = "password", value = "用户密码", required = true, dataType = "String") }) public Object companyLogin(@RequestParam("username") String username, @RequestParam("password") String password) { //获取数据库中的账号密码,准备比对 List user = companyMapper.selectList(new EntityWrapper().eq("account",username)); if (user.size()==0) { return new ErrorTip(500, "Account password error!"); } if(user.get(0).getExpirationTime().getTime() result = new HashMap<>(); result.put("token", JwtTokenUtil.generateToken(String.valueOf(company.getId()))); result.put("company", company); return new SuccessTip(result); } } private ShiroUser shiroUser(User user) { ShiroUser shiroUser = new ShiroUser(); shiroUser.setId(user.getId()); shiroUser.setAccount(user.getAccount()); shiroUser.setDeptId(user.getDeptid()); shiroUser.setDeptName(ConstantFactory.me().getDeptName(user.getDeptid())); shiroUser.setName(user.getName()); Integer[] roleArray = Convert.toIntArray(user.getRoleid()); List roleList = new ArrayList(); List roleNameList = new ArrayList(); for (int roleId : roleArray) { roleList.add(roleId); roleNameList.add(ConstantFactory.me().getSingleRoleName(roleId)); } shiroUser.setRoleList(roleList); shiroUser.setRoleNames(roleNameList); return shiroUser; } /** * 测试接口是否走鉴权 */ @RequestMapping(value = "/test", method = RequestMethod.POST) public Object test() { return SUCCESS_TIP; } @PostMapping("/forget") @ApiOperation(value = "忘记密码", notes = "忘记密码") @ApiImplicitParams({ @ApiImplicitParam(name = "username", value = "用户账号", required = true, dataType = "String"), @ApiImplicitParam(name = "password", value = "用户密码", required = true, dataType = "String"), @ApiImplicitParam(name = "code", value = "验证码", required = true, dataType = "String"), }) public Object forget(@RequestParam("username") String username, @RequestParam("password") String password, @RequestParam("code") String code) { List user = companyMapper.selectList(new EntityWrapper().eq("account",username)); String value = redisUtil.getValue(username); if(!code.equals(value)){ return new ErrorTip(5001, "Verification code error!"); } if (user.size()==0){ return new ErrorTip(500, "Account does not exist!"); } user.get(0).setPassword(MD5Util.encrypt(password)); companyMapper.updateById(user.get(0)); return new SuccessTip(); } @PostMapping("/sendCode") @ApiOperation(value = "发送验证码", notes = "发送验证码") @ApiImplicitParams({ @ApiImplicitParam(name = "email", value = "用户邮箱", required = true, dataType = "String"), }) public Object sendCode(@RequestParam("email") String email) { String randomNumber = getRandomString(6); redisUtil.setStrValue(email,randomNumber,300); try { EmailUtil.sendMailGMail(email, randomNumber); return new com.stylefeng.guns.core.base.tips.SuccessTip(); }catch (Exception e){ e.printStackTrace(); return new ErrorTip(500,"ERROR"); } } private String getRandomString(int length) { String base = "0123456789"; Random random = new Random(); StringBuffer sb = new StringBuffer(); for(int i = 0; i < length; ++i) { int number = random.nextInt(base.length()); sb.append(base.charAt(number)); } return sb.toString(); } @ApiOperation(value = "redirectURL接口",notes="redirectURL接口") @GetMapping(value = "/oauth2redirectOfCar") @ResponseBody @Transactional public String callbackIntuit(@RequestParam("code") String authCode, @RequestParam("state") String state, @RequestParam(value = "realmId", required = false) String realmId, HttpSession session) throws OAuthException { String accessToken = ""; if (com.stylefeng.guns.core.util.ToolUtil.isEmpty(realmId)) { return new JSONObject().put("response","No realm ID. QBO calls only work if the accounting scope was passed!").toString(); } try { session.setAttribute("realmId", realmId); session.setAttribute("auth_code", authCode); // OAuth2PlatformClient client = factory.getOAuth2PlatformClient(); // String redirectUri = factory.getRedirectUrl(); BearerTokenResponse bearerTokenResponse = InvoicesDataUploadUtil.callBackFromOAuth(authCode); accessToken = bearerTokenResponse.getAccessToken(); session.setAttribute("access_token", bearerTokenResponse.getAccessToken()); session.setAttribute("refresh_token", bearerTokenResponse.getRefreshToken()); }catch (Exception e){ e.printStackTrace(); } try { String value = redisUtil.getValue(INVOICE_DATA); log.info("value:{}",value); if (ToolUtil.isEmpty(value)){ return "ERROR"; } Gson gson = new Gson(); JsonArray jsonArray = gson.fromJson(value, JsonArray.class); for (JsonElement jsonElement : jsonArray) { JsonObject asJsonObject = jsonElement.getAsJsonObject(); String name = asJsonObject.get("name").getAsString(); String amount = asJsonObject.get("amount").getAsString(); String unitPrice = asJsonObject.get("unitPrice").getAsString(); DataService service = InvoicesDataUploadUtil.getDataService(realmId, accessToken); Customer customer = getCustomerWithAllFields(name,"testconceptsample@mailinator.com"); Customer savedCustomer = service.add(customer); Item item = getItemFields(service, unitPrice == null || unitPrice == "ABC Corporations" ? "0" : unitPrice ); Item savedItem = service.add(item); Invoice invoice = getInvoiceFields(savedCustomer, savedItem, amount == null || amount == "" ? "0" : amount); Invoice savedInvoice = service.add(invoice); service.sendEmail(savedInvoice, customer.getPrimaryEmailAddr().getAddress()); Payment payment = getPaymentFields(savedCustomer, savedInvoice); Payment savedPayment = service.add(payment); createResponse(savedPayment); } redisUtil.remove(INVOICE_DATA); } catch (Exception e) { e.printStackTrace(); throw new GunsException(BizExceptionEnum.CALLBACK_ERROR); } return "SUCCESS"; } private Customer getCustomerWithAllFields(String companyName,String mailAddr) { Customer customer = new Customer(); customer.setDisplayName(RandomStringUtils.randomAlphanumeric(6)); customer.setCompanyName(companyName); EmailAddress emailAddr = new EmailAddress(); emailAddr.setAddress(mailAddr); customer.setPrimaryEmailAddr(emailAddr); return customer; } private Item getItemFields(DataService service,String unitPrice) throws FMSException { Item item = new Item(); item.setName("Item" + RandomStringUtils.randomAlphanumeric(5)); item.setTaxable(false); item.setUnitPrice(unitPrice == null || unitPrice == "" ? BigDecimal.ZERO :new BigDecimal(unitPrice)); item.setType(ItemTypeEnum.SERVICE); Account incomeAccount = getIncomeBankAccount(service); item.setIncomeAccountRef(createRef(incomeAccount)); return item; } private Account getIncomeBankAccount(DataService service) throws FMSException { QueryResult queryResult = service.executeQuery(String.format(ACCOUNT_QUERY, AccountTypeEnum.INCOME.value())); List entities = queryResult.getEntities(); if(!entities.isEmpty()) { return (Account)entities.get(0); } return createIncomeBankAccount(service); } private ReferenceType createRef(IntuitEntity entity) { ReferenceType referenceType = new ReferenceType(); referenceType.setValue(entity.getId()); return referenceType; } private Account createIncomeBankAccount(DataService service) throws FMSException { Account account = new Account(); account.setName("Incom" + RandomStringUtils.randomAlphabetic(5)); account.setAccountType(AccountTypeEnum.INCOME); return service.add(account); } private Invoice getInvoiceFields(Customer customer, Item item,String amount) { Invoice invoice = new Invoice(); invoice.setCustomerRef(createRef(customer)); BigDecimal balance = invoice.getBalance(); log.info("balance:{}",balance); List invLine = new ArrayList(); Line line = new Line(); line.setAmount(amount == null || amount == "" ? BigDecimal.ZERO : new BigDecimal(amount)); line.setDetailType(LineDetailTypeEnum.SALES_ITEM_LINE_DETAIL); SalesItemLineDetail silDetails = new SalesItemLineDetail(); silDetails.setItemRef(createRef(item)); line.setSalesItemLineDetail(silDetails); invLine.add(line); invoice.setLine(invLine); return invoice; } private Payment getPaymentFields(Customer customer, Invoice invoice) { Payment payment = new Payment(); payment.setCustomerRef(createRef(customer)); payment.setTotalAmt(invoice.getTotalAmt()); List linkedTxnList = new ArrayList(); LinkedTxn linkedTxn = new LinkedTxn(); linkedTxn.setTxnId(invoice.getId()); linkedTxn.setTxnType(TxnTypeEnum.INVOICE.value()); linkedTxnList.add(linkedTxn); Line line1 = new Line(); line1.setAmount(invoice.getTotalAmt()); line1.setLinkedTxn(linkedTxnList); List lineList = new ArrayList(); lineList.add(line1); payment.setLine(lineList); return payment; } private String createResponse(Object entity) { ObjectMapper mapper = new ObjectMapper(); String jsonInString; try { jsonInString = mapper.writeValueAsString(entity); } catch (Exception e) { return createErrorResponse(e); } return jsonInString; } private String createErrorResponse(Exception e) { log.error("Exception while calling QBO ", e); return new JSONObject().put("response","Failed").toString(); } }