Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
cloud-platform
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
youjj
cloud-platform
Commits
4e08442a
Commit
4e08442a
authored
Jan 08, 2020
by
hanfeng
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master-invoice-modular' into dev
parents
56e57d3e
4a22dcb5
Changes
19
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
1352 additions
and
5 deletions
+1352
-5
AppStaffUserBiz.java
...om/github/wxiaoqi/security/admin/biz/AppStaffUserBiz.java
+1
-1
OrderFeign.java
...c/main/java/com/xxfc/platform/order/feign/OrderFeign.java
+6
-4
OrderInvoiceBiz.java
...ain/java/com/xxfc/platform/order/biz/OrderInvoiceBiz.java
+15
-0
OrderInvoiceController.java
.../com/xxfc/platform/order/rest/OrderInvoiceController.java
+5
-0
InvoiceStatusEum.java
...om/xxfc/platform/universal/constant/InvoiceStatusEum.java
+31
-0
Invoice.java
...main/java/com/xxfc/platform/universal/entity/Invoice.java
+218
-0
InvoiceQueryError.java
...com/xxfc/platform/universal/entity/InvoiceQueryError.java
+21
-0
OrderData.java
...in/java/com/xxfc/platform/universal/entity/OrderData.java
+40
-0
InvoiceVo.java
...java/com/xxfc/platform/universal/entity/vo/InvoiceVo.java
+69
-0
NumberToCN.java
...in/java/com/xxfc/platform/universal/utils/NumberToCN.java
+129
-0
SnowflakeIdWorker.java
.../com/xxfc/platform/universal/utils/SnowflakeIdWorker.java
+133
-0
pom.xml
xx-universal/xx-universal-server/pom.xml
+12
-0
InvoiceQueryErrorBiz.java
...com/xxfc/platform/universal/biz/InvoiceQueryErrorBiz.java
+16
-0
InvoiceController.java
...xxfc/platform/universal/controller/InvoiceController.java
+57
-0
InvoiceMapper.java
...ava/com/xxfc/platform/universal/mapper/InvoiceMapper.java
+13
-0
InvoiceQueryErrorMapper.java
...fc/platform/universal/mapper/InvoiceQueryErrorMapper.java
+12
-0
InvoiceBiz.java
.../java/com/xxfc/platform/universal/service/InvoiceBiz.java
+294
-0
InvoiceDao.java
...m/xxfc/platform/universal/service/invoice/InvoiceDao.java
+22
-0
InvoiceDaoImpl.java
...atform/universal/service/invoice/impl/InvoiceDaoImpl.java
+258
-0
No files found.
ace-modules/ace-admin/src/main/java/com/github/wxiaoqi/security/admin/biz/AppStaffUserBiz.java
View file @
4e08442a
...
...
@@ -23,8 +23,8 @@ import java.util.List;
* @author Administrator
*/
@Service
@RequiredArgsConstructor
(
onConstructor_
=
{
@Autowired
})
@Slf4j
@RequiredArgsConstructor
(
onConstructor_
=
{
@Autowired
})
public
class
AppStaffUserBiz
extends
BaseBiz
<
AppStaffUserMapper
,
AppStaffUser
>
{
private
final
AppUserDetailBiz
appUserDetailBiz
;
private
final
Integer
POSITION_ID
=
4
;
...
...
xx-order/xx-order-api/src/main/java/com/xxfc/platform/order/feign/OrderFeign.java
View file @
4e08442a
...
...
@@ -3,13 +3,11 @@ package com.xxfc.platform.order.feign;
import
com.github.wxiaoqi.security.auth.client.annotation.IgnoreClientToken
;
import
com.github.wxiaoqi.security.auth.client.annotation.IgnoreUserToken
;
import
com.github.wxiaoqi.security.common.msg.ObjectRestResponse
;
import
com.xxfc.platform.order.entity.OrderInvoice
;
import
com.xxfc.platform.order.pojo.dto.OrderDTO
;
import
com.xxfc.platform.order.pojo.order.OrderPageVO
;
import
org.springframework.cloud.openfeign.FeignClient
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.*
;
import
java.util.List
;
...
...
@@ -27,4 +25,8 @@ public interface OrderFeign {
@GetMapping
(
value
=
"/count/basebase/findByOrderIds"
)
public
ObjectRestResponse
<
List
<
OrderDTO
>>
findOrdersByorderId
(
@RequestParam
(
value
=
"orderIds"
)
List
<
Integer
>
orderIds
);
@PostMapping
(
value
=
"/order/invoice/updateByOrderId"
)
ObjectRestResponse
updateByOrderId
(
@RequestBody
OrderInvoice
orderInvoice
);
}
xx-order/xx-order-server/src/main/java/com/xxfc/platform/order/biz/OrderInvoiceBiz.java
View file @
4e08442a
...
...
@@ -19,6 +19,8 @@ import org.apache.commons.lang3.StringUtils;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.transaction.interceptor.TransactionAspectSupport
;
import
tk.mybatis.mapper.entity.Example
;
import
javax.servlet.http.HttpServletRequest
;
import
java.util.HashSet
;
...
...
@@ -164,4 +166,17 @@ public class OrderInvoiceBiz extends BaseBiz<OrderInvoiceMapper, OrderInvoice> {
}
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
boolean
updateByOrderId
(
OrderInvoice
orderInvoice
)
{
try
{
Example
example
=
new
Example
(
OrderInvoice
.
class
);
example
.
createCriteria
().
andEqualTo
(
"orderIds"
,
orderInvoice
.
getOrderIds
());
mapper
.
updateByExample
(
orderInvoice
,
example
);
return
true
;
}
catch
(
Exception
e
)
{
TransactionAspectSupport
.
currentTransactionStatus
().
setRollbackOnly
();
log
.
error
(
"修改状态异常={}"
,
e
);
return
false
;
}
}
}
xx-order/xx-order-server/src/main/java/com/xxfc/platform/order/rest/OrderInvoiceController.java
View file @
4e08442a
...
...
@@ -47,4 +47,9 @@ public class OrderInvoiceController extends BaseController<OrderInvoiceBiz, Orde
return
baseBiz
.
update
(
orderInvoice
);
}
@PostMapping
(
value
=
"/updateByOrderId"
)
public
ObjectRestResponse
updateByOrderId
(
@RequestBody
OrderInvoice
orderInvoice
)
{
boolean
flag
=
baseBiz
.
updateByOrderId
(
orderInvoice
);
return
ObjectRestResponse
.
succ
();
}
}
xx-universal/xx-universal-api/src/main/java/com/xxfc/platform/universal/constant/InvoiceStatusEum.java
0 → 100644
View file @
4e08442a
package
com
.
xxfc
.
platform
.
universal
.
constant
;
import
lombok.Data
;
/**
* @Auther: Administrator
* @Date: 2020/1/6 18:04
* @Description:
*/
public
enum
InvoiceStatusEum
{
UNBILLED
(
0
,
"未开票"
),
ONGOING
(
1
,
"开票中"
),
SUCCESS
(
2
,
"开票成功"
),
FAILURE
(
3
,
"开票失败"
);
private
Integer
code
;
private
String
msg
;
InvoiceStatusEum
(
int
code
,
String
msg
)
{
this
.
code
=
code
;
this
.
msg
=
msg
;
}
public
Integer
getCode
()
{
return
code
;
}
public
String
getMsg
()
{
return
msg
;
}
}
xx-universal/xx-universal-api/src/main/java/com/xxfc/platform/universal/entity/Invoice.java
0 → 100644
View file @
4e08442a
package
com
.
xxfc
.
platform
.
universal
.
entity
;
import
io.swagger.annotations.ApiModel
;
import
lombok.Data
;
import
javax.persistence.*
;
import
java.math.BigDecimal
;
import
java.util.Date
;
@Data
@Table
(
name
=
"invoice"
)
@ApiModel
public
class
Invoice
{
@Id
@GeneratedValue
(
strategy
=
GenerationType
.
IDENTITY
)
private
Integer
id
;
/**
* 用户id
*/
private
Integer
userId
;
/**
* 订单id :多个以逗号隔开
*/
private
String
orderId
;
/**
* 公司代码
*/
private
String
companyCode
;
/**
* 发票订单号
*/
private
String
orderNo
;
/**
* 机构代码
*/
private
String
orgCode
;
/**
* 发票代码
*/
private
String
invoiceCode
;
/**
* 发票号码
*/
private
String
invoiceNo
;
/**
* 开票日期
*/
private
Date
invoiceDate
;
/**
* 发票分类:01 专票,02 货物运输业增值税专用发票,03 机动车销售统一发票,
* 04 增值税普通发票,10 增值税普通发票(电子),11 增值税普通发票(卷票),14 增值税普通发票(卷票)
*/
private
Integer
invoiceCategory
;
/**
* 合计金额
*/
private
BigDecimal
invoiceAmount
;
/**
* 合计税额
*/
private
BigDecimal
taxAmount
;
/**
* 价税合计总额
*/
private
BigDecimal
invoiceSummaryAmount
;
/**
* 价税合计总额大写
*/
private
String
invoiceSummaryAmountText
;
/**
* 备注
*/
private
String
remark
;
/**
* 验证码
*/
private
String
verifyCode
;
/**
* 机器编号
*/
private
String
machineNo
;
/**
* 密码区
*/
private
String
invoicePassword
;
/**
* 地区
*/
private
String
areaCode
;
/**
* 地区名称
*/
private
String
areaName
;
/**
* 销售方名称
*/
private
String
salerName
;
/**
* 销售方纳税人识别号
*/
private
String
salerTaxCode
;
/**
* 销售方地址
*/
private
String
salerAddress
;
/**
* 销售方电话
*/
private
String
salerPhone
;
/**
* 销售方银行及账户
*/
private
String
salerAccountBank
;
/**
* 购买方名称
*/
private
String
purchaserName
;
/**
* 购买方纳税人识别号
*/
private
String
purchaserTaxCode
;
/**
* 购方手机
*/
private
String
purchaserPhone
;
/**
* 购方邮箱
*/
private
String
purchaserEmail
;
/**
* 购买方地址电话
*/
private
String
purchaserAddressPhone
;
/**
* 购买方银行账号
*/
private
String
purchaserAccountBank
;
/**
* 收款人
*/
private
String
payee
;
/**
* 复核人
*/
private
String
reviewer
;
/**
* 开票人
*/
private
String
issuer
;
// /**
// * 发票状态
// */
// private Integer invoiceStatus;
/**
* 附件
*/
private
String
attachment
;
/**
* 原票代码
*/
private
String
originalCode
;
/**
* 原票号
*/
private
String
originalNo
;
/**
* 查验状态
*/
private
Integer
recognizeFlag
;
/**
* 查验
*/
private
Integer
validState
;
/**
* 开票状态 0:未开票;1:开票中;2:为开票成功;3:开票失败;
*/
private
Integer
status
;
/**
* 发票图片链接
*/
private
String
pictureUrl
;
/**
* 开票类型:1-正票;2-红票
*/
private
Integer
invoiceType
=
1
;
/**
* 开票内容
*/
private
String
content
;
/**
* 推送方式:-1,不推送;0,邮箱;1,手机(默认);2,邮箱、手机
*/
private
Integer
pushMode
=
2
;
/**
* 开票代码
*/
private
String
invoiceSerialNum
;
private
String
createBy
;
private
String
updateBy
;
private
Date
createTime
;
private
Date
updateTime
;
}
xx-universal/xx-universal-api/src/main/java/com/xxfc/platform/universal/entity/InvoiceQueryError.java
0 → 100644
View file @
4e08442a
package
com
.
xxfc
.
platform
.
universal
.
entity
;
import
lombok.Data
;
import
javax.persistence.Table
;
import
java.util.Date
;
/**
* 发票最终查询结果,错误记录表
* @author Administrator
*/
@Data
@Table
(
name
=
"invoice_query_error"
)
public
class
InvoiceQueryError
{
private
Integer
id
;
private
Integer
invoiceId
;
private
String
invoiceSerialNum
;
private
Integer
status
;
private
Date
creTime
;
}
xx-universal/xx-universal-api/src/main/java/com/xxfc/platform/universal/entity/OrderData.java
0 → 100644
View file @
4e08442a
package
com
.
xxfc
.
platform
.
universal
.
entity
;
import
lombok.Data
;
import
java.math.BigDecimal
;
/**
* @Auther: Administrator
* @Date: 2020/1/3 11:20
* @Description:
*/
@Data
public
class
OrderData
{
/**
* 产品名称
*/
private
String
orderName
;
/**
* 产品数量
*/
private
Integer
num
;
/**
* 是否含税价格 0:不含税,1:含税
*/
private
Integer
withTaxFlag
=
1
;
/**
* 产品单价
*/
private
BigDecimal
price
;
/**
* 税率
*/
private
BigDecimal
taxRate
=
new
BigDecimal
(
0.03
);
/**
* 单位
*/
private
String
unit
=
"次"
;
}
xx-universal/xx-universal-api/src/main/java/com/xxfc/platform/universal/entity/vo/InvoiceVo.java
0 → 100644
View file @
4e08442a
package
com
.
xxfc
.
platform
.
universal
.
entity
.
vo
;
import
com.xxfc.platform.universal.entity.OrderData
;
import
lombok.Data
;
import
java.util.List
;
/**
* @Auther: Administrator
* @Date: 2020/1/3 14:43
* @Description:
*/
@Data
public
class
InvoiceVo
{
/**
* 发票分类:01 专票,02 货物运输业增值税专用发票,03 机动车销售统一发票,
* 04 增值税普通发票,10 增值税普通发票(电子),11 增值税普通发票(卷票),14 增值税普通发票(卷票)
*/
private
Integer
invoiceCategory
=
10
;
/**
* 订单id :多个以逗号隔开
*/
private
String
orderId
;
/**
* 备注
*/
private
String
remark
;
/**
* 购买方名称
*/
private
String
purchaserName
;
/**
* 购买方纳税人识别号
*/
private
String
purchaserTaxCode
;
/**
* 购方邮箱
*/
private
String
purchaserEmail
;
/**
* 购买方地址电话
*/
private
String
purchaserAddressPhone
;
/**
* 购买方银行账号
*/
private
String
purchaserAccountBank
;
/**
* 开票内容
*/
private
String
content
;
/**
* 购方手机
*/
private
String
purchaserPhone
;
private
List
<
OrderData
>
orders
;
}
xx-universal/xx-universal-api/src/main/java/com/xxfc/platform/universal/utils/NumberToCN.java
0 → 100644
View file @
4e08442a
package
com
.
xxfc
.
platform
.
universal
.
utils
;
import
java.math.BigDecimal
;
/**
*
*
* 数字转换为汉语中人民币的大写<br>
*
*/
public
class
NumberToCN
{
/**
* 汉语中数字大写
*/
private
static
final
String
[]
CN_UPPER_NUMBER
=
{
"零"
,
"壹"
,
"贰"
,
"叁"
,
"肆"
,
"伍"
,
"陆"
,
"柒"
,
"捌"
,
"玖"
};
/**
* 汉语中货币单位大写,这样的设计类似于占位符
*/
private
static
final
String
[]
CN_UPPER_MONETRAY_UNIT
=
{
"分"
,
"角"
,
"元"
,
"拾"
,
"佰"
,
"仟"
,
"万"
,
"拾"
,
"佰"
,
"仟"
,
"亿"
,
"拾"
,
"佰"
,
"仟"
,
"兆"
,
"拾"
,
"佰"
,
"仟"
};
/**
* 特殊字符:整
*/
private
static
final
String
CN_FULL
=
"整"
;
/**
* 特殊字符:负
*/
private
static
final
String
CN_NEGATIVE
=
"负"
;
/**
* 金额的精度,默认值为2
*/
private
static
final
int
MONEY_PRECISION
=
2
;
/**
* 特殊字符:零元整
*/
private
static
final
String
CN_ZEOR_FULL
=
"零元"
+
CN_FULL
;
/**
* 把输入的金额转换为汉语中人民币的大写
*
* @param numberOfMoney
* 输入的金额
* @return 对应的汉语大写
*/
public
static
String
number2CNMontrayUnit
(
BigDecimal
numberOfMoney
)
{
StringBuffer
sb
=
new
StringBuffer
();
// -1, 0, or 1 as the value of this BigDecimal is negative, zero, or
// positive.
int
signum
=
numberOfMoney
.
signum
();
// 零元整的情况
if
(
signum
==
0
)
{
return
CN_ZEOR_FULL
;
}
// 这里会进行金额的四舍五入
long
number
=
numberOfMoney
.
movePointRight
(
MONEY_PRECISION
)
.
setScale
(
0
,
4
).
abs
().
longValue
();
// 得到小数点后两位值
long
scale
=
number
%
100
;
int
numUnit
=
0
;
int
numIndex
=
0
;
boolean
getZero
=
false
;
// 判断最后两位数,一共有四中情况:00 = 0, 01 = 1, 10, 11
if
(!(
scale
>
0
))
{
numIndex
=
2
;
number
=
number
/
100
;
getZero
=
true
;
}
if
((
scale
>
0
)
&&
(!(
scale
%
10
>
0
)))
{
numIndex
=
1
;
number
=
number
/
10
;
getZero
=
true
;
}
int
zeroSize
=
0
;
while
(
true
)
{
if
(
number
<=
0
)
{
break
;
}
// 每次获取到最后一个数
numUnit
=
(
int
)
(
number
%
10
);
if
(
numUnit
>
0
)
{
if
((
numIndex
==
9
)
&&
(
zeroSize
>=
3
))
{
sb
.
insert
(
0
,
CN_UPPER_MONETRAY_UNIT
[
6
]);
}
if
((
numIndex
==
13
)
&&
(
zeroSize
>=
3
))
{
sb
.
insert
(
0
,
CN_UPPER_MONETRAY_UNIT
[
10
]);
}
sb
.
insert
(
0
,
CN_UPPER_MONETRAY_UNIT
[
numIndex
]);
sb
.
insert
(
0
,
CN_UPPER_NUMBER
[
numUnit
]);
getZero
=
false
;
zeroSize
=
0
;
}
else
{
++
zeroSize
;
if
(!(
getZero
))
{
sb
.
insert
(
0
,
CN_UPPER_NUMBER
[
numUnit
]);
}
if
(
numIndex
==
2
)
{
if
(
number
>
0
)
{
sb
.
insert
(
0
,
CN_UPPER_MONETRAY_UNIT
[
numIndex
]);
}
}
else
if
(((
numIndex
-
2
)
%
4
==
0
)
&&
(
number
%
1000
>
0
))
{
sb
.
insert
(
0
,
CN_UPPER_MONETRAY_UNIT
[
numIndex
]);
}
getZero
=
true
;
}
// 让number每次都去掉最后一个数
number
=
number
/
10
;
++
numIndex
;
}
// 如果signum == -1,则说明输入的数字为负数,就在最前面追加特殊字符:负
if
(
signum
==
-
1
)
{
sb
.
insert
(
0
,
CN_NEGATIVE
);
}
// 输入的数字小数点后两位为"00"的情况,则要在最后追加特殊字符:整
if
(!(
scale
>
0
))
{
sb
.
append
(
CN_FULL
);
}
return
sb
.
toString
();
}
public
static
void
main
(
String
[]
args
)
{
double
money
=
2500.32
;
BigDecimal
numberOfMoney
=
new
BigDecimal
(
money
);
String
s
=
NumberToCN
.
number2CNMontrayUnit
(
numberOfMoney
);
System
.
out
.
println
(
"你输入的金额为:【"
+
money
+
"】 #--# ["
+
s
.
toString
()
+
"]"
);
}
}
\ No newline at end of file
xx-universal/xx-universal-api/src/main/java/com/xxfc/platform/universal/utils/SnowflakeIdWorker.java
0 → 100644
View file @
4e08442a
package
com
.
xxfc
.
platform
.
universal
.
utils
;
public
class
SnowflakeIdWorker
{
// ==============================Fields==================
/** 开始时间截 (2019-01-07) */
private
final
long
twepoch
=
1578326400000L
;
/** 机器id所占的位数 */
private
final
long
workerIdBits
=
5L
;
/** 数据标识id所占的位数 */
private
final
long
datacenterIdBits
=
5L
;
/** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */
private
final
long
maxWorkerId
=
-
1L
^
(-
1L
<<
workerIdBits
);
/** 支持的最大数据标识id,结果是31 */
private
final
long
maxDatacenterId
=
-
1L
^
(-
1L
<<
datacenterIdBits
);
/** 序列在id中占的位数 */
private
final
long
sequenceBits
=
12L
;
/** 机器ID向左移12位 */
private
final
long
workerIdShift
=
sequenceBits
;
/** 数据标识id向左移17位(12+5) */
private
final
long
datacenterIdShift
=
sequenceBits
+
workerIdBits
;
/** 时间截向左移22位(5+5+12) */
private
final
long
timestampLeftShift
=
sequenceBits
+
workerIdBits
+
datacenterIdBits
;
/** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */
private
final
long
sequenceMask
=
-
1L
^
(-
1L
<<
sequenceBits
);
/** 工作机器ID(0~31) */
private
long
workerId
;
/** 数据中心ID(0~31) */
private
long
datacenterId
;
/** 毫秒内序列(0~4095) */
private
long
sequence
=
0L
;
/** 上次生成ID的时间截 */
private
long
lastTimestamp
=
-
1L
;
//==============================Constructors====================
/**
* 构造函数
* @param workerId 工作ID (0~31)
* @param datacenterId 数据中心ID (0~31)
*/
public
SnowflakeIdWorker
(
long
workerId
,
long
datacenterId
)
{
if
(
workerId
>
maxWorkerId
||
workerId
<
0
)
{
throw
new
IllegalArgumentException
(
String
.
format
(
"worker Id can't be greater than %d or less than 0"
,
maxWorkerId
));
}
if
(
datacenterId
>
maxDatacenterId
||
datacenterId
<
0
)
{
throw
new
IllegalArgumentException
(
String
.
format
(
"datacenter Id can't be greater than %d or less than 0"
,
maxDatacenterId
));
}
this
.
workerId
=
workerId
;
this
.
datacenterId
=
datacenterId
;
}
// ==============================Methods=================================
/**
* 获得下一个ID (该方法是线程安全的)
* @return SnowflakeId
*/
public
synchronized
long
nextId
()
{
long
timestamp
=
timeGen
();
//如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
if
(
timestamp
<
lastTimestamp
)
{
throw
new
RuntimeException
(
String
.
format
(
"Clock moved backwards. Refusing to generate id for %d milliseconds"
,
lastTimestamp
-
timestamp
));
}
//如果是同一时间生成的,则进行毫秒内序列
if
(
lastTimestamp
==
timestamp
)
{
sequence
=
(
sequence
+
1
)
&
sequenceMask
;
//毫秒内序列溢出
if
(
sequence
==
0
)
{
//阻塞到下一个毫秒,获得新的时间戳
timestamp
=
tilNextMillis
(
lastTimestamp
);
}
}
//时间戳改变,毫秒内序列重置
else
{
sequence
=
0L
;
}
//上次生成ID的时间截
lastTimestamp
=
timestamp
;
//移位并通过或运算拼到一起组成64位的ID
return
((
timestamp
-
twepoch
)
<<
timestampLeftShift
)
//
|
(
datacenterId
<<
datacenterIdShift
)
//
|
(
workerId
<<
workerIdShift
)
//
|
sequence
;
}
/**
* 阻塞到下一个毫秒,直到获得新的时间戳
* @param lastTimestamp 上次生成ID的时间截
* @return 当前时间戳
*/
protected
long
tilNextMillis
(
long
lastTimestamp
)
{
long
timestamp
=
timeGen
();
while
(
timestamp
<=
lastTimestamp
)
{
timestamp
=
timeGen
();
}
return
timestamp
;
}
/**
* 返回以毫秒为单位的当前时间
* @return 当前时间(毫秒)
*/
protected
long
timeGen
()
{
return
System
.
currentTimeMillis
();
}
//==============================Test=============================================
/** 测试 */
public
static
void
main
(
String
[]
args
)
{
SnowflakeIdWorker
idWorker
=
new
SnowflakeIdWorker
(
0
,
0
);
for
(
int
i
=
0
;
i
<
1000
;
i
++)
{
long
id
=
idWorker
.
nextId
();
System
.
out
.
println
(
Long
.
toBinaryString
(
id
));
System
.
out
.
println
(
id
);
}
}
}
\ No newline at end of file
xx-universal/xx-universal-server/pom.xml
View file @
4e08442a
...
...
@@ -105,6 +105,18 @@
<version>
2.0-SNAPSHOT
</version>
<scope>
compile
</scope>
</dependency>
<!-- 诺诺发票sdk-->
<dependency>
<groupId>
com.nuonuo
</groupId>
<artifactId>
open-sdk
</artifactId>
<version>
1.0.3
</version>
</dependency>
<dependency>
<groupId>
com.xxfc.platform
</groupId>
<artifactId>
xx-order-api
</artifactId>
<version>
2.0-SNAPSHOT
</version>
<scope>
compile
</scope>
</dependency>
</dependencies>
<build>
...
...
xx-universal/xx-universal-server/src/main/java/com/xxfc/platform/universal/biz/InvoiceQueryErrorBiz.java
0 → 100644
View file @
4e08442a
package
com
.
xxfc
.
platform
.
universal
.
biz
;
import
com.github.wxiaoqi.security.common.biz.BaseBiz
;
import
com.xxfc.platform.universal.entity.InvoiceQueryError
;
import
com.xxfc.platform.universal.mapper.InvoiceQueryErrorMapper
;
import
org.springframework.stereotype.Service
;
/**
* @Auther: Administrator
* @Date: 2020/1/8 10:48
* @Description:
*/
@Service
public
class
InvoiceQueryErrorBiz
extends
BaseBiz
<
InvoiceQueryErrorMapper
,
InvoiceQueryError
>
{
}
xx-universal/xx-universal-server/src/main/java/com/xxfc/platform/universal/controller/InvoiceController.java
0 → 100644
View file @
4e08442a
package
com
.
xxfc
.
platform
.
universal
.
controller
;
import
com.github.wxiaoqi.security.common.msg.ObjectRestResponse
;
import
com.github.wxiaoqi.security.common.rest.BaseController
;
import
com.xxfc.platform.universal.entity.Invoice
;
import
com.xxfc.platform.universal.entity.vo.InvoiceVo
;
import
com.xxfc.platform.universal.service.InvoiceBiz
;
import
org.springframework.web.bind.annotation.*
;
import
java.util.List
;
import
java.util.Map
;
/**
* 发票接口
* @Auther: Administrator
* @Date: 2019/12/31 09:57
* @Description:
*/
@RestController
@RequestMapping
(
"/invoice"
)
public
class
InvoiceController
extends
BaseController
<
InvoiceBiz
,
Invoice
>
{
/**
* 根据开票代码获取税号
* @param code
* @return
*/
@GetMapping
(
"/dutyParagraph"
)
public
ObjectRestResponse
getDutyParagraphByCode
(
@RequestParam
(
"code"
)
String
code
){
String
dutyParagraph
=
baseBiz
.
getDutyParagraphByCode
(
code
);
return
ObjectRestResponse
.
succ
(
dutyParagraph
);
}
/**
* 模糊查询获取公司全名和开票代码
* @param name
* @return
*/
@GetMapping
(
"/corporateName"
)
public
ObjectRestResponse
corporateName
(
@RequestParam
(
"name"
)
String
name
){
List
<
Map
<
String
,
String
>>
mapList
=
baseBiz
.
corporateName
(
name
);
return
ObjectRestResponse
.
succ
(
mapList
);
}
@PostMapping
(
"/invoicing"
)
public
ObjectRestResponse
invoicing
(
@RequestBody
InvoiceVo
invoiceVo
)
throws
Exception
{
String
invoicing
=
baseBiz
.
Invoicing
(
invoiceVo
);
return
ObjectRestResponse
.
succ
(
invoicing
);
}
@GetMapping
(
"/result"
)
public
ObjectRestResponse
invoiceResult
(
@RequestParam
(
"invoiceSerialNum"
)
String
invoiceSerialNum
){
List
<
Map
<
String
,
Object
>>
result
=
baseBiz
.
invoiceResult
(
invoiceSerialNum
);
return
ObjectRestResponse
.
succ
(
result
);
}
}
xx-universal/xx-universal-server/src/main/java/com/xxfc/platform/universal/mapper/InvoiceMapper.java
0 → 100644
View file @
4e08442a
package
com
.
xxfc
.
platform
.
universal
.
mapper
;
import
com.xxfc.platform.universal.entity.Invoice
;
import
tk.mybatis.mapper.common.Mapper
;
/**
* @author Administrator
* @Auther: Administrator
* @Date: 2020/1/6 16:38
* @Description:
*/
public
interface
InvoiceMapper
extends
Mapper
<
Invoice
>
{
}
xx-universal/xx-universal-server/src/main/java/com/xxfc/platform/universal/mapper/InvoiceQueryErrorMapper.java
0 → 100644
View file @
4e08442a
package
com
.
xxfc
.
platform
.
universal
.
mapper
;
import
com.xxfc.platform.universal.entity.InvoiceQueryError
;
import
tk.mybatis.mapper.common.Mapper
;
/**
* @author Administrator
* @Date: 2020/1/8 10:49
* @Description:
*/
public
interface
InvoiceQueryErrorMapper
extends
Mapper
<
InvoiceQueryError
>
{
}
xx-universal/xx-universal-server/src/main/java/com/xxfc/platform/universal/service/InvoiceBiz.java
0 → 100644
View file @
4e08442a
This diff is collapsed.
Click to expand it.
xx-universal/xx-universal-server/src/main/java/com/xxfc/platform/universal/service/invoice/InvoiceDao.java
0 → 100644
View file @
4e08442a
package
com
.
xxfc
.
platform
.
universal
.
service
.
invoice
;
import
com.xxfc.platform.universal.entity.Invoice
;
import
com.xxfc.platform.universal.entity.OrderData
;
import
java.util.List
;
import
java.util.Map
;
/**
* @Auther: Administrator
* @Date: 2019/12/31 10:23
* @Description:
*/
public
interface
InvoiceDao
{
List
<
Map
<
String
,
String
>>
corporateName
(
String
name
);
String
getDutyParagraphByCode
(
String
code
);
String
Invoicing
(
Invoice
invoice
,
List
<
OrderData
>
orders
);
List
<
Map
<
String
,
Object
>>
invoiceResult
(
String
invoiceSerialNum
);
}
xx-universal/xx-universal-server/src/main/java/com/xxfc/platform/universal/service/invoice/impl/InvoiceDaoImpl.java
0 → 100644
View file @
4e08442a
package
com
.
xxfc
.
platform
.
universal
.
service
.
invoice
.
impl
;
import
cn.hutool.core.collection.CollectionUtil
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.github.wxiaoqi.security.common.exception.BaseException
;
import
com.google.common.collect.Lists
;
import
com.xxfc.platform.universal.entity.Invoice
;
import
com.xxfc.platform.universal.entity.OrderData
;
import
com.xxfc.platform.universal.service.invoice.InvoiceDao
;
import
lombok.extern.slf4j.Slf4j
;
import
nuonuo.open.sdk.NNOpenSDK
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.context.annotation.Primary
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.stereotype.Service
;
import
java.text.SimpleDateFormat
;
import
java.util.*
;
import
java.util.concurrent.TimeUnit
;
/**
* @Auther: Administrator
* @Date: 2019/12/31 10:26
* @Description:
*/
@Service
@Primary
@Slf4j
public
class
InvoiceDaoImpl
implements
InvoiceDao
{
@Autowired
private
RedisTemplate
redisTemplate
;
/**
* 诺诺-极速开票
*/
@Value
(
"${invoice.nuonuo.js.taxnum}"
)
private
String
taxnum
;
@Value
(
"${invoice.nuonuo.js.appKey}"
)
private
String
appKey
;
@Value
(
"${invoice.nuonuo.js.appSecret}"
)
private
String
appSecret
;
/**
* 诺诺-诺诺发票
*/
@Value
(
"${invoice.nuonuo.nn.taxnum}"
)
private
String
taxnum2
;
@Value
(
"${invoice.nuonuo.nn.appKey}"
)
private
String
appKey2
;
@Value
(
"${invoice.nuonuo.nn.appSecret}"
)
private
String
appSecret2
;
@Value
(
"${invoice.nuonuo.queryUrl}"
)
private
String
queryUrl
;
@Value
(
"${invoice.nuonuo.invoiceUrl}"
)
private
String
invoiceUrl
;
/**
* 给定的部分名,获取税号
*
* @param name
* @return
*/
@Override
public
List
<
Map
<
String
,
String
>>
corporateName
(
String
name
)
{
NNOpenSDK
sdk
=
NNOpenSDK
.
getIntance
();
HashMap
<
String
,
String
>
map
=
new
HashMap
();
map
.
put
(
"q"
,
name
);
String
content
=
JSON
.
toJSONString
(
map
);
//方法名
String
method
=
"nuonuo.speedBilling.prefixQuery"
;
// SDK请求地址
String
url
=
"https://sdk.nuonuo.com/open/v1/services"
;
// 唯一标识,由企业自己生成32位随机码
String
senid
=
UUID
.
randomUUID
().
toString
().
replace
(
"-"
,
""
);
String
result
=
sdk
.
sendPostSyncRequest
(
url
,
senid
,
appKey
,
appSecret
,
getTokenJS
(),
taxnum
,
method
,
content
);
JSONObject
jsonObject
=
JSON
.
parseObject
(
result
);
List
<
Map
<
String
,
String
>>
mapList
=
(
List
<
Map
<
String
,
String
>>)
jsonObject
.
get
(
"result"
);
if
(
CollectionUtil
.
isNotEmpty
(
mapList
))
{
return
mapList
;
}
return
new
ArrayList
<>();
}
/**
* 根据开票代码,调用第三方接口获取税号
*
* @param code
* @return
*/
@Override
public
String
getDutyParagraphByCode
(
String
code
)
{
NNOpenSDK
sdk
=
NNOpenSDK
.
getIntance
();
// API方法名
String
method
=
"nuonuo.speedBilling.queryNameAndTaxByCode"
;
// SDK请求地址
String
url
=
"https://sdk.jss.com.cn/open/v1/services"
;
HashMap
<
String
,
String
>
map
=
new
HashMap
();
map
.
put
(
"code"
,
code
);
String
content
=
JSON
.
toJSONString
(
map
);
// 唯一标识,由企业自己生成32位随机码
String
senid
=
UUID
.
randomUUID
().
toString
().
replace
(
"-"
,
""
);
String
result
=
sdk
.
sendPostSyncRequest
(
url
,
senid
,
appKey
,
appSecret
,
getTokenJS
(),
taxnum
,
method
,
content
);
JSONObject
jsonObject
=
JSON
.
parseObject
(
result
);
Map
<
String
,
String
>
resultMap
=
(
Map
<
String
,
String
>)
jsonObject
.
get
(
"result"
);
return
resultMap
.
get
(
"kpCode"
);
}
/**
* 调用第三方开票接口进行开票
* @param invoice
* @param orders
* @return
*/
@Override
public
String
Invoicing
(
Invoice
invoice
,
List
<
OrderData
>
orders
)
{
NNOpenSDK
sdk
=
NNOpenSDK
.
getIntance
();
// API方法名
String
method
=
"nuonuo.electronInvoice.requestBilling"
;
String
senid
=
UUID
.
randomUUID
().
toString
().
replace
(
"-"
,
""
);
HashMap
<
String
,
Object
>
map
=
new
HashMap
<>();
HashMap
<
String
,
Map
<
String
,
Object
>>
orderMap
=
new
HashMap
<>();
orderMap
.
put
(
"order"
,
map
);
//购方信息
map
.
put
(
"buyerName"
,
invoice
.
getPurchaserName
());
map
.
put
(
"buyerTaxNum"
,
invoice
.
getPurchaserTaxCode
());
// map.put("buyerTel", invoice.getPurchaserPhone());
map
.
put
(
"buyerAddress"
,
invoice
.
getPurchaserAddressPhone
());
map
.
put
(
"buyerAccount"
,
invoice
.
getPurchaserAccountBank
());
map
.
put
(
"buyerPhone"
,
invoice
.
getPurchaserPhone
());
map
.
put
(
"email"
,
invoice
.
getPurchaserEmail
());
map
.
put
(
"remark"
,
invoice
.
getRemark
());
SimpleDateFormat
dateFormat
=
new
SimpleDateFormat
(
"yyyy-MM-dd HH:mm:ss"
);
//销方信息
map
.
put
(
"orderNo"
,
invoice
.
getOrderNo
());
map
.
put
(
"invoiceDate"
,
dateFormat
.
format
(
invoice
.
getInvoiceDate
()));
map
.
put
(
"salerName"
,
invoice
.
getSalerName
());
map
.
put
(
"salerTaxNum"
,
invoice
.
getSalerTaxCode
());
map
.
put
(
"salerTel"
,
invoice
.
getSalerPhone
());
map
.
put
(
"salerAddress"
,
invoice
.
getSalerAddress
());
map
.
put
(
"salerAccount"
,
invoice
.
getSalerAccountBank
());
map
.
put
(
"clerk"
,
invoice
.
getIssuer
());
map
.
put
(
"payee"
,
invoice
.
getPayee
());
map
.
put
(
"checker"
,
invoice
.
getReviewer
());
//其他设置
map
.
put
(
"pushMode"
,
String
.
valueOf
(
invoice
.
getPushMode
()));
map
.
put
(
"invoiceType"
,
String
.
valueOf
(
invoice
.
getInvoiceType
()));
//订单信息
ArrayList
<
Map
<
String
,
String
>>
arrayList
=
Lists
.
newArrayList
();
map
.
put
(
"invoiceDetail"
,
arrayList
);
for
(
OrderData
order
:
orders
)
{
HashMap
<
String
,
String
>
mx
=
new
HashMap
<>();
mx
.
put
(
"goodsName"
,
invoice
.
getContent
());
mx
.
put
(
"num"
,
String
.
valueOf
(
order
.
getNum
()));
//单价含税标志,0:不含税,1:含税
mx
.
put
(
"withTaxFlag"
,
String
.
valueOf
(
order
.
getWithTaxFlag
()));
mx
.
put
(
"price"
,
String
.
valueOf
(
order
.
getPrice
()));
mx
.
put
(
"taxRate"
,
String
.
valueOf
(
order
.
getTaxRate
()));
mx
.
put
(
"unit"
,
order
.
getUnit
());
mx
.
put
(
"specType"
,
order
.
getOrderName
());
arrayList
.
add
(
mx
);
}
String
token
=
getTokenFP
();
String
jsonString
=
JSON
.
toJSONString
(
orderMap
);
//调用第三方接口
String
result
=
sdk
.
sendPostSyncRequest
(
invoiceUrl
,
senid
,
appKey2
,
appSecret2
,
token
,
taxnum2
,
method
,
jsonString
);
log
.
info
(
"result={}"
,
result
);
//把字符串json数据转换为map
JSONObject
jsonObject
=
JSON
.
parseObject
(
result
);
Map
<
String
,
String
>
data
=
(
Map
<
String
,
String
>)
jsonObject
.
get
(
"result"
);
String
invoiceSerialNum
=
data
.
get
(
"invoiceSerialNum"
);
if
(
StringUtils
.
isBlank
(
invoiceSerialNum
))
{
log
.
error
(
"失败原因={}"
,
result
);
throw
new
BaseException
(
"开票失败"
);
}
return
invoiceSerialNum
;
}
@Override
public
List
<
Map
<
String
,
Object
>>
invoiceResult
(
String
invoiceSerialNum
)
{
NNOpenSDK
sdk
=
NNOpenSDK
.
getIntance
();
// API方法名
String
method
=
"nuonuo.electronInvoice.CheckEInvoice"
;
HashMap
<
String
,
List
<
String
>>
map
=
new
HashMap
<>();
ArrayList
<
String
>
arrayList
=
Lists
.
newArrayList
();
arrayList
.
add
(
invoiceSerialNum
);
map
.
put
(
"invoiceSerialNum"
,
arrayList
);
String
content
=
JSON
.
toJSONString
(
map
);
// 唯一标识,由企业自己生成32位随机码
String
senid
=
UUID
.
randomUUID
().
toString
().
replace
(
"-"
,
""
);
String
data
=
null
;
try
{
data
=
sdk
.
sendPostSyncRequest
(
queryUrl
,
senid
,
appKey2
,
appSecret2
,
getTokenFP
(),
taxnum2
,
method
,
content
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
if
(
data
!=
null
){
try
{
JSONObject
jsonObject
=
JSON
.
parseObject
(
data
);
List
<
Map
<
String
,
Object
>>
mapList
=
(
List
<
Map
<
String
,
Object
>>)
jsonObject
.
get
(
"result"
);
return
mapList
;
}
catch
(
Exception
e
)
{
throw
new
BaseException
(
"发票请求流水号错误"
);
}
}
return
null
;
}
/**
* 获取极速开票token
*/
private
String
getTokenJS
()
{
return
getToken
(
appKey
,
appSecret
);
}
/**
* 获取诺诺发票token
*/
public
String
getTokenFP
()
{
return
getToken
(
appKey2
,
appSecret2
);
}
private
String
getToken
(
String
appKey
,
String
appSecret
)
{
String
token
=
(
String
)
redisTemplate
.
opsForValue
().
get
(
appKey
);
if
(
StringUtils
.
isBlank
(
token
))
{
String
json
=
NNOpenSDK
.
getIntance
().
getMerchantToken
(
appKey
,
appSecret
);
log
.
info
(
"token={}"
,
json
);
JSONObject
jsonObject
=
JSONObject
.
parseObject
(
json
);
token
=
(
String
)
jsonObject
.
get
(
"access_token"
);
if
(
StringUtils
.
isBlank
(
token
))
{
throw
new
BaseException
(
"获取极速开票token失败"
);
}
redisTemplate
.
opsForValue
().
set
(
appKey
,
token
,
23
,
TimeUnit
.
HOURS
);
}
return
token
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment