统一修改ruoyi->bms
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
package com.bms;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
/**
|
||||
* 启动程序
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@EnableAsync
|
||||
@EnableScheduling
|
||||
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
|
||||
public class BmsApplication
|
||||
{
|
||||
public static void main(String[] args)
|
||||
{
|
||||
// System.setProperty("spring.devtools.restart.enabled", "false");
|
||||
SpringApplication.run(BmsApplication.class, args);
|
||||
System.out.println("(♥◠‿◠)ノ゙ 启动成功 ლ(´ڡ`ლ)゙ \n" +
|
||||
" .-------. ____ __ \n" +
|
||||
" | _ _ \\ \\ \\ / / \n" +
|
||||
" | ( ' ) | \\ _. / ' \n" +
|
||||
" |(_ o _) / _( )_ .' \n" +
|
||||
" | (_,_).' __ ___(_ o _)' \n" +
|
||||
" | |\\ \\ | || |(_,_)' \n" +
|
||||
" | | \\ `' /| `-' / \n" +
|
||||
" | | \\ / \\ / \n" +
|
||||
" ''-' `'-' `-..-' ");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.bms;
|
||||
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
|
||||
/**
|
||||
* web容器中进行部署
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
public class BmsServletInitializer extends SpringBootServletInitializer
|
||||
{
|
||||
@Override
|
||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
|
||||
{
|
||||
return application.sources(BmsApplication.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.bms.web.controller.api;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.exception.ServiceException;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.price.search.EsBizLogSupport;
|
||||
import com.bms.price.search.IBillSearchStore;
|
||||
import com.bms.web.controller.price.BillingController;
|
||||
|
||||
/**
|
||||
* Persist quote/bill API failures to Elasticsearch (validation, JSON parse, business, unexpected).
|
||||
* Uses {@link EsBizLogSupport#saveApiFail} so service/controller can also call without duplicate docs.
|
||||
*/
|
||||
@Order(0)
|
||||
@RestControllerAdvice(assignableTypes = { TmsPriceController.class, BillingController.class })
|
||||
public class PriceSyncEsLogAdvice
|
||||
{
|
||||
@Autowired
|
||||
private IBillSearchStore billSearchStore;
|
||||
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public AjaxResult handleValid(MethodArgumentNotValidException e, HttpServletRequest request)
|
||||
{
|
||||
String message = e.getBindingResult().getFieldError() == null
|
||||
? e.getMessage()
|
||||
: e.getBindingResult().getFieldError().getDefaultMessage();
|
||||
saveFail(request, e.getBindingResult().getTarget(), message);
|
||||
return AjaxResult.error(message);
|
||||
}
|
||||
|
||||
@ExceptionHandler(BindException.class)
|
||||
public AjaxResult handleBind(BindException e, HttpServletRequest request)
|
||||
{
|
||||
String message = e.getAllErrors().isEmpty() ? e.getMessage() : e.getAllErrors().get(0).getDefaultMessage();
|
||||
saveFail(request, e.getTarget(), message);
|
||||
return AjaxResult.error(message);
|
||||
}
|
||||
|
||||
@ExceptionHandler(HttpMessageNotReadableException.class)
|
||||
public AjaxResult handleNotReadable(HttpMessageNotReadableException e, HttpServletRequest request)
|
||||
{
|
||||
String message = EsBizLogSupport.errorText(e);
|
||||
saveFail(request, null, message);
|
||||
return AjaxResult.error(message);
|
||||
}
|
||||
|
||||
@ExceptionHandler(ServiceException.class)
|
||||
public AjaxResult handleService(ServiceException e, HttpServletRequest request)
|
||||
{
|
||||
saveFail(request, null, e);
|
||||
Integer code = e.getCode();
|
||||
return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
public AjaxResult handleAny(Exception e, HttpServletRequest request)
|
||||
{
|
||||
saveFail(request, null, e);
|
||||
return AjaxResult.error(EsBizLogSupport.errorText(e));
|
||||
}
|
||||
|
||||
private void saveFail(HttpServletRequest request, Object boundTarget, Throwable e)
|
||||
{
|
||||
if (!EsBizLogSupport.isPriceSyncWriteApi(request))
|
||||
{
|
||||
return;
|
||||
}
|
||||
EsBizLogSupport.saveApiFail(billSearchStore, request, boundTarget, e);
|
||||
}
|
||||
|
||||
private void saveFail(HttpServletRequest request, Object boundTarget, String message)
|
||||
{
|
||||
if (!EsBizLogSupport.isPriceSyncWriteApi(request))
|
||||
{
|
||||
return;
|
||||
}
|
||||
EsBizLogSupport.saveApiFail(billSearchStore, request, boundTarget, message);
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
package com.bms.web.controller.api;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Anonymous;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.exception.ServiceException;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.framework.config.properties.TmsApiProperties;
|
||||
import com.bms.price.domain.vo.TmsOrderBillStatusResult;
|
||||
import com.bms.price.service.IPrcOrderBillService;
|
||||
|
||||
/**
|
||||
* TMS 订单客户状态查询接口。
|
||||
*
|
||||
* <p>该接口不要求登录 Token,但必须携带 X-Api-Code。
|
||||
* identifier 会按订单号、运单号、转单号进行精确匹配。</p>
|
||||
*/
|
||||
@Anonymous
|
||||
@RestController
|
||||
@RequestMapping("/api/tms/order-bill")
|
||||
public class TmsOrderBillStatusController extends BaseController {
|
||||
private static final String HEADER_API_CODE = "X-Api-Code";
|
||||
|
||||
@Autowired
|
||||
private IPrcOrderBillService prcOrderBillService;
|
||||
|
||||
@Autowired
|
||||
private TmsApiProperties tmsApiProperties;
|
||||
|
||||
/**
|
||||
* 查询订单对应客户是否正常、额度是否欠费。
|
||||
*
|
||||
* <p>接口只返回查询事实和状态字段,不判断上游是否继续处理。</p>
|
||||
*/
|
||||
@GetMapping("/status")
|
||||
public AjaxResult status(
|
||||
@RequestHeader(value = HEADER_API_CODE, required = false) String headerApiCode,
|
||||
@RequestParam(value = "identifier", required = false) String identifier) {
|
||||
assertApiCode(headerApiCode);
|
||||
TmsOrderBillStatusResult result = prcOrderBillService.queryTmsOrderBillStatus(identifier);
|
||||
return success(result);
|
||||
}
|
||||
|
||||
private void assertApiCode(String headerApiCode) {
|
||||
String expected = tmsApiProperties.getApiCode();
|
||||
if (StringUtils.isEmpty(expected)) {
|
||||
throw new ServiceException("API_CODE_NOT_CONFIGURED: bms.tms.api-code is empty");
|
||||
}
|
||||
if (StringUtils.isEmpty(headerApiCode) || !expected.equals(headerApiCode.trim())) {
|
||||
throw new ServiceException("API_CODE_INVALID: missing or invalid X-Api-Code");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
package com.bms.web.controller.api;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Anonymous;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.exception.ServiceException;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.framework.config.properties.TmsApiProperties;
|
||||
import com.bms.price.domain.vo.BillingTaskSubmitRequest;
|
||||
import com.bms.price.domain.vo.TmsPriceBillRequest;
|
||||
import com.bms.price.domain.vo.TmsPriceQuoteRequest;
|
||||
import com.bms.price.domain.vo.TmsPriceQuoteResult;
|
||||
import com.bms.price.domain.PrcBillingTask;
|
||||
import com.bms.price.search.EsBizLogSupport;
|
||||
import com.bms.price.search.EsLogType;
|
||||
import com.bms.price.search.IBillSearchStore;
|
||||
import com.bms.price.service.IPrcBillingTaskService;
|
||||
import com.bms.price.service.IPrcOrderBillService;
|
||||
import com.bms.price.service.ITmsPriceQuoteService;
|
||||
|
||||
/**
|
||||
* TMS open API: freight quote.
|
||||
*
|
||||
* POST /api/tms/price/quote
|
||||
* Header X-Api-Code must equal bms.tms.api-code
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@Anonymous
|
||||
@RestController
|
||||
@RequestMapping("/api/tms/price")
|
||||
public class TmsPriceController extends BaseController
|
||||
{
|
||||
public static final String HEADER_API_CODE = "X-Api-Code";
|
||||
|
||||
@Autowired
|
||||
private ITmsPriceQuoteService tmsPriceQuoteService;
|
||||
|
||||
@Autowired
|
||||
private IPrcOrderBillService prcOrderBillService;
|
||||
|
||||
@Autowired
|
||||
private IPrcBillingTaskService prcBillingTaskService;
|
||||
|
||||
@Autowired
|
||||
private TmsApiProperties tmsApiProperties;
|
||||
|
||||
@Autowired
|
||||
private IBillSearchStore billSearchStore;
|
||||
|
||||
/**
|
||||
* Quote by customer + product + country + weight (+ destPostcode when country has zones).
|
||||
* Zone resolve: destPostcode -> prc_zone_detail/prc_zone -> bms_product_country.zone_code.
|
||||
* Match: customer package FIXED > DISCOUNT > product default.
|
||||
*/
|
||||
@PostMapping("/quote")
|
||||
public AjaxResult quote(
|
||||
@RequestHeader(value = HEADER_API_CODE, required = false) String headerApiCode,
|
||||
@Validated @RequestBody TmsPriceQuoteRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
assertApiCode(headerApiCode, request == null ? null : request.getApiCode());
|
||||
}
|
||||
catch (ServiceException e)
|
||||
{
|
||||
EsBizLogSupport.saveFail(billSearchStore, EsLogType.QUOTE, EsBizLogSupport.quoteFailBizId(request),
|
||||
request, e);
|
||||
throw e;
|
||||
}
|
||||
TmsPriceQuoteResult result = tmsPriceQuoteService.quote(request);
|
||||
return success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync order and persist prc_order_bill / prc_income_bill_fee.
|
||||
* Same price match as quote (bound set + active version by bizDate, else default).
|
||||
* Same orderNo upserts.
|
||||
*/
|
||||
@PostMapping("/bill")
|
||||
public AjaxResult bill(
|
||||
@RequestHeader(value = HEADER_API_CODE, required = false) String headerApiCode,
|
||||
@Validated @RequestBody TmsPriceBillRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
assertApiCode(headerApiCode, request == null ? null : request.getApiCode());
|
||||
}
|
||||
catch (ServiceException e)
|
||||
{
|
||||
EsBizLogSupport.saveFail(billSearchStore, EsLogType.BILL, EsBizLogSupport.billFailBizId(request), request, e);
|
||||
throw e;
|
||||
}
|
||||
TmsPriceQuoteResult result = prcOrderBillService.bill(request);
|
||||
return success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Warehouse inbound: create billing task (PENDING/REBILL/REFUND) and publish MQ.
|
||||
* Consumer queries Oracle by transferNo/orderNo then inserts prc_order_bill.
|
||||
* POST /api/tms/price/billing-task
|
||||
*/
|
||||
@PostMapping("/billing-task")
|
||||
public AjaxResult submitBillingTask(
|
||||
@RequestHeader(value = HEADER_API_CODE, required = false) String headerApiCode,
|
||||
@RequestBody BillingTaskSubmitRequest request)
|
||||
{
|
||||
assertApiCode(headerApiCode, request == null ? null : request.getApiCode());
|
||||
PrcBillingTask task = prcBillingTaskService.submitInbound(request);
|
||||
return success(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query billing task writeback status.
|
||||
* GET /api/tms/price/billing-task/{taskId}
|
||||
*/
|
||||
@GetMapping("/billing-task/{taskId}")
|
||||
public AjaxResult getBillingTask(
|
||||
@RequestHeader(value = HEADER_API_CODE, required = false) String headerApiCode,
|
||||
@PathVariable("taskId") Long taskId,
|
||||
@RequestParam(value = "apiCode", required = false) String apiCode)
|
||||
{
|
||||
assertApiCode(headerApiCode, apiCode);
|
||||
return success(prcBillingTaskService.getById(taskId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Query order bill by orderNo after sync.
|
||||
*/
|
||||
@GetMapping("/bill/by-order/{orderNo}")
|
||||
public AjaxResult getBillByOrder(
|
||||
@RequestHeader(value = HEADER_API_CODE, required = false) String headerApiCode,
|
||||
@PathVariable("orderNo") String orderNo,
|
||||
@RequestParam(value = "apiCode", required = false) String apiCode)
|
||||
{
|
||||
assertApiCode(headerApiCode, apiCode);
|
||||
return success(prcOrderBillService.getBillByOrderNo(orderNo));
|
||||
}
|
||||
|
||||
private void assertApiCode(String headerApiCode, String bodyApiCode)
|
||||
{
|
||||
String expected = tmsApiProperties.getApiCode();
|
||||
if (StringUtils.isEmpty(expected))
|
||||
{
|
||||
throw new ServiceException("API_CODE_NOT_CONFIGURED: bms.tms.api-code is empty");
|
||||
}
|
||||
String actual = StringUtils.isNotEmpty(headerApiCode) ? headerApiCode.trim() : null;
|
||||
if (StringUtils.isEmpty(actual) && StringUtils.isNotEmpty(bodyApiCode))
|
||||
{
|
||||
actual = bodyApiCode.trim();
|
||||
}
|
||||
if (StringUtils.isEmpty(actual))
|
||||
{
|
||||
throw new ServiceException("API_CODE_REQUIRED: missing header X-Api-Code (or body apiCode)");
|
||||
}
|
||||
if (!expected.equals(actual))
|
||||
{
|
||||
throw new ServiceException("API_CODE_INVALID: api identification code mismatch");
|
||||
}
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package com.bms.web.controller.ar;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.ar.domain.ArBankAccount;
|
||||
import com.bms.ar.mapper.ArBankAccountMapper;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
|
||||
/**
|
||||
* 公司收款银行账户(下拉选项,供登记收款等场景选择)。
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/ar/bank-account")
|
||||
public class ArBankAccountController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private ArBankAccountMapper arBankAccountMapper;
|
||||
|
||||
/**
|
||||
* 启用账户列表;可按币种过滤,默认账户优先。
|
||||
*/
|
||||
@GetMapping("/options")
|
||||
public AjaxResult options(@RequestParam(value = "currency", required = false) String currency) {
|
||||
List<ArBankAccount> list = arBankAccountMapper.selectEnabledList(currency);
|
||||
return AjaxResult.success(list);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
package com.bms.web.controller.ar;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Date;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.beans.propertyeditors.CustomDateEditor;
|
||||
import org.springframework.web.bind.annotation.InitBinder;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.ar.domain.ArBill;
|
||||
import com.bms.ar.domain.ArBankAccount;
|
||||
import com.bms.ar.domain.ArBillDetailFee;
|
||||
import com.bms.ar.domain.ArBillExport;
|
||||
import com.bms.ar.domain.ArBillGenerateTask;
|
||||
import com.bms.ar.domain.ArBillLog;
|
||||
import com.bms.ar.domain.vo.ArBillActionRequest;
|
||||
import com.bms.ar.domain.vo.ArBillGenerateQuery;
|
||||
import com.bms.ar.domain.vo.ArBillGenerateRequest;
|
||||
import com.bms.ar.domain.vo.ArBillQuery;
|
||||
import com.bms.ar.service.IArBillService;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.exception.ServiceException;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.common.utils.uuid.IdUtils;
|
||||
import com.bms.price.domain.PrcOrderBill;
|
||||
|
||||
/**
|
||||
* 应收账单 HTTP 接口层。
|
||||
*
|
||||
* <p>负责账单列表、账单生成、确认/作废、异步导出、日志和详情分页接口;
|
||||
* 具体业务规则统一下沉到 {@code IArBillService}。</p>
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/ar/bill")
|
||||
@Validated
|
||||
public class ArBillController extends BaseController {
|
||||
@Autowired
|
||||
private IArBillService billService;
|
||||
|
||||
/**
|
||||
* 查询参数中的日期必须严格按 yyyy-MM-dd 解析,禁止非法日期自动滚动到其他日期。
|
||||
*/
|
||||
@InitBinder
|
||||
public void initDateBinder(WebDataBinder binder) {
|
||||
java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy-MM-dd");
|
||||
formatter.setLenient(false);
|
||||
binder.registerCustomEditor(Date.class, new CustomDateEditor(formatter, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询账单列表;分页参数由 BaseController.startPage 交给 MyBatis PageHelper 处理。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('ar:bill:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(ArBillQuery query, HttpServletRequest request) {
|
||||
rejectMultiValueParameter(request, "customerId");
|
||||
startPage();
|
||||
List<ArBill> list = billService.selectArBillList(query);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询账单头信息;账单明细通过独立分页接口按需加载。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('ar:bill:query')")
|
||||
@GetMapping("/{arBillId}")
|
||||
public AjaxResult getInfo(@PathVariable Long arBillId) {
|
||||
return success(billService.selectArBillById(arBillId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询账单明细,避免详情页一次性加载全部订单。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('ar:bill:query')")
|
||||
@GetMapping("/{arBillId}/details")
|
||||
public TableDataInfo details(@PathVariable Long arBillId) {
|
||||
startPage();
|
||||
return getDataTable(billService.selectArBillDetails(arBillId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询单条账单明细的费用明细,按展开行懒加载。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('ar:bill:query')")
|
||||
@GetMapping("/{arBillId}/details/{detailId}/fees")
|
||||
public AjaxResult detailFees(@PathVariable Long arBillId, @PathVariable Long detailId) {
|
||||
List<ArBillDetailFee> fees = billService.selectArBillDetailFees(arBillId, detailId);
|
||||
return success(fees);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询指定币种的公司默认收款账户,账号返回脱敏值。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('ar:bill:generate')")
|
||||
@GetMapping("/default-bank-account")
|
||||
public AjaxResult defaultBankAccount(@RequestParam(required = false, defaultValue = "CNY") String currency) {
|
||||
ArBankAccount account = billService.getDefaultBankAccount(currency);
|
||||
return success(account);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询生成账单前的订单计费结果。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('ar:bill:generate')")
|
||||
@GetMapping("/generate/preview")
|
||||
public AjaxResult preview(ArBillGenerateQuery query, HttpServletRequest request) {
|
||||
rejectMultiValueParameter(request, "customerId");
|
||||
startPage();
|
||||
List<PrcOrderBill> list = billService.previewBill(query);
|
||||
TableDataInfo pageData = getDataTable(list);
|
||||
AjaxResult result = success();
|
||||
result.put("rows", pageData.getRows());
|
||||
result.put("total", pageData.getTotal());
|
||||
result.put("totalAmount", billService.sumPreviewBill(query));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建账单头和异步生成任务,接口不等待全部订单明细处理完成。
|
||||
*/
|
||||
@Log(title = "应收账单", businessType = BusinessType.INSERT)
|
||||
@PreAuthorize("@ss.hasPermi('ar:bill:generate')")
|
||||
@PostMapping("/generate")
|
||||
public AjaxResult generate(@Valid @RequestBody ArBillGenerateRequest request,
|
||||
@RequestHeader(value = "X-Request-Id", required = false) String headerRequestId) {
|
||||
String requestId = requestId(request.getRequestId(), headerRequestId);
|
||||
ArBillGenerateTask task = billService.generateBill(request, getUsername(), requestId);
|
||||
return success(task).put("request_id", requestId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询单个应收账单异步生成任务。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('ar:bill:query')")
|
||||
@GetMapping("/generate/task/{taskId}")
|
||||
public AjaxResult generateTaskInfo(@PathVariable Long taskId) {
|
||||
return success(billService.selectGenerateTask(taskId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前用户仍在处理中的应收账单生成任务。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('ar:bill:query')")
|
||||
@GetMapping("/generate/tasks/active")
|
||||
public AjaxResult activeGenerateTasks() {
|
||||
return success(billService.selectActiveGenerateTasks(getUsername()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求取消应收账单异步生成任务。
|
||||
*/
|
||||
@Log(title = "应收账单", businessType = BusinessType.UPDATE)
|
||||
@PreAuthorize("@ss.hasPermi('ar:bill:generate')")
|
||||
@PostMapping("/generate/task/{taskId}/cancel")
|
||||
public AjaxResult cancelGenerateTask(@PathVariable Long taskId,
|
||||
@RequestHeader(value = "X-Request-Id", required = false) String headerRequestId) {
|
||||
String requestId = requestId(null, headerRequestId);
|
||||
return success(billService.cancelGenerateTask(taskId, getUsername(), requestId)).put("request_id", requestId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 整单重新发起应收账单异步生成任务。
|
||||
*/
|
||||
@Log(title = "应收账单", businessType = BusinessType.INSERT)
|
||||
@PreAuthorize("@ss.hasPermi('ar:bill:generate')")
|
||||
@PostMapping("/generate/task/{taskId}/retry")
|
||||
public AjaxResult retryGenerateTask(@PathVariable Long taskId,
|
||||
@RequestHeader(value = "X-Request-Id", required = false) String headerRequestId) {
|
||||
String requestId = requestId(null, headerRequestId);
|
||||
return success(billService.retryGenerateTask(taskId, getUsername(), requestId)).put("request_id", requestId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认已生成完成的账单,使其进入可核销状态。
|
||||
*/
|
||||
@Log(title = "应收账单", businessType = BusinessType.UPDATE)
|
||||
@PreAuthorize("@ss.hasPermi('ar:bill:confirm')")
|
||||
@PutMapping("/{arBillId}/confirm")
|
||||
public AjaxResult confirm(@PathVariable Long arBillId, @RequestBody(required = false) ArBillActionRequest request,
|
||||
@RequestHeader(value = "X-Request-Id", required = false) String headerRequestId) {
|
||||
String requestId = requestId(request == null ? null : request.getRequestId(), headerRequestId);
|
||||
return success(billService.confirmBill(arBillId, request, getUsername(), requestId)).put("request_id", requestId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 作废尚未发生核销的账单;账单明细保留作为历史快照。
|
||||
*/
|
||||
@Log(title = "应收账单", businessType = BusinessType.UPDATE)
|
||||
@PreAuthorize("@ss.hasPermi('ar:bill:void')")
|
||||
@PutMapping("/{arBillId}/void")
|
||||
public AjaxResult voidBill(@PathVariable Long arBillId, @RequestBody ArBillActionRequest request,
|
||||
@RequestHeader(value = "X-Request-Id", required = false) String headerRequestId) {
|
||||
String requestId = requestId(request == null ? null : request.getRequestId(), headerRequestId);
|
||||
return success(billService.voidBill(arBillId, request, getUsername(), requestId)).put("request_id", requestId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅提交导出任务;前端通过导出任务状态接口轮询并在完成后下载。
|
||||
*/
|
||||
@Log(title = "应收账单导出", businessType = BusinessType.EXPORT)
|
||||
@PreAuthorize("@ss.hasPermi('ar:bill:export')")
|
||||
@PostMapping("/{arBillId}/export")
|
||||
public AjaxResult export(@PathVariable Long arBillId,
|
||||
@RequestHeader(value = "X-Request-Id", required = false) String headerRequestId) {
|
||||
String requestId = requestId(null, headerRequestId);
|
||||
return success(billService.exportBill(arBillId, getUsername(), requestId)).put("request_id", requestId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前账单的导出历史和任务状态。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('ar:bill:query')")
|
||||
@GetMapping("/{arBillId}/exports")
|
||||
public AjaxResult exports(@PathVariable Long arBillId) {
|
||||
return success(billService.selectExports(arBillId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询单个账单导出任务状态,供前端轮询。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('ar:bill:query')")
|
||||
@GetMapping("/export/{exportId}")
|
||||
public AjaxResult exportInfo(@PathVariable Long exportId) {
|
||||
return success(billService.selectExport(exportId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载已成功生成的导出文件;文件内容由服务层从临时文件或配置存储读取。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('ar:bill:export')")
|
||||
@GetMapping("/export/{exportId}/download")
|
||||
public void download(@PathVariable Long exportId, HttpServletResponse response) throws Exception {
|
||||
billService.downloadExport(exportId, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询账单操作日志。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('ar:log:list')")
|
||||
@GetMapping("/log/list")
|
||||
public TableDataInfo logs(ArBillLog query) {
|
||||
startPage();
|
||||
return getDataTable(billService.selectLogList(query));
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析接口幂等号:优先使用请求体,再使用请求头,最后生成新的 UUID。
|
||||
* 生成账单、确认、作废和导出都依赖该值避免重复提交。
|
||||
*/
|
||||
private String requestId(String bodyRequestId, String headerRequestId) {
|
||||
if (StringUtils.isNotEmpty(bodyRequestId)) return bodyRequestId;
|
||||
if (StringUtils.isNotEmpty(headerRequestId)) return headerRequestId;
|
||||
return IdUtils.fastSimpleUUID();
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁止把 customerId 以数组参数或重复参数提交,避免参数绑定失败后悄悄退化为无客户条件查询。
|
||||
*/
|
||||
private void rejectMultiValueParameter(HttpServletRequest request, String parameterName) {
|
||||
if (request.getParameterMap().containsKey(parameterName + "[]")) {
|
||||
throw new ServiceException("查询参数[" + parameterName + "]格式不正确,请传入单个客户ID");
|
||||
}
|
||||
String[] values = request.getParameterValues(parameterName);
|
||||
if (values != null && values.length > 1) {
|
||||
throw new ServiceException("查询参数[" + parameterName + "]只能传入一个值");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.bms.web.controller.common;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import jakarta.annotation.Resource;
|
||||
import javax.imageio.ImageIO;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.util.FastByteArrayOutputStream;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.google.code.kaptcha.Producer;
|
||||
import com.bms.common.config.BmsConfig;
|
||||
import com.bms.common.constant.CacheConstants;
|
||||
import com.bms.common.constant.Constants;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.redis.RedisCache;
|
||||
import com.bms.common.utils.sign.Base64;
|
||||
import com.bms.common.utils.uuid.IdUtils;
|
||||
import com.bms.system.service.ISysConfigService;
|
||||
|
||||
/**
|
||||
* 验证码操作处理
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
public class CaptchaController
|
||||
{
|
||||
@Resource(name = "captchaProducer")
|
||||
private Producer captchaProducer;
|
||||
|
||||
@Resource(name = "captchaProducerMath")
|
||||
private Producer captchaProducerMath;
|
||||
|
||||
@Autowired
|
||||
private RedisCache redisCache;
|
||||
|
||||
@Autowired
|
||||
private ISysConfigService configService;
|
||||
/**
|
||||
* 生成验证码
|
||||
*/
|
||||
@GetMapping("/captchaImage")
|
||||
public AjaxResult getCode(HttpServletResponse response) throws IOException
|
||||
{
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
boolean captchaEnabled = configService.selectCaptchaEnabled();
|
||||
ajax.put("captchaEnabled", captchaEnabled);
|
||||
if (!captchaEnabled)
|
||||
{
|
||||
return ajax;
|
||||
}
|
||||
|
||||
// 保存验证码信息
|
||||
String uuid = IdUtils.simpleUUID();
|
||||
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
|
||||
|
||||
String capStr = null, code = null;
|
||||
BufferedImage image = null;
|
||||
|
||||
// 生成验证码
|
||||
String captchaType = BmsConfig.getCaptchaType();
|
||||
if ("math".equals(captchaType))
|
||||
{
|
||||
String capText = captchaProducerMath.createText();
|
||||
capStr = capText.substring(0, capText.lastIndexOf("@"));
|
||||
code = capText.substring(capText.lastIndexOf("@") + 1);
|
||||
image = captchaProducerMath.createImage(capStr);
|
||||
}
|
||||
else if ("char".equals(captchaType))
|
||||
{
|
||||
capStr = code = captchaProducer.createText();
|
||||
image = captchaProducer.createImage(capStr);
|
||||
}
|
||||
|
||||
redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
|
||||
// 转换流信息写出
|
||||
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
|
||||
try
|
||||
{
|
||||
ImageIO.write(image, "jpg", os);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
|
||||
ajax.put("uuid", uuid);
|
||||
ajax.put("img", Base64.encode(os.toByteArray()));
|
||||
return ajax;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
package com.bms.web.controller.common;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.bms.common.config.BmsConfig;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.common.utils.file.FileUploadUtils;
|
||||
import com.bms.common.utils.file.FileUtils;
|
||||
import com.bms.framework.config.ServerConfig;
|
||||
|
||||
/**
|
||||
* 通用请求处理
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/common")
|
||||
public class CommonController
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(CommonController.class);
|
||||
|
||||
@Autowired
|
||||
private ServerConfig serverConfig;
|
||||
|
||||
private static final String FILE_DELIMITER = ",";
|
||||
|
||||
/**
|
||||
* 通用下载请求
|
||||
*
|
||||
* @param fileName 文件名称
|
||||
* @param delete 是否删除
|
||||
*/
|
||||
@GetMapping("/download")
|
||||
public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!FileUtils.checkAllowDownload(fileName))
|
||||
{
|
||||
throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
|
||||
}
|
||||
String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
|
||||
String filePath = BmsConfig.getDownloadPath() + fileName;
|
||||
|
||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||
FileUtils.setAttachmentResponseHeader(response, realFileName);
|
||||
FileUtils.writeBytes(filePath, response.getOutputStream());
|
||||
if (delete)
|
||||
{
|
||||
FileUtils.deleteFile(filePath);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("下载文件失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用上传请求(单个)
|
||||
*/
|
||||
@PostMapping("/upload")
|
||||
public AjaxResult uploadFile(MultipartFile file) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
// 上传文件路径
|
||||
String filePath = BmsConfig.getUploadPath();
|
||||
// 上传并返回新文件名称
|
||||
String fileName = FileUploadUtils.upload(filePath, file);
|
||||
String url = serverConfig.getUrl() + fileName;
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
ajax.put("url", url);
|
||||
ajax.put("fileName", fileName);
|
||||
ajax.put("newFileName", FileUtils.getName(fileName));
|
||||
ajax.put("originalFilename", file.getOriginalFilename());
|
||||
return ajax;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用上传请求(多个)
|
||||
*/
|
||||
@PostMapping("/uploads")
|
||||
public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
// 上传文件路径
|
||||
String filePath = BmsConfig.getUploadPath();
|
||||
List<String> urls = new ArrayList<String>();
|
||||
List<String> fileNames = new ArrayList<String>();
|
||||
List<String> newFileNames = new ArrayList<String>();
|
||||
List<String> originalFilenames = new ArrayList<String>();
|
||||
for (MultipartFile file : files)
|
||||
{
|
||||
// 上传并返回新文件名称
|
||||
String fileName = FileUploadUtils.upload(filePath, file);
|
||||
String url = serverConfig.getUrl() + fileName;
|
||||
urls.add(url);
|
||||
fileNames.add(fileName);
|
||||
newFileNames.add(FileUtils.getName(fileName));
|
||||
originalFilenames.add(file.getOriginalFilename());
|
||||
}
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
ajax.put("urls", StringUtils.join(urls, FILE_DELIMITER));
|
||||
ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMITER));
|
||||
ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMITER));
|
||||
ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMITER));
|
||||
return ajax;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 本地资源通用下载
|
||||
*/
|
||||
@GetMapping("/download/resource")
|
||||
public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
|
||||
throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!FileUtils.checkAllowDownload(resource))
|
||||
{
|
||||
throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource));
|
||||
}
|
||||
// 本地资源路径
|
||||
String localPath = BmsConfig.getProfile();
|
||||
// 数据库资源地址
|
||||
String downloadPath = localPath + FileUtils.stripPrefix(resource);
|
||||
// 下载名称
|
||||
String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
|
||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||
FileUtils.setAttachmentResponseHeader(response, downloadName);
|
||||
FileUtils.writeBytes(downloadPath, response.getOutputStream());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("下载文件失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+225
@@ -0,0 +1,225 @@
|
||||
package com.bms.web.controller.customer.customerinfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.bms.customer.customerinfo.domain.BmsCustomerAttachment;
|
||||
import com.bms.customer.customerinfo.domain.BmsCustomerCompany;
|
||||
import com.bms.customer.customerinfo.domain.BmsCustomerContact;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.customer.customerinfo.domain.BmsCustomer;
|
||||
import com.bms.customer.customerinfo.service.IBmsCustomerService;
|
||||
import com.bms.common.utils.poi.ExcelUtil;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 客户管理Controller
|
||||
*
|
||||
* @author bms
|
||||
* @date 2026-09-08
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/customersupplier/customerinfo")
|
||||
public class BmsCustomerController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IBmsCustomerService bmsCustomerService;
|
||||
|
||||
/**
|
||||
* 查询客户信息列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(BmsCustomer bmsCustomer)
|
||||
{
|
||||
startPage();
|
||||
List<BmsCustomer> list = bmsCustomerService.selectBmsCustomerList(bmsCustomer);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出客户信息列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:export')")
|
||||
@Log(title = "客户信息", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, BmsCustomer bmsCustomer)
|
||||
{
|
||||
List<BmsCustomer> list = bmsCustomerService.selectBmsCustomerList(bmsCustomer);
|
||||
ExcelUtil<BmsCustomer> util = new ExcelUtil<>(BmsCustomer.class);
|
||||
util.exportExcel(response, list, "客户主数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户信息详细信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:query')")
|
||||
@GetMapping(value = "/{customerId}")
|
||||
public AjaxResult getInfo(@PathVariable("customerId") Long customerId)
|
||||
{
|
||||
return success(bmsCustomerService.selectBmsCustomerByCustomerId(customerId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增客户信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:add')")
|
||||
@Log(title = "客户信息", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody BmsCustomer bmsCustomer)
|
||||
{
|
||||
bmsCustomerService.insertBmsCustomer(bmsCustomer);
|
||||
// 返回新主键,供前端新增成功后停留在编辑页继续维护子表/绑定产品
|
||||
AjaxResult ajax = AjaxResult.success("新增成功");
|
||||
ajax.put("customerId", bmsCustomer.getCustomerId());
|
||||
return ajax;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改客户信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:edit')")
|
||||
@Log(title = "客户信息", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody BmsCustomer bmsCustomer)
|
||||
{
|
||||
return toAjax(bmsCustomerService.updateBmsCustomer(bmsCustomer));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除客户信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:remove')")
|
||||
@Log(title = "客户信息", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{customerIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] customerIds)
|
||||
{
|
||||
return toAjax(bmsCustomerService.deleteBmsCustomerByCustomerIds(customerIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看附件列表数据
|
||||
*/
|
||||
// @PreAuthorize("")
|
||||
|
||||
@GetMapping("/attachment/list")
|
||||
public TableDataInfo showattachmentlist(BmsCustomerAttachment bmsCustomerAttachment)
|
||||
{
|
||||
startPage();
|
||||
List<BmsCustomerAttachment> list = bmsCustomerService.selectBmsCustomerAttachmentList(bmsCustomerAttachment);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询客户公司主体列表
|
||||
*/
|
||||
@GetMapping("/company/list")
|
||||
public TableDataInfo companyList(BmsCustomerCompany bmsCustomerCompany)
|
||||
{
|
||||
startPage();
|
||||
List<BmsCustomerCompany> list = bmsCustomerService.selectBmsCustomerCompanyList(bmsCustomerCompany);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户公司主体详细信息
|
||||
*/
|
||||
@GetMapping("/company/{companyId}")
|
||||
public AjaxResult getCompanyInfo(@PathVariable("companyId") Long companyId)
|
||||
{
|
||||
return success(bmsCustomerService.selectBmsCustomerCompanyByCompanyId(companyId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增客户公司主体(可关联客户主表,可不关联)
|
||||
*/
|
||||
@Log(title = "客户公司主体", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/company")
|
||||
public AjaxResult addCompany(@RequestBody BmsCustomerCompany bmsCustomerCompany)
|
||||
{
|
||||
return toAjax(bmsCustomerService.insertBmsCustomerCompany(bmsCustomerCompany));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改客户公司主体
|
||||
*/
|
||||
@Log(title = "客户公司主体", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/company")
|
||||
public AjaxResult editCompany(@RequestBody BmsCustomerCompany bmsCustomerCompany)
|
||||
{
|
||||
return toAjax(bmsCustomerService.updateBmsCustomerCompany(bmsCustomerCompany));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除客户公司主体
|
||||
*/
|
||||
@Log(title = "客户公司主体", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/company/{companyIds}")
|
||||
public AjaxResult removeCompany(@PathVariable Long[] companyIds)
|
||||
{
|
||||
return toAjax(bmsCustomerService.deleteBmsCustomerCompanyByCompanyIds(companyIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询客户联系人列表
|
||||
*/
|
||||
@GetMapping("/contact/list")
|
||||
public TableDataInfo contactList(BmsCustomerContact bmsCustomerContact)
|
||||
{
|
||||
startPage();
|
||||
List<BmsCustomerContact> list = bmsCustomerService.selectBmsCustomerContactList(bmsCustomerContact);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户联系人详细信息
|
||||
*/
|
||||
@GetMapping("/contact/{contactId}")
|
||||
public AjaxResult getContactInfo(@PathVariable("contactId") Long contactId)
|
||||
{
|
||||
return success(bmsCustomerService.selectBmsCustomerContactByContactId(contactId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增客户联系人
|
||||
*/
|
||||
@Log(title = "客户联系人", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/contact")
|
||||
public AjaxResult addContact(@RequestBody BmsCustomerContact bmsCustomerContact)
|
||||
{
|
||||
return toAjax(bmsCustomerService.insertBmsCustomerContact(bmsCustomerContact));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改客户联系人
|
||||
*/
|
||||
@Log(title = "客户联系人", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/contact")
|
||||
public AjaxResult editContact(@RequestBody BmsCustomerContact bmsCustomerContact)
|
||||
{
|
||||
return toAjax(bmsCustomerService.updateBmsCustomerContact(bmsCustomerContact));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除客户联系人
|
||||
*/
|
||||
@Log(title = "客户联系人", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/contact/{contactIds}")
|
||||
public AjaxResult removeContact(@PathVariable Long[] contactIds)
|
||||
{
|
||||
return toAjax(bmsCustomerService.deleteBmsCustomerContactByContactIds(contactIds));
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
package com.bms.web.controller.customer.customerinfo;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.customer.customerinfo.domain.BmsCustomerPriceSet;
|
||||
import com.bms.customer.customerinfo.domain.BmsPriceSetOption;
|
||||
import com.bms.customer.customerinfo.service.IBmsCustomerPriceSetService;
|
||||
|
||||
/**
|
||||
* 客户套餐绑定Controller(客户管理-客户编辑-绑定套餐)
|
||||
*
|
||||
* @author bms
|
||||
* @date 2026-09-16
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/customersupplier/customerinfo/priceset")
|
||||
public class BmsCustomerPriceSetController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IBmsCustomerPriceSetService customerPriceSetService;
|
||||
|
||||
/**
|
||||
* 查询客户已绑定的套餐列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:list')")
|
||||
@GetMapping("/bind/list")
|
||||
public AjaxResult bindList(Long customerId)
|
||||
{
|
||||
List<BmsCustomerPriceSet> list = customerPriceSetService.selectBindList(customerId);
|
||||
return success(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询可绑定的生效套餐选项
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:list')")
|
||||
@GetMapping("/option/list")
|
||||
public AjaxResult optionList(BmsPriceSetOption query)
|
||||
{
|
||||
return success(customerPriceSetService.selectOptionList(query));
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存客户套餐绑定(已绑定则更新/更换套餐,未绑定则新增)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:edit')")
|
||||
@Log(title = "客户套餐绑定", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/bind")
|
||||
public AjaxResult saveBind(@RequestBody BmsCustomerPriceSet bind)
|
||||
{
|
||||
bind.setCreateBy(getUsername());
|
||||
bind.setUpdateBy(getUsername());
|
||||
return toAjax(customerPriceSetService.saveBind(bind));
|
||||
}
|
||||
|
||||
/**
|
||||
* 解绑客户套餐
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:edit')")
|
||||
@Log(title = "客户套餐解绑", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/bind/{customerPricesetIds}")
|
||||
public AjaxResult removeBind(@PathVariable Long[] customerPricesetIds)
|
||||
{
|
||||
return toAjax(customerPriceSetService.deleteBindByIds(customerPricesetIds));
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
package com.bms.web.controller.customer.customermoney;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.ar.domain.ArBalanceWriteoff;
|
||||
import com.bms.ar.service.IArBalanceWriteoffService;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
|
||||
/**
|
||||
* 客户余额核销应收账单 Controller(账单查看统一走应收管理-应收账单页面)
|
||||
*
|
||||
* @author bms
|
||||
* @date 2026-09-16
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/customersupplier/customerbill")
|
||||
public class CustomerBillController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IArBalanceWriteoffService balanceWriteoffService;
|
||||
|
||||
/**
|
||||
* 查询客户可核销账单(已确认/部分核销,未核销额大于0)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:list')")
|
||||
@GetMapping("/unsettled/{customerId}")
|
||||
public AjaxResult unsettled(@PathVariable("customerId") Long customerId)
|
||||
{
|
||||
return success(balanceWriteoffService.selectUnsettledBills(customerId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询余额核销记录(分页)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:list')")
|
||||
@GetMapping("/writeoff/list")
|
||||
public TableDataInfo writeoffList(ArBalanceWriteoff query)
|
||||
{
|
||||
if (query == null || query.getCustomerId() == null || query.getCustomerId() == 0L)
|
||||
{
|
||||
return getDataTable(Collections.emptyList());
|
||||
}
|
||||
startPage();
|
||||
List<ArBalanceWriteoff> list = balanceWriteoffService.selectWriteoffList(query);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用客户账户余额核销账单
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customer:bill:writeoff')")
|
||||
@Log(title = "余额核销账单", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/writeoff")
|
||||
public AjaxResult writeoff(@RequestBody ArBalanceWriteoff cmd)
|
||||
{
|
||||
cmd.setCreateBy(getUsername());
|
||||
return success(balanceWriteoffService.writeoff(cmd));
|
||||
}
|
||||
|
||||
/**
|
||||
* 反核销(取消一笔有效余额核销)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customer:bill:writeoff:cancel')")
|
||||
@Log(title = "余额核销反核销", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/writeoff/{writeoffId}/cancel")
|
||||
public AjaxResult cancelWriteoff(@PathVariable("writeoffId") Long writeoffId,
|
||||
@RequestBody(required = false) ArBalanceWriteoff body)
|
||||
{
|
||||
balanceWriteoffService.cancelWriteoff(writeoffId, body == null ? null : body.getCancelRemark());
|
||||
return success();
|
||||
}
|
||||
}
|
||||
+312
@@ -0,0 +1,312 @@
|
||||
package com.bms.web.controller.customer.customermoney;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.utils.poi.ExcelUtil;
|
||||
import com.bms.customer.customermoney.api.ICustomerAccountApi;
|
||||
import com.bms.customer.customermoney.domain.CustomerBalanceFlow;
|
||||
import com.bms.customer.customermoney.domain.CustomerCreditApply;
|
||||
import com.bms.customer.customermoney.domain.CustomerCreditFlow;
|
||||
import com.bms.customer.customermoney.domain.CustomerReceipt;
|
||||
import com.bms.customer.customermoney.service.ICreditQuotaService;
|
||||
import com.bms.customer.customermoney.service.ICustomerMoneyService;
|
||||
import com.bms.customer.customermoney.vo.CustomerAccountStatusVO;
|
||||
import com.bms.customer.customermoney.vo.CustomerBalanceFlowExportVO;
|
||||
import com.bms.customer.customermoney.vo.CustomerCreditFlowExportVO;
|
||||
import com.bms.customer.customermoney.vo.CustomerReceiptExportVO;
|
||||
import com.bms.common.utils.SecurityUtils;
|
||||
|
||||
/**
|
||||
* 客户余额/收款/流水 Controller
|
||||
*
|
||||
* @author bms
|
||||
* @date 2026-09-11
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/customersupplier/customermoney")
|
||||
public class CustomerMoneyController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ICustomerMoneyService customerMoneyService;
|
||||
|
||||
@Autowired
|
||||
private ICustomerAccountApi customerAccountApi;
|
||||
|
||||
@Autowired
|
||||
private ICreditQuotaService creditQuotaService;
|
||||
|
||||
/**
|
||||
* 查询客户账号状态(收货扣件准入控制用)。支持 customerId 或 customerCode 二选一。
|
||||
* 只读轻量查询,不锁账户也不物化临时额度失效。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:list')")
|
||||
@GetMapping("/account/status")
|
||||
public AjaxResult accountStatus(@RequestParam(value = "customerId", required = false) Long customerId,
|
||||
@RequestParam(value = "customerCode", required = false) String customerCode)
|
||||
{
|
||||
CustomerAccountStatusVO vo = customerAccountApi.getAccountStatus(customerId, customerCode);
|
||||
if (vo == null)
|
||||
{
|
||||
return error("客户不存在");
|
||||
}
|
||||
return success(vo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询客户各币种账户余额
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:list')")
|
||||
@GetMapping("/account/list/{customerId}")
|
||||
public AjaxResult accountList(@PathVariable("customerId") Long customerId)
|
||||
{
|
||||
return success(customerMoneyService.selectAccountList(customerId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询收款记录列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:list')")
|
||||
@GetMapping("/receipt/list")
|
||||
public TableDataInfo receiptList(CustomerReceipt query)
|
||||
{
|
||||
// customerId 为空或为 0,直接返回空数据
|
||||
if (query == null || query.getCustomerId() == null || query.getCustomerId() == 0L) {
|
||||
return getDataTable(Collections.emptyList());
|
||||
}
|
||||
|
||||
startPage();
|
||||
List<CustomerReceipt> list = customerMoneyService.selectReceiptList(query);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出收款记录(按当前筛选条件,全量导出不分页)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:export')")
|
||||
@Log(title = "客户收款记录", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/receipt/export")
|
||||
public void receiptExport(HttpServletResponse response, CustomerReceipt query)
|
||||
{
|
||||
List<CustomerReceiptExportVO> list = Collections.emptyList();
|
||||
if (query != null && query.getCustomerId() != null && query.getCustomerId() != 0L)
|
||||
{
|
||||
list = customerMoneyService.selectReceiptList(query).stream()
|
||||
.map(CustomerReceiptExportVO::from).collect(Collectors.toList());
|
||||
}
|
||||
ExcelUtil<CustomerReceiptExportVO> util = new ExcelUtil<>(CustomerReceiptExportVO.class);
|
||||
util.exportExcel(response, list, "收款记录");
|
||||
}
|
||||
/**
|
||||
* 获取收款单详情(含收款附件)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:query')")
|
||||
@GetMapping("/receipt/{id}")
|
||||
public AjaxResult getReceipt(@PathVariable("id") Long id)
|
||||
{
|
||||
return success(customerMoneyService.selectReceiptById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 登记收款(默认待确认,同时保存收款凭证附件)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:add')")
|
||||
@Log(title = "客户收款", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/receipt")
|
||||
public AjaxResult addReceipt(@RequestBody CustomerReceipt receipt)
|
||||
{
|
||||
receipt.setCreateBy(getUsername());
|
||||
return toAjax(customerMoneyService.insertReceipt(receipt));
|
||||
}
|
||||
|
||||
/**
|
||||
* 审核通过收款单:确认后变动客户余额并生成余额流水
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customer:balance:review')")
|
||||
@Log(title = "客户收款审核", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/receipt/confirm/{id}")
|
||||
public AjaxResult confirmReceipt(@PathVariable("id") Long id)
|
||||
{
|
||||
return toAjax(customerMoneyService.confirmReceipt(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消收款单(仅待确认可取消)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:edit')")
|
||||
@Log(title = "客户收款取消", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/receipt/cancel/{id}")
|
||||
public AjaxResult cancelReceipt(@PathVariable("id") Long id)
|
||||
{
|
||||
return toAjax(customerMoneyService.cancelReceipt(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询余额流水列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:list')")
|
||||
@GetMapping("/flow/list")
|
||||
public TableDataInfo flowList(CustomerBalanceFlow query)
|
||||
{
|
||||
// customerId 为空或为 0,直接返回空数据
|
||||
if (query == null || query.getCustomerId() == null || query.getCustomerId() == 0L) {
|
||||
return getDataTable(Collections.emptyList());
|
||||
}
|
||||
startPage();
|
||||
List<CustomerBalanceFlow> list = customerMoneyService.selectFlowList(query);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出余额流水(按当前筛选条件,全量导出不分页)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:export')")
|
||||
@Log(title = "客户余额流水", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/flow/export")
|
||||
public void flowExport(HttpServletResponse response, CustomerBalanceFlow query)
|
||||
{
|
||||
List<CustomerBalanceFlowExportVO> list = Collections.emptyList();
|
||||
if (query != null && query.getCustomerId() != null && query.getCustomerId() != 0L)
|
||||
{
|
||||
list = customerMoneyService.selectFlowList(query).stream()
|
||||
.map(CustomerBalanceFlowExportVO::from).collect(Collectors.toList());
|
||||
}
|
||||
ExcelUtil<CustomerBalanceFlowExportVO> util = new ExcelUtil<>(CustomerBalanceFlowExportVO.class);
|
||||
util.exportExcel(response, list, "余额流水");
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询额度流水列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:list')")
|
||||
@GetMapping("/credit/flow/list")
|
||||
public TableDataInfo creditFlowList(CustomerCreditFlow query)
|
||||
{
|
||||
if (query == null || query.getCustomerId() == null || query.getCustomerId() == 0L) {
|
||||
return getDataTable(Collections.emptyList());
|
||||
}
|
||||
startPage();
|
||||
List<CustomerCreditFlow> list = customerMoneyService.selectCreditFlowList(query);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出额度流水(按当前筛选条件,全量导出不分页)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:export')")
|
||||
@Log(title = "客户额度流水", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/credit/flow/export")
|
||||
public void creditFlowExport(HttpServletResponse response, CustomerCreditFlow query)
|
||||
{
|
||||
List<CustomerCreditFlowExportVO> list = Collections.emptyList();
|
||||
if (query != null && query.getCustomerId() != null && query.getCustomerId() != 0L)
|
||||
{
|
||||
list = customerMoneyService.selectCreditFlowList(query).stream()
|
||||
.map(CustomerCreditFlowExportVO::from).collect(Collectors.toList());
|
||||
}
|
||||
ExcelUtil<CustomerCreditFlowExportVO> util = new ExcelUtil<>(CustomerCreditFlowExportVO.class);
|
||||
util.exportExcel(response, list, "额度流水");
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交额度调整申请(信用额度/临时额度),申请待审批通过后才真正调整额度
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customer:credit:adjust')")
|
||||
@Log(title = "客户额度调整申请", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/credit/apply")
|
||||
public AjaxResult applyCredit(@RequestBody CustomerCreditApply apply)
|
||||
{
|
||||
apply.setCreateBy(getUsername());
|
||||
return toAjax(customerMoneyService.applyCreditAdjust(apply));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询额度调整申请列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:list')")
|
||||
@GetMapping("/credit/apply/list")
|
||||
public TableDataInfo creditApplyList(CustomerCreditApply query)
|
||||
{
|
||||
if (query == null || query.getCustomerId() == null || query.getCustomerId() == 0L) {
|
||||
return getDataTable(Collections.emptyList());
|
||||
}
|
||||
startPage();
|
||||
List<CustomerCreditApply> list = customerMoneyService.selectCreditApplyList(query);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询额度调整申请详情
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:list')")
|
||||
@GetMapping("/credit/apply/{applyId}")
|
||||
public AjaxResult getCreditApply(@PathVariable("applyId") Long applyId)
|
||||
{
|
||||
return success(customerMoneyService.selectCreditApplyById(applyId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 审批通过额度调整申请:通过后调整账户额度并生成额度流水。
|
||||
* 非超管审批净增额度时 body 须带 approveRoleId(占用该角色额度池)。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customer:credit:approve')")
|
||||
@Log(title = "客户额度调整审批", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/credit/apply/approve/{applyId}")
|
||||
public AjaxResult approveCreditApply(@PathVariable("applyId") Long applyId,
|
||||
@RequestBody(required = false) CustomerCreditApply body)
|
||||
{
|
||||
String remark = body != null ? body.getApproveRemark() : null;
|
||||
Long approveRoleId = body != null ? body.getApproveRoleId() : null;
|
||||
return toAjax(customerMoneyService.approveCreditApply(applyId, remark, approveRoleId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前登录用户审批时可选择的角色额度池(超管返回空列表,前端不展示选框)。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customer:credit:approve')")
|
||||
@GetMapping("/credit/quota/my-pools")
|
||||
public AjaxResult myCreditPools()
|
||||
{
|
||||
return success(creditQuotaService.myPools(SecurityUtils.getUserId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 驳回额度调整申请(驳回原因必填)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customer:credit:approve')")
|
||||
@Log(title = "客户额度调整驳回", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/credit/apply/reject/{applyId}")
|
||||
public AjaxResult rejectCreditApply(@PathVariable("applyId") Long applyId,
|
||||
@RequestBody CustomerCreditApply body)
|
||||
{
|
||||
String reason = body != null ? body.getApproveRemark() : null;
|
||||
return toAjax(customerMoneyService.rejectCreditApply(applyId, reason));
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤销待审批的额度调整申请
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('customer:credit:adjust')")
|
||||
@Log(title = "客户额度调整撤销", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/credit/apply/cancel/{applyId}")
|
||||
public AjaxResult cancelCreditApply(@PathVariable("applyId") Long applyId)
|
||||
{
|
||||
return toAjax(customerMoneyService.cancelCreditApply(applyId));
|
||||
}
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
package com.bms.web.controller.customer.supplierinfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.bms.customer.customerinfo.domain.BmsCustomerAttachment;
|
||||
import com.bms.customer.customerinfo.domain.BmsCustomerCompany;
|
||||
import com.bms.customer.supplierinfo.domain.BmsSupplier;
|
||||
import com.bms.customer.supplierinfo.domain.BmsSupplierAttachment;
|
||||
import com.bms.customer.supplierinfo.domain.BmsSupplierCompany;
|
||||
import com.bms.customer.supplierinfo.service.IBmsSupplierService;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.utils.poi.ExcelUtil;
|
||||
|
||||
/**
|
||||
* 供应商管理Controller
|
||||
*
|
||||
* @author bms
|
||||
* @date 2026-09-09
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/customersupplier/supplierinfo")
|
||||
public class BmsSupplierController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IBmsSupplierService bmsSupplierService;
|
||||
|
||||
/** 查询供应商列表 */
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:supplierinfo:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(BmsSupplier bmsSupplier)
|
||||
{
|
||||
startPage();
|
||||
List<BmsSupplier> list = bmsSupplierService.selectBmsSupplierList(bmsSupplier);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/** 导出供应商列表 */
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:supplierinfo:export')")
|
||||
@Log(title = "供应商信息", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, BmsSupplier bmsSupplier)
|
||||
{
|
||||
List<BmsSupplier> list = bmsSupplierService.selectBmsSupplierList(bmsSupplier);
|
||||
ExcelUtil<BmsSupplier> util = new ExcelUtil<BmsSupplier>(BmsSupplier.class);
|
||||
util.exportExcel(response, list, "供应商数据");
|
||||
}
|
||||
|
||||
/** 获取供应商详细信息 */
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:supplierinfo:query')")
|
||||
@GetMapping(value = "/{supplierId}")
|
||||
public AjaxResult getInfo(@PathVariable("supplierId") Long supplierId)
|
||||
{
|
||||
return success(bmsSupplierService.selectBmsSupplierBySupplierId(supplierId));
|
||||
}
|
||||
|
||||
/** 新增供应商 */
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:supplierinfo:add')")
|
||||
@Log(title = "供应商信息", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody BmsSupplier bmsSupplier)
|
||||
{
|
||||
bmsSupplierService.insertBmsSupplier(bmsSupplier);
|
||||
// 返回新主键,供前端新增成功后停留在编辑页继续维护子表
|
||||
AjaxResult ajax = AjaxResult.success("新增成功");
|
||||
ajax.put("supplierId", bmsSupplier.getSupplierId());
|
||||
return ajax;
|
||||
}
|
||||
|
||||
/** 修改供应商 */
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:supplierinfo:edit')")
|
||||
@Log(title = "供应商信息", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody BmsSupplier bmsSupplier)
|
||||
{
|
||||
return toAjax(bmsSupplierService.updateBmsSupplier(bmsSupplier));
|
||||
}
|
||||
|
||||
/** 删除供应商 */
|
||||
@PreAuthorize("@ss.hasPermi('customersupplier:supplierinfo:remove')")
|
||||
@Log(title = "供应商信息", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{supplierIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] supplierIds)
|
||||
{
|
||||
return toAjax(bmsSupplierService.deleteBmsSupplierBySupplierIds(supplierIds));
|
||||
}
|
||||
|
||||
/** 查看供应商附件列表(子表共用) */
|
||||
@GetMapping("/attachment/list")
|
||||
public TableDataInfo attachmentList(BmsSupplierAttachment bmsSupplierAttachment)
|
||||
{
|
||||
startPage();
|
||||
List<BmsSupplierAttachment> list = bmsSupplierService.selectBmsSupplierAttachmentList(bmsSupplierAttachment);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/** 查看供应商公司主体列表(子表共用) */
|
||||
@GetMapping("/company/list")
|
||||
public TableDataInfo companyList(BmsSupplierCompany bmsSupplierCompany)
|
||||
{
|
||||
startPage();
|
||||
List<BmsSupplierCompany> list = bmsSupplierService.selectBmsSupplierCompanyList(bmsSupplierCompany);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/** 删除供应商公司主体 */
|
||||
@Log(title = "供应商公司主体", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/company/{companyIds}")
|
||||
public AjaxResult removeCompany(@PathVariable Long[] companyIds)
|
||||
{
|
||||
return toAjax(bmsSupplierService.deleteBmsSupplierCompanyByCompanyIds(companyIds));
|
||||
}
|
||||
|
||||
/** 删除供应商联系人 */
|
||||
@Log(title = "供应商联系人", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/contact/{contactIds}")
|
||||
public AjaxResult removeContact(@PathVariable Long[] contactIds)
|
||||
{
|
||||
return toAjax(bmsSupplierService.deleteBmsSupplierContactByContactIds(contactIds));
|
||||
}
|
||||
}
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
package com.bms.web.controller.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.utils.poi.ExcelUtil;
|
||||
import com.bms.system.domain.BmsExchangeRate;
|
||||
import com.bms.system.domain.BmsExchangeRateConvertResult;
|
||||
import com.bms.system.service.IBmsExchangeRateService;
|
||||
|
||||
/**
|
||||
* 汇率管理 信息操作处理
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/data/exchangerate")
|
||||
public class BmsExchangeRateController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IBmsExchangeRateService exchangeRateService;
|
||||
|
||||
/**
|
||||
* 获取汇率列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('data:exchangerate:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(BmsExchangeRate exchangeRate)
|
||||
{
|
||||
startPage();
|
||||
List<BmsExchangeRate> list = exchangeRateService.selectExchangeRateList(exchangeRate);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出汇率列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('data:exchangerate:export')")
|
||||
@Log(title = "汇率管理", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, BmsExchangeRate exchangeRate)
|
||||
{
|
||||
List<BmsExchangeRate> list = exchangeRateService.selectExchangeRateList(exchangeRate);
|
||||
ExcelUtil<BmsExchangeRate> util = new ExcelUtil<BmsExchangeRate>(BmsExchangeRate.class);
|
||||
util.exportExcel(response, list, "汇率数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取汇率详细信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('data:exchangerate:query')")
|
||||
@GetMapping(value = "/{rateId}")
|
||||
public AjaxResult getInfo(@PathVariable Long rateId)
|
||||
{
|
||||
return success(exchangeRateService.selectExchangeRateById(rateId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增汇率
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('data:exchangerate:add')")
|
||||
@Log(title = "汇率管理", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@Validated @RequestBody BmsExchangeRate exchangeRate)
|
||||
{
|
||||
exchangeRate.setCreateBy(getUsername());
|
||||
return toAjax(exchangeRateService.insertExchangeRate(exchangeRate));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改汇率
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('data:exchangerate:edit')")
|
||||
@Log(title = "汇率管理", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@Validated @RequestBody BmsExchangeRate exchangeRate)
|
||||
{
|
||||
return toAjax(exchangeRateService.updateExchangeRate(exchangeRate));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除汇率
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('data:exchangerate:remove')")
|
||||
@Log(title = "汇率管理", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{rateIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] rateIds)
|
||||
{
|
||||
return toAjax(exchangeRateService.deleteExchangeRateByIds(rateIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 汇率换算(业务公共接口,登录即可调用,不单独设权限)
|
||||
*
|
||||
* @param amount 源金额
|
||||
* @param fromCurrency 源币种
|
||||
* @param toCurrency 目标币种
|
||||
* @param rateType 汇率类型(0即期 1月初 2月末 3固定),默认即期
|
||||
* @param bizDate 业务日期 yyyy-MM-dd,默认当天
|
||||
*/
|
||||
@GetMapping("/convert")
|
||||
public AjaxResult convert(@RequestParam BigDecimal amount,
|
||||
@RequestParam String fromCurrency,
|
||||
@RequestParam String toCurrency,
|
||||
@RequestParam(required = false) String rateType,
|
||||
@RequestParam(required = false) String bizDate)
|
||||
{
|
||||
Date date = parseDate(bizDate);
|
||||
BmsExchangeRateConvertResult result = exchangeRateService.convert(
|
||||
amount, fromCurrency, toCurrency, rateType, date);
|
||||
return success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 本位币(CNY)折算:任意币种金额折算为人民币
|
||||
*/
|
||||
@GetMapping("/toBase")
|
||||
public AjaxResult toBase(@RequestParam BigDecimal amount,
|
||||
@RequestParam String currency,
|
||||
@RequestParam(required = false) String rateType,
|
||||
@RequestParam(required = false) String bizDate)
|
||||
{
|
||||
Date date = parseDate(bizDate);
|
||||
BmsExchangeRateConvertResult result = exchangeRateService.convert(
|
||||
amount, currency, BmsExchangeRate.BASE_CURRENCY, rateType, date);
|
||||
return success(result);
|
||||
}
|
||||
|
||||
private Date parseDate(String bizDate)
|
||||
{
|
||||
if (bizDate == null || bizDate.isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
try
|
||||
{
|
||||
return new SimpleDateFormat("yyyy-MM-dd").parse(bizDate);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
package com.bms.web.controller.data;
|
||||
|
||||
import java.util.List;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.utils.poi.ExcelUtil;
|
||||
import com.bms.system.domain.BmsRegion;
|
||||
import com.bms.system.service.IBmsRegionService;
|
||||
import com.bms.system.service.IBmsRegionSyncService;
|
||||
|
||||
/**
|
||||
* 区域管理 信息操作处理
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/data/region")
|
||||
public class BmsRegionController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IBmsRegionService regionService;
|
||||
|
||||
@Autowired
|
||||
private IBmsRegionSyncService syncService;
|
||||
|
||||
/**
|
||||
* 获取区域列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('data:region:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(BmsRegion region)
|
||||
{
|
||||
startPage();
|
||||
List<BmsRegion> list = regionService.selectRegionList(region);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取国家下拉选项列表(仅启用状态)
|
||||
*/
|
||||
@GetMapping("/optionselect")
|
||||
public AjaxResult optionselect()
|
||||
{
|
||||
BmsRegion query = new BmsRegion();
|
||||
query.setStatus("0");
|
||||
List<BmsRegion> list = regionService.selectRegionList(query);
|
||||
return success(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出区域列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('data:region:list')")
|
||||
@Log(title = "区域管理", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, BmsRegion region)
|
||||
{
|
||||
List<BmsRegion> list = regionService.selectRegionList(region);
|
||||
ExcelUtil<BmsRegion> util = new ExcelUtil<BmsRegion>(BmsRegion.class);
|
||||
util.exportExcel(response, list, "区域数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取区域详细信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('data:region:query')")
|
||||
@GetMapping(value = "/{regionId}")
|
||||
public AjaxResult getInfo(@PathVariable Long regionId)
|
||||
{
|
||||
return success(regionService.selectRegionById(regionId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改区域
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('data:region:edit')")
|
||||
@Log(title = "区域管理", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@Validated @RequestBody BmsRegion region)
|
||||
{
|
||||
region.setUpdateBy(getUsername());
|
||||
return toAjax(regionService.updateRegion(region));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除区域
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('data:region:remove')")
|
||||
@Log(title = "区域管理", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{regionIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] regionIds)
|
||||
{
|
||||
return toAjax(regionService.deleteRegionByIds(regionIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改区域状态(启用/停用)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('data:region:edit')")
|
||||
@Log(title = "区域管理", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/changeStatus")
|
||||
public AjaxResult changeStatus(@RequestBody BmsRegion region)
|
||||
{
|
||||
region.setUpdateBy(getUsername());
|
||||
return toAjax(regionService.updateRegionStatus(region));
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步国家数据(异步)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('data:region:sync')")
|
||||
@Log(title = "区域管理", businessType = BusinessType.OTHER)
|
||||
@PostMapping("/sync")
|
||||
public AjaxResult sync()
|
||||
{
|
||||
Long logId = syncService.syncRegion();
|
||||
AjaxResult ajax = AjaxResult.success("同步任务已创建,正在后台执行");
|
||||
ajax.put("logId", logId);
|
||||
return ajax;
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package com.bms.web.controller.data;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.system.domain.BmsRegionSyncLog;
|
||||
import com.bms.system.mapper.BmsRegionSyncLogMapper;
|
||||
|
||||
/**
|
||||
* 区域同步日志 信息操作处理
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/data/region/log")
|
||||
public class BmsRegionSyncLogController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private BmsRegionSyncLogMapper syncLogMapper;
|
||||
|
||||
/**
|
||||
* 获取同步日志列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('data:region:log:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(BmsRegionSyncLog syncLog)
|
||||
{
|
||||
startPage();
|
||||
List<BmsRegionSyncLog> list = syncLogMapper.selectSyncLogList(syncLog);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取同步日志详细信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('data:region:log:list')")
|
||||
@GetMapping(value = "/{logId}")
|
||||
public AjaxResult getInfo(@PathVariable Long logId)
|
||||
{
|
||||
return success(syncLogMapper.selectSyncLogById(logId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除同步日志
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('data:region:log:remove')")
|
||||
@Log(title = "同步日志", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{logIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] logIds)
|
||||
{
|
||||
return toAjax(syncLogMapper.deleteSyncLogByIds(logIds));
|
||||
}
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
package com.bms.web.controller.monitor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.price.domain.PrcBillingTask;
|
||||
import com.bms.price.enums.BillTaskSuccessStatus;
|
||||
import com.bms.price.service.IPrcBillingTaskService;
|
||||
|
||||
/**
|
||||
* Monitor: failed / waiting prc_billing_task list and manual resync.
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/monitor/billingTask")
|
||||
public class BillingTaskMonitorController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IPrcBillingTaskService billingTaskService;
|
||||
|
||||
/** Default list = FAILED abnormal tasks. */
|
||||
@PreAuthorize("@ss.hasPermi('monitor:billingTask:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(PrcBillingTask query)
|
||||
{
|
||||
if (query.getSuccessStatus() == null || query.getSuccessStatus().isEmpty())
|
||||
{
|
||||
query.setSuccessStatus(BillTaskSuccessStatus.FAILED.getCode());
|
||||
}
|
||||
else if ("ALL".equalsIgnoreCase(query.getSuccessStatus()))
|
||||
{
|
||||
query.setSuccessStatus(null);
|
||||
}
|
||||
startPage();
|
||||
List<PrcBillingTask> list = billingTaskService.selectList(query);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('monitor:billingTask:list')")
|
||||
@GetMapping("/{taskId}")
|
||||
public AjaxResult getInfo(@PathVariable("taskId") Long taskId)
|
||||
{
|
||||
return success(billingTaskService.getById(taskId));
|
||||
}
|
||||
|
||||
/** Manual resync one task (reset WAITING then process). */
|
||||
@PreAuthorize("@ss.hasPermi('monitor:billingTask:retry')")
|
||||
@Log(title = "billing task retry", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/retry/{taskId}")
|
||||
public AjaxResult retry(@PathVariable("taskId") Long taskId)
|
||||
{
|
||||
return success(billingTaskService.retryTask(taskId));
|
||||
}
|
||||
|
||||
/** Manual resync selected tasks. */
|
||||
@PreAuthorize("@ss.hasPermi('monitor:billingTask:retry')")
|
||||
@Log(title = "billing task batch retry", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/retry")
|
||||
public AjaxResult retryBatch(@RequestBody Long[] taskIds)
|
||||
{
|
||||
if (taskIds == null || taskIds.length == 0)
|
||||
{
|
||||
return error("taskIds required");
|
||||
}
|
||||
int ok = 0;
|
||||
int fail = 0;
|
||||
List<Map<String, Object>> details = new ArrayList<Map<String, Object>>();
|
||||
for (Long taskId : taskIds)
|
||||
{
|
||||
Map<String, Object> row = new HashMap<String, Object>();
|
||||
row.put("taskId", taskId);
|
||||
try
|
||||
{
|
||||
PrcBillingTask task = billingTaskService.retryTask(taskId);
|
||||
row.put("successStatus", task == null ? null : task.getSuccessStatus());
|
||||
row.put("errorMessage", task == null ? null : task.getErrorMessage());
|
||||
if (task != null && BillTaskSuccessStatus.SUCCESS.getCode().equals(task.getSuccessStatus()))
|
||||
{
|
||||
ok++;
|
||||
}
|
||||
else
|
||||
{
|
||||
fail++;
|
||||
}
|
||||
details.add(row);
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
fail++;
|
||||
row.put("successStatus", "ERROR");
|
||||
row.put("errorMessage", e.getMessage());
|
||||
details.add(row);
|
||||
}
|
||||
}
|
||||
Map<String, Object> data = new HashMap<String, Object>();
|
||||
data.put("ok", Integer.valueOf(ok));
|
||||
data.put("fail", Integer.valueOf(fail));
|
||||
data.put("details", details);
|
||||
return success(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package com.bms.web.controller.monitor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisCallback;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.constant.CacheConstants;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.system.domain.SysCache;
|
||||
|
||||
/**
|
||||
* 缓存监控
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/monitor/cache")
|
||||
public class CacheController
|
||||
{
|
||||
@Autowired
|
||||
private RedisTemplate<String, String> redisTemplate;
|
||||
|
||||
private final static List<SysCache> caches = new ArrayList<SysCache>();
|
||||
{
|
||||
caches.add(new SysCache(CacheConstants.LOGIN_TOKEN_KEY, "用户信息"));
|
||||
caches.add(new SysCache(CacheConstants.SYS_CONFIG_KEY, "配置信息"));
|
||||
caches.add(new SysCache(CacheConstants.SYS_DICT_KEY, "数据字典"));
|
||||
caches.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码"));
|
||||
caches.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "防重提交"));
|
||||
caches.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "限流处理"));
|
||||
caches.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
|
||||
@GetMapping()
|
||||
public AjaxResult getInfo() throws Exception
|
||||
{
|
||||
Properties info = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info());
|
||||
Properties commandStats = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info("commandstats"));
|
||||
Object dbSize = redisTemplate.execute((RedisCallback<Object>) connection -> connection.dbSize());
|
||||
|
||||
Map<String, Object> result = new HashMap<>(3);
|
||||
result.put("info", info);
|
||||
result.put("dbSize", dbSize);
|
||||
|
||||
List<Map<String, String>> pieList = new ArrayList<>();
|
||||
commandStats.stringPropertyNames().forEach(key -> {
|
||||
Map<String, String> data = new HashMap<>(2);
|
||||
String property = commandStats.getProperty(key);
|
||||
data.put("name", StringUtils.removeStart(key, "cmdstat_"));
|
||||
data.put("value", StringUtils.substringBetween(property, "calls=", ",usec"));
|
||||
pieList.add(data);
|
||||
});
|
||||
result.put("commandStats", pieList);
|
||||
return AjaxResult.success(result);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
|
||||
@GetMapping("/getNames")
|
||||
public AjaxResult cache()
|
||||
{
|
||||
return AjaxResult.success(caches);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
|
||||
@GetMapping("/getKeys/{cacheName}")
|
||||
public AjaxResult getCacheKeys(@PathVariable String cacheName)
|
||||
{
|
||||
Set<String> cacheKeys = redisTemplate.keys(cacheName + "*");
|
||||
return AjaxResult.success(new TreeSet<>(cacheKeys));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
|
||||
@GetMapping("/getValue/{cacheName}/{cacheKey}")
|
||||
public AjaxResult getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey)
|
||||
{
|
||||
String cacheValue = redisTemplate.opsForValue().get(cacheKey);
|
||||
SysCache sysCache = new SysCache(cacheName, cacheKey, cacheValue);
|
||||
return AjaxResult.success(sysCache);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
|
||||
@DeleteMapping("/clearCacheName/{cacheName}")
|
||||
public AjaxResult clearCacheName(@PathVariable String cacheName)
|
||||
{
|
||||
Collection<String> cacheKeys = redisTemplate.keys(cacheName + "*");
|
||||
redisTemplate.delete(cacheKeys);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
|
||||
@DeleteMapping("/clearCacheKey/{cacheKey}")
|
||||
public AjaxResult clearCacheKey(@PathVariable String cacheKey)
|
||||
{
|
||||
redisTemplate.delete(cacheKey);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
|
||||
@DeleteMapping("/clearCacheAll")
|
||||
public AjaxResult clearCacheAll()
|
||||
{
|
||||
Collection<String> cacheKeys = redisTemplate.keys("*");
|
||||
redisTemplate.delete(cacheKeys);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.bms.web.controller.monitor;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.constant.HttpStatus;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.PageDomain;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.core.page.TableSupport;
|
||||
import com.bms.price.search.BillSearchPage;
|
||||
import com.bms.price.search.IBillSearchStore;
|
||||
|
||||
/**
|
||||
* Generic Elasticsearch business-log viewer.
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/monitor/eslog")
|
||||
public class EsLogController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IBillSearchStore billSearchStore;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('monitor:eslog:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(
|
||||
@RequestParam(value = "logType", required = false) String logType,
|
||||
@RequestParam(value = "bizId", required = false) String bizId,
|
||||
@RequestParam(value = "status", required = false) String status)
|
||||
{
|
||||
PageDomain pageDomain = TableSupport.buildPageRequest();
|
||||
int pageNum = pageDomain.getPageNum() == null ? 1 : pageDomain.getPageNum().intValue();
|
||||
int pageSize = pageDomain.getPageSize() == null ? 10 : pageDomain.getPageSize().intValue();
|
||||
BillSearchPage page = billSearchStore.search(logType, bizId, status, pageNum, pageSize);
|
||||
TableDataInfo rsp = new TableDataInfo();
|
||||
rsp.setCode(HttpStatus.SUCCESS);
|
||||
rsp.setMsg("\u67e5\u8be2\u6210\u529f");
|
||||
rsp.setRows(page.getRows());
|
||||
rsp.setTotal(page.getTotal());
|
||||
return rsp;
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('monitor:eslog:list')")
|
||||
@GetMapping("/{docId}")
|
||||
public AjaxResult getInfo(@PathVariable("docId") String docId)
|
||||
{
|
||||
return success(billSearchStore.getByDocId(docId));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.bms.web.controller.monitor;
|
||||
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.framework.web.domain.Server;
|
||||
|
||||
/**
|
||||
* 服务器监控
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/monitor/server")
|
||||
public class ServerController
|
||||
{
|
||||
@PreAuthorize("@ss.hasPermi('monitor:server:list')")
|
||||
@GetMapping()
|
||||
public AjaxResult getInfo() throws Exception
|
||||
{
|
||||
Server server = new Server();
|
||||
server.copyTo();
|
||||
return AjaxResult.success(server);
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
package com.bms.web.controller.monitor;
|
||||
|
||||
import java.util.List;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.utils.poi.ExcelUtil;
|
||||
import com.bms.framework.web.service.SysPasswordService;
|
||||
import com.bms.system.domain.SysLogininfor;
|
||||
import com.bms.system.service.ISysLogininforService;
|
||||
|
||||
/**
|
||||
* 系统访问记录
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/monitor/logininfor")
|
||||
public class SysLogininforController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISysLogininforService logininforService;
|
||||
|
||||
@Autowired
|
||||
private SysPasswordService passwordService;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('monitor:logininfor:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SysLogininfor logininfor)
|
||||
{
|
||||
startPage();
|
||||
List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@Log(title = "登录日志", businessType = BusinessType.EXPORT)
|
||||
@PreAuthorize("@ss.hasPermi('monitor:logininfor:export')")
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, SysLogininfor logininfor)
|
||||
{
|
||||
List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
|
||||
ExcelUtil<SysLogininfor> util = new ExcelUtil<SysLogininfor>(SysLogininfor.class);
|
||||
util.exportExcel(response, list, "登录日志");
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
|
||||
@Log(title = "登录日志", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{infoIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] infoIds)
|
||||
{
|
||||
return toAjax(logininforService.deleteLogininforByIds(infoIds));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
|
||||
@Log(title = "登录日志", businessType = BusinessType.CLEAN)
|
||||
@DeleteMapping("/clean")
|
||||
public AjaxResult clean()
|
||||
{
|
||||
logininforService.cleanLogininfor();
|
||||
return success();
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('monitor:logininfor:unlock')")
|
||||
@Log(title = "账户解锁", businessType = BusinessType.OTHER)
|
||||
@GetMapping("/unlock/{userName}")
|
||||
public AjaxResult unlock(@PathVariable("userName") String userName)
|
||||
{
|
||||
passwordService.clearLoginRecordCache(userName);
|
||||
return success();
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
package com.bms.web.controller.monitor;
|
||||
|
||||
import java.util.List;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.utils.poi.ExcelUtil;
|
||||
import com.bms.system.domain.SysOperLog;
|
||||
import com.bms.system.service.ISysOperLogService;
|
||||
|
||||
/**
|
||||
* 操作日志记录
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/monitor/operlog")
|
||||
public class SysOperlogController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISysOperLogService operLogService;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('monitor:operlog:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SysOperLog operLog)
|
||||
{
|
||||
startPage();
|
||||
List<SysOperLog> list = operLogService.selectOperLogList(operLog);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@Log(title = "操作日志", businessType = BusinessType.EXPORT)
|
||||
@PreAuthorize("@ss.hasPermi('monitor:operlog:export')")
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, SysOperLog operLog)
|
||||
{
|
||||
List<SysOperLog> list = operLogService.selectOperLogList(operLog);
|
||||
ExcelUtil<SysOperLog> util = new ExcelUtil<SysOperLog>(SysOperLog.class);
|
||||
util.exportExcel(response, list, "操作日志");
|
||||
}
|
||||
|
||||
@Log(title = "操作日志", businessType = BusinessType.DELETE)
|
||||
@PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
|
||||
@DeleteMapping("/{operIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] operIds)
|
||||
{
|
||||
return toAjax(operLogService.deleteOperLogByIds(operIds));
|
||||
}
|
||||
|
||||
@Log(title = "操作日志", businessType = BusinessType.CLEAN)
|
||||
@PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
|
||||
@DeleteMapping("/clean")
|
||||
public AjaxResult clean()
|
||||
{
|
||||
operLogService.cleanOperLog();
|
||||
return success();
|
||||
}
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
package com.bms.web.controller.monitor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.constant.CacheConstants;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.domain.model.LoginUser;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.core.redis.RedisCache;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.system.domain.SysUserOnline;
|
||||
import com.bms.system.service.ISysUserOnlineService;
|
||||
|
||||
/**
|
||||
* 在线用户监控
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/monitor/online")
|
||||
public class SysUserOnlineController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISysUserOnlineService userOnlineService;
|
||||
|
||||
@Autowired
|
||||
private RedisCache redisCache;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('monitor:online:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(String ipaddr, String userName)
|
||||
{
|
||||
Collection<String> keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
|
||||
List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>();
|
||||
for (String key : keys)
|
||||
{
|
||||
LoginUser user = redisCache.getCacheObject(key);
|
||||
if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName))
|
||||
{
|
||||
userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user));
|
||||
}
|
||||
else if (StringUtils.isNotEmpty(ipaddr))
|
||||
{
|
||||
userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user));
|
||||
}
|
||||
else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser()))
|
||||
{
|
||||
userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user));
|
||||
}
|
||||
else
|
||||
{
|
||||
userOnlineList.add(userOnlineService.loginUserToUserOnline(user));
|
||||
}
|
||||
}
|
||||
Collections.reverse(userOnlineList);
|
||||
userOnlineList.removeAll(Collections.singleton(null));
|
||||
return getDataTable(userOnlineList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 强退用户
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('monitor:online:forceLogout')")
|
||||
@Log(title = "在线用户", businessType = BusinessType.FORCE)
|
||||
@DeleteMapping("/{tokenId}")
|
||||
public AjaxResult forceLogout(@PathVariable String tokenId)
|
||||
{
|
||||
redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId);
|
||||
return success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
package com.bms.web.controller.price;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.price.domain.PrcOrderBill;
|
||||
import com.bms.price.domain.PrcQuote;
|
||||
import com.bms.price.domain.vo.AddIncomeBillFeeRequest;
|
||||
import com.bms.price.domain.vo.UpdateIncomeBillFeeRequest;
|
||||
import com.bms.price.domain.vo.TmsPriceBillRequest;
|
||||
import com.bms.price.domain.vo.TmsPriceQuoteRequest;
|
||||
import com.bms.price.domain.vo.TmsPriceQuoteResult;
|
||||
import com.bms.price.service.IPrcOrderBillService;
|
||||
import com.bms.price.service.ITmsPriceQuoteService;
|
||||
|
||||
/**
|
||||
* Billing center: order quote trial (authenticated).
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/price/billing")
|
||||
public class BillingController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ITmsPriceQuoteService tmsPriceQuoteService;
|
||||
|
||||
@Autowired
|
||||
private IPrcOrderBillService prcOrderBillService;
|
||||
|
||||
/**
|
||||
* Historical quote list.
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('price:billing:quote')")
|
||||
@GetMapping("/quote/list")
|
||||
public TableDataInfo list(PrcQuote query)
|
||||
{
|
||||
startPage();
|
||||
List<PrcQuote> list = tmsPriceQuoteService.selectQuoteList(query);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Historical quote detail with fee lines.
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('price:billing:quote')")
|
||||
@GetMapping("/quote/{quoteId}")
|
||||
public AjaxResult getInfo(@PathVariable String quoteId)
|
||||
{
|
||||
return success(tmsPriceQuoteService.getQuote(quoteId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Same matching logic as TMS open API, for BMS console trial.
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('price:billing:quote')")
|
||||
@PostMapping("/quote")
|
||||
public AjaxResult quote(@Validated @RequestBody TmsPriceQuoteRequest request)
|
||||
{
|
||||
TmsPriceQuoteResult result = tmsPriceQuoteService.quote(request);
|
||||
return success(result);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:billing:bill')")
|
||||
@GetMapping("/bill/list")
|
||||
public TableDataInfo billList(PrcOrderBill query)
|
||||
{
|
||||
startPage();
|
||||
List<PrcOrderBill> list = prcOrderBillService.selectBillList(query);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Order no options for remote-search dropdown (bill list multi search).
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('price:billing:bill')")
|
||||
@GetMapping("/bill/orderNos")
|
||||
public AjaxResult orderNoOptions(@RequestParam(value = "keyword", required = false) String keyword)
|
||||
{
|
||||
return success(prcOrderBillService.listOrderNoOptions(keyword));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:billing:bill')")
|
||||
@GetMapping("/bill/trackingNos")
|
||||
public AjaxResult trackingNoOptions(@RequestParam(value = "keyword", required = false) String keyword)
|
||||
{
|
||||
return success(prcOrderBillService.listTrackingNoOptions(keyword));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:billing:bill')")
|
||||
@GetMapping("/bill/transferNos")
|
||||
public AjaxResult transferNoOptions(@RequestParam(value = "keyword", required = false) String keyword)
|
||||
{
|
||||
return success(prcOrderBillService.listTransferNoOptions(keyword));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:billing:bill')")
|
||||
@GetMapping("/bill/{billId}")
|
||||
public AjaxResult getBill(@PathVariable String billId)
|
||||
{
|
||||
return success(prcOrderBillService.getBill(billId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch update order credit arrears status (ARREARS -> NORMAL) with available-credit check.
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('price:billing:arrearsUpdate')")
|
||||
@Log(title = "Billing credit arrears", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/bill/creditArrears")
|
||||
public AjaxResult updateCreditArrears(@RequestBody java.util.List<String> billIds)
|
||||
{
|
||||
if (billIds == null || billIds.isEmpty())
|
||||
{
|
||||
return error("请勾选要更新的订单");
|
||||
}
|
||||
int success = 0;
|
||||
java.util.List<String> fails = new java.util.ArrayList<String>();
|
||||
for (String billId : billIds)
|
||||
{
|
||||
try
|
||||
{
|
||||
prcOrderBillService.updateCreditArrearsStatus(billId);
|
||||
success++;
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
String msg = e.getMessage();
|
||||
if (msg == null || msg.isEmpty())
|
||||
{
|
||||
msg = e.getClass().getSimpleName();
|
||||
}
|
||||
fails.add((billId == null ? "" : billId) + ": " + msg);
|
||||
}
|
||||
}
|
||||
if (fails.isEmpty())
|
||||
{
|
||||
return success("成功更新 " + success + " 条");
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("成功 ").append(success).append(" 条,失败 ").append(fails.size()).append(" 条");
|
||||
int limit = Math.min(fails.size(), 5);
|
||||
for (int i = 0; i < limit; i++)
|
||||
{
|
||||
sb.append(";").append(fails.get(i));
|
||||
}
|
||||
if (fails.size() > limit)
|
||||
{
|
||||
sb.append("…");
|
||||
}
|
||||
if (success > 0)
|
||||
{
|
||||
return success(sb.toString());
|
||||
}
|
||||
return error(sb.toString());
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:billing:feeAdd')")
|
||||
@Log(title = "Billing income fee", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/bill/fee")
|
||||
public AjaxResult addIncomeFee(@Validated @RequestBody AddIncomeBillFeeRequest request)
|
||||
{
|
||||
return success(prcOrderBillService.addIncomeFee(request));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:billing:feeEdit')")
|
||||
@Log(title = "Billing income fee", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/bill/fee")
|
||||
public AjaxResult updateIncomeFee(@Validated @RequestBody UpdateIncomeBillFeeRequest request)
|
||||
{
|
||||
return success(prcOrderBillService.updateIncomeFee(request));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:billing:feeRemove')")
|
||||
@Log(title = "Billing income fee", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/bill/fee/{feeId}")
|
||||
public AjaxResult deleteIncomeFee(@PathVariable String feeId)
|
||||
{
|
||||
return success(prcOrderBillService.deleteIncomeFee(feeId));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:billing:bill')")
|
||||
@PostMapping("/bill")
|
||||
public AjaxResult bill(@Validated @RequestBody TmsPriceBillRequest request)
|
||||
{
|
||||
TmsPriceQuoteResult result = prcOrderBillService.bill(request);
|
||||
return success(result);
|
||||
}
|
||||
}
|
||||
+277
@@ -0,0 +1,277 @@
|
||||
package com.bms.web.controller.price;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.utils.MessageUtils;
|
||||
import com.bms.price.domain.PrcCustomerPriceSet;
|
||||
import com.bms.price.domain.PrcPriceSet;
|
||||
import com.bms.price.domain.PrcPriceSetDetail;
|
||||
import com.bms.price.domain.PrcPriceSetSaveTask;
|
||||
import com.bms.price.domain.PrcPriceSetVersion;
|
||||
import com.bms.price.service.IPrcPriceSetService;
|
||||
|
||||
/**
|
||||
* 价格套餐管理
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/price/set")
|
||||
public class PriceSetController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IPrcPriceSetService priceSetService;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(PrcPriceSet set)
|
||||
{
|
||||
startPage();
|
||||
List<PrcPriceSet> list = priceSetService.selectPrcPriceSetList(set);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:query')")
|
||||
@GetMapping("/{priceSetId:[0-9]+}")
|
||||
public AjaxResult getInfo(@PathVariable Long priceSetId)
|
||||
{
|
||||
return success(priceSetService.selectPrcPriceSetById(priceSetId));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:add')")
|
||||
@Log(title = "价格套餐", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@Validated @RequestBody PrcPriceSet set)
|
||||
{
|
||||
set.setCreateBy(getUsername());
|
||||
set.setUpdateBy(getUsername());
|
||||
String taskId = priceSetService.submitSaveAsync(set);
|
||||
// Do not pass bare String to success(): overload puts it into msg, not data.
|
||||
Map<String, Object> payload = new HashMap<String, Object>();
|
||||
payload.put("taskId", taskId);
|
||||
return success(payload);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:query')")
|
||||
@GetMapping("/save/task/{taskId}")
|
||||
public AjaxResult getSaveTask(@PathVariable String taskId)
|
||||
{
|
||||
PrcPriceSetSaveTask task = priceSetService.getSaveTask(taskId);
|
||||
if (task == null)
|
||||
{
|
||||
return error(MessageUtils.message("price.set.save.task.notExists"));
|
||||
}
|
||||
return success(task);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:edit')")
|
||||
@Log(title = "价格套餐", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@Validated @RequestBody PrcPriceSet set)
|
||||
{
|
||||
set.setUpdateBy(getUsername());
|
||||
return toAjax(priceSetService.updatePrcPriceSet(set));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:remove')")
|
||||
@Log(title = "价格套餐", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{priceSetIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] priceSetIds)
|
||||
{
|
||||
return toAjax(priceSetService.deletePrcPriceSetByIds(priceSetIds));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:audit')")
|
||||
@Log(title = "价格套餐提交审核", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/submit/{priceSetId}")
|
||||
public AjaxResult submit(@PathVariable Long priceSetId)
|
||||
{
|
||||
return toAjax(priceSetService.submit(priceSetId, getUsername()));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:audit')")
|
||||
@Log(title = "价格套餐生效", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/approve/{priceSetId}")
|
||||
public AjaxResult approve(@PathVariable Long priceSetId)
|
||||
{
|
||||
return toAjax(priceSetService.approve(priceSetId, getUsername()));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:audit')")
|
||||
@Log(title = "价格套餐驳回", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/reject/{priceSetId}")
|
||||
public AjaxResult reject(@PathVariable Long priceSetId)
|
||||
{
|
||||
return toAjax(priceSetService.reject(priceSetId, getUsername()));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:edit')")
|
||||
@Log(title = "Price set version activate", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/version/activate/{psvId}")
|
||||
public AjaxResult activateVersion(@PathVariable Long psvId, @RequestBody(required = false) PrcPriceSetVersion body)
|
||||
{
|
||||
Date effectiveTime = body == null ? null : body.getEffectiveTime();
|
||||
return toAjax(priceSetService.activateVersion(psvId, effectiveTime, getUsername()));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:add')")
|
||||
@Log(title = "Price set version copy", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/version/copy/{psvId}")
|
||||
public AjaxResult copyVersion(@PathVariable Long psvId)
|
||||
{
|
||||
Long newPsvId = priceSetService.copyVersion(psvId, getUsername());
|
||||
return success(newPsvId);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:edit')")
|
||||
@Log(title = "Price set version delete", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/version/{psvId}")
|
||||
public AjaxResult deleteVersion(@PathVariable Long psvId)
|
||||
{
|
||||
return toAjax(priceSetService.deleteVersion(psvId, getUsername()));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:audit')")
|
||||
@Log(title = "Price set disable", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/disable/{priceSetId}")
|
||||
public AjaxResult disable(@PathVariable Long priceSetId)
|
||||
{
|
||||
return toAjax(priceSetService.disable(priceSetId, getUsername()));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:audit')")
|
||||
@Log(title = "Price set enable", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/enable/{priceSetId}")
|
||||
public AjaxResult enable(@PathVariable Long priceSetId)
|
||||
{
|
||||
return toAjax(priceSetService.enable(priceSetId, getUsername()));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:add')")
|
||||
@Log(title = "Price set copy", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/copy/{priceSetId}")
|
||||
public AjaxResult copy(@PathVariable Long priceSetId)
|
||||
{
|
||||
Long id = priceSetService.copy(priceSetId, getUsername());
|
||||
return success(id);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:query')")
|
||||
@PostMapping("/validate")
|
||||
public AjaxResult validate(@RequestBody PrcPriceSet set)
|
||||
{
|
||||
return success(priceSetService.validate(set));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:list')")
|
||||
@GetMapping("/detail/list")
|
||||
public TableDataInfo detailList(PrcPriceSetDetail detail)
|
||||
{
|
||||
startPage();
|
||||
List<PrcPriceSetDetail> list = priceSetService.selectDetailList(detail);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 版本明细搜索下拉选项:按版本去重后的 产品/国家/分区
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('price:set:list')")
|
||||
@GetMapping("/detail/options")
|
||||
public AjaxResult detailOptions(@RequestParam("psvId") Long psvId)
|
||||
{
|
||||
return success(priceSetService.selectDetailOptions(psvId));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:edit') or @ss.hasPermi('price:set:forceEdit')")
|
||||
@Log(title = "套餐明细", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/detail")
|
||||
public AjaxResult addDetail(@RequestBody PrcPriceSetDetail detail)
|
||||
{
|
||||
return toAjax(priceSetService.insertDetail(detail));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:edit') or @ss.hasPermi('price:set:forceEdit')")
|
||||
@Log(title = "\u5957\u9910\u660e\u7ec6", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/detail")
|
||||
public AjaxResult editDetail(@RequestBody PrcPriceSetDetail detail)
|
||||
{
|
||||
return toAjax(priceSetService.updateDetail(detail));
|
||||
}
|
||||
|
||||
/**
|
||||
* Async batch write of detail surcharge snapshots. Returns taskId; poll /save/task/{taskId}.
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('price:set:edit') or @ss.hasPermi('price:set:forceEdit')")
|
||||
@Log(title = "\u5957\u9910\u9644\u52a0\u8d39", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/detail/surcharge/async")
|
||||
public AjaxResult batchSurchargeAsync(@RequestBody List<PrcPriceSetDetail> details)
|
||||
{
|
||||
String taskId = priceSetService.submitDetailSurchargeAsync(details);
|
||||
Map<String, Object> payload = new HashMap<String, Object>();
|
||||
payload.put("taskId", taskId);
|
||||
return success(payload);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:edit') or @ss.hasPermi('price:set:forceEdit')")
|
||||
@Log(title = "\u5957\u9910\u660e\u7ec6", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/detail/{psdIds}")
|
||||
public AjaxResult removeDetail(@PathVariable Long[] psdIds)
|
||||
{
|
||||
return toAjax(priceSetService.deleteDetailByIds(psdIds));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:list')")
|
||||
@GetMapping("/customer/list")
|
||||
public TableDataInfo customerList(PrcCustomerPriceSet customer)
|
||||
{
|
||||
startPage();
|
||||
List<PrcCustomerPriceSet> list = priceSetService.selectCustomerList(customer);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:edit')")
|
||||
@Log(title = "套餐客户绑定", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/customer")
|
||||
public AjaxResult addCustomer(@RequestBody PrcCustomerPriceSet customer)
|
||||
{
|
||||
customer.setCreateBy(getUsername());
|
||||
return toAjax(priceSetService.insertCustomer(customer));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:edit')")
|
||||
@Log(title = "套餐客户绑定", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/customer")
|
||||
public AjaxResult editCustomer(@RequestBody PrcCustomerPriceSet customer)
|
||||
{
|
||||
customer.setUpdateBy(getUsername());
|
||||
return toAjax(priceSetService.updateCustomer(customer));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:edit')")
|
||||
@Log(title = "套餐客户绑定", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/customer/{customerPricesetIds}")
|
||||
public AjaxResult removeCustomer(@PathVariable Long[] customerPricesetIds)
|
||||
{
|
||||
return toAjax(priceSetService.deleteCustomerByIds(customerPricesetIds));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package com.bms.web.controller.price;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.price.domain.BmsProduct;
|
||||
import com.bms.price.domain.BmsProductCountry;
|
||||
import com.bms.price.service.IBmsProductService;
|
||||
|
||||
/**
|
||||
* 产品列表(含 Excel 导入)
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/price/product")
|
||||
public class ProductController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IBmsProductService productService;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:product:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(BmsProduct product)
|
||||
{
|
||||
startPage();
|
||||
List<BmsProduct> list = productService.selectBmsProductList(product);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:product:query')")
|
||||
@GetMapping("/{productCode}/countries")
|
||||
public AjaxResult countries(@PathVariable String productCode,
|
||||
@RequestParam(required = false) Date effectiveDate,
|
||||
@RequestParam(required = false) Long productId)
|
||||
{
|
||||
List<BmsProductCountry> list = productService.selectCountryListByProductCode(productCode, effectiveDate, productId);
|
||||
return success(list);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:product:query')")
|
||||
@GetMapping("/{productId}")
|
||||
public AjaxResult getInfo(@PathVariable Long productId)
|
||||
{
|
||||
return success(productService.selectBmsProductById(productId));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:product:add')")
|
||||
@Log(title = "产品列表", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@Validated @RequestBody BmsProduct product)
|
||||
{
|
||||
product.setCreateBy(getUsername());
|
||||
return toAjax(productService.insertBmsProduct(product));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:product:edit')")
|
||||
@Log(title = "产品列表", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@Validated @RequestBody BmsProduct product)
|
||||
{
|
||||
product.setUpdateBy(getUsername());
|
||||
return toAjax(productService.updateBmsProduct(product));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改产品国家明细行(重量段/运费/挂号费/尺寸/尾程/时效/生效失效日期)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('price:product:edit')")
|
||||
@Log(title = "产品国家明细", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/country")
|
||||
public AjaxResult editCountry(@RequestBody BmsProductCountry country)
|
||||
{
|
||||
return toAjax(productService.updateBmsProductCountry(country));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:product:remove')")
|
||||
@Log(title = "产品列表", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{productIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] productIds)
|
||||
{
|
||||
return toAjax(productService.deleteBmsProductByIds(productIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入威狮B2C小包价表.xlsx(产品目录 + 国家服务明细)
|
||||
*/
|
||||
@Log(title = "产品列表", businessType = BusinessType.IMPORT)
|
||||
@PreAuthorize("@ss.hasPermi('price:product:import')")
|
||||
@PostMapping("/importData")
|
||||
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
|
||||
{
|
||||
String message = productService.importProductExcel(file, updateSupport, getUsername());
|
||||
return success(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Import a single-country linehaul cost sheet. countryCode is the destination.
|
||||
*/
|
||||
@Log(title = "\u4ea7\u54c1\u5217\u8868", businessType = BusinessType.IMPORT)
|
||||
@PreAuthorize("@ss.hasPermi('price:product:import')")
|
||||
@PostMapping("/importCountryData")
|
||||
public AjaxResult importCountryData(MultipartFile file, String countryCode) throws Exception
|
||||
{
|
||||
String message = productService.importCountryProductExcel(file, countryCode, getUsername());
|
||||
return success(message);
|
||||
}
|
||||
}
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
package com.bms.web.controller.price;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.price.domain.PrcSurcharge;
|
||||
import com.bms.price.domain.PrcSurchargeRel;
|
||||
import com.bms.price.service.IPrcSurchargeRelService;
|
||||
import com.bms.price.service.IPrcSurchargeService;
|
||||
|
||||
/**
|
||||
* 附加费配置
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/price/surcharge")
|
||||
public class SurchargeController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IPrcSurchargeService surchargeService;
|
||||
|
||||
@Autowired
|
||||
private IPrcSurchargeRelService surchargeRelService;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:surcharge:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(PrcSurcharge surcharge)
|
||||
{
|
||||
startPage();
|
||||
List<PrcSurcharge> list = surchargeService.selectPrcSurchargeList(surcharge);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:surcharge:query')")
|
||||
@GetMapping("/{scId}")
|
||||
public AjaxResult getInfo(@PathVariable Long scId)
|
||||
{
|
||||
return success(surchargeService.selectPrcSurchargeById(scId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询指定产品已关联的附加费(非分页,供产品列表抽屉、套餐明细展示使用)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('price:surcharge:query') or @ss.hasPermi('price:set:query') or @ss.hasPermi('price:set:add')")
|
||||
@GetMapping("/byProduct/{productCode}")
|
||||
public AjaxResult listByProduct(@PathVariable String productCode)
|
||||
{
|
||||
return success(surchargeRelService.selectRelByProductCode(productCode));
|
||||
}
|
||||
|
||||
/**
|
||||
* 附加费配置全量(非分页,供套餐明细勾选使用)
|
||||
*
|
||||
* 不要求 price:surcharge:list 权限,套餐维护角色(price:set:*)也能读,避免套餐页拿到 403 空列表。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('price:surcharge:list') or @ss.hasPermi('price:surcharge:query')"
|
||||
+ " or @ss.hasPermi('price:set:query') or @ss.hasPermi('price:set:add') or @ss.hasPermi('price:set:edit')"
|
||||
+ " or @ss.hasPermi('price:billing:bill')")
|
||||
@GetMapping("/options")
|
||||
public AjaxResult listOptions(PrcSurcharge surcharge)
|
||||
{
|
||||
return success(surchargeService.selectPrcSurchargeList(surcharge));
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定附加费到产品/明细(body: scId, productId, productCode, detailId;detailId 空=产品级)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('price:surcharge:add')")
|
||||
@Log(title = "附加费关联", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/rel")
|
||||
public AjaxResult addRel(@RequestBody PrcSurchargeRel rel)
|
||||
{
|
||||
rel.setCreateBy(getUsername());
|
||||
return toAjax(surchargeRelService.insertPrcSurchargeRel(rel));
|
||||
}
|
||||
|
||||
/**
|
||||
* 解绑(删除关联记录,不删除附加费本身)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('price:surcharge:remove')")
|
||||
@Log(title = "附加费关联", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/rel/{relIds}")
|
||||
public AjaxResult removeRel(@PathVariable Long[] relIds)
|
||||
{
|
||||
return toAjax(surchargeRelService.deletePrcSurchargeRelByIds(relIds));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:surcharge:add')")
|
||||
@Log(title = "附加费配置", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@Validated @RequestBody PrcSurcharge surcharge)
|
||||
{
|
||||
surcharge.setCreateBy(getUsername());
|
||||
return toAjax(surchargeService.insertPrcSurcharge(surcharge));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改(版本化):内容无变化时返回 warn 提示,否则原记录作废 + 插入新记录,产品关联自动重指向新记录。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('price:surcharge:edit')")
|
||||
@Log(title = "附加费配置", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@Validated @RequestBody PrcSurcharge surcharge)
|
||||
{
|
||||
surcharge.setUpdateBy(getUsername());
|
||||
int rows = surchargeService.updatePrcSurcharge(surcharge);
|
||||
if (rows == -1)
|
||||
{
|
||||
return AjaxResult.warn("未做任何修改");
|
||||
}
|
||||
return toAjax(rows);
|
||||
}
|
||||
|
||||
/**
|
||||
* 停用(原地修改 ss_code=of,不新增数据,不物理删除)。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('price:surcharge:remove')")
|
||||
@Log(title = "附加费停用", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/disable/{scIds}")
|
||||
public AjaxResult disable(@PathVariable Long[] scIds)
|
||||
{
|
||||
return toAjax(surchargeService.disablePrcSurchargeByIds(scIds, getUsername()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用(原地修改 ss_code=on,不新增数据)。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('price:surcharge:remove')")
|
||||
@Log(title = "附加费启用", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/enable/{scIds}")
|
||||
public AjaxResult enable(@PathVariable Long[] scIds)
|
||||
{
|
||||
return toAjax(surchargeService.enablePrcSurchargeByIds(scIds, getUsername()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package com.bms.web.controller.price;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.price.domain.PrcWeightSectionDetail;
|
||||
import com.bms.price.domain.PrcWeightSectionTemplate;
|
||||
import com.bms.price.service.IPrcWeightService;
|
||||
|
||||
/**
|
||||
* 重量段管理
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/price/weight")
|
||||
public class WeightController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IPrcWeightService weightService;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:weight:list')")
|
||||
@GetMapping("/template/list")
|
||||
public TableDataInfo templateList(PrcWeightSectionTemplate template)
|
||||
{
|
||||
startPage();
|
||||
List<PrcWeightSectionTemplate> list = weightService.selectPrcWeightSectionTemplateList(template);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:weight:query')")
|
||||
@GetMapping("/template/{wstId}")
|
||||
public AjaxResult getTemplate(@PathVariable Long wstId)
|
||||
{
|
||||
return success(weightService.selectPrcWeightSectionTemplateById(wstId));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:weight:add')")
|
||||
@Log(title = "重量段模板", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/template")
|
||||
public AjaxResult addTemplate(@Validated @RequestBody PrcWeightSectionTemplate template)
|
||||
{
|
||||
template.setCreateBy(getUsername());
|
||||
return toAjax(weightService.insertPrcWeightSectionTemplate(template));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:weight:edit')")
|
||||
@Log(title = "重量段模板", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/template")
|
||||
public AjaxResult editTemplate(@Validated @RequestBody PrcWeightSectionTemplate template)
|
||||
{
|
||||
template.setUpdateBy(getUsername());
|
||||
return toAjax(weightService.updatePrcWeightSectionTemplate(template));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:weight:remove')")
|
||||
@Log(title = "重量段模板", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/template/{wstIds}")
|
||||
public AjaxResult removeTemplate(@PathVariable Long[] wstIds)
|
||||
{
|
||||
return toAjax(weightService.deletePrcWeightSectionTemplateByIds(wstIds));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:weight:list')")
|
||||
@GetMapping("/detail/list")
|
||||
public TableDataInfo detailList(PrcWeightSectionDetail detail)
|
||||
{
|
||||
startPage();
|
||||
List<PrcWeightSectionDetail> list = weightService.selectPrcWeightSectionDetailList(detail);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:weight:add')")
|
||||
@Log(title = "重量段明细", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/detail")
|
||||
public AjaxResult addDetail(@Validated @RequestBody PrcWeightSectionDetail detail)
|
||||
{
|
||||
return toAjax(weightService.insertPrcWeightSectionDetail(detail));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:weight:edit')")
|
||||
@Log(title = "重量段明细", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/detail")
|
||||
public AjaxResult editDetail(@Validated @RequestBody PrcWeightSectionDetail detail)
|
||||
{
|
||||
return toAjax(weightService.updatePrcWeightSectionDetail(detail));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:weight:remove')")
|
||||
@Log(title = "重量段明细", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/detail/{wsdIds}")
|
||||
public AjaxResult removeDetail(@PathVariable Long[] wsdIds)
|
||||
{
|
||||
return toAjax(weightService.deletePrcWeightSectionDetailByIds(wsdIds));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package com.bms.web.controller.price;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.price.domain.PrcZone;
|
||||
import com.bms.price.domain.PrcZoneDetail;
|
||||
import com.bms.price.domain.PrcZoneRegion;
|
||||
import com.bms.price.service.IPrcZoneService;
|
||||
|
||||
/**
|
||||
* Zone management: bms_region -> zone -> postcode detail
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/price/zone")
|
||||
public class ZoneController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IPrcZoneService zoneService;
|
||||
|
||||
// ========== countries that already have zones (from bms_region) ==========
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:zone:list')")
|
||||
@GetMapping("/country/list")
|
||||
public TableDataInfo countryList(PrcZoneRegion query)
|
||||
{
|
||||
startPage();
|
||||
List<PrcZoneRegion> list = zoneService.selectZoneRegionList(query);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:zone:query')")
|
||||
@GetMapping("/country/{regionId}")
|
||||
public AjaxResult getCountry(@PathVariable Long regionId)
|
||||
{
|
||||
return success(zoneService.selectZoneRegionById(regionId));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:zone:remove')")
|
||||
@Log(title = "ZoneRegion", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/country/{regionIds}")
|
||||
public AjaxResult removeCountryZones(@PathVariable Long[] regionIds)
|
||||
{
|
||||
return toAjax(zoneService.deleteZonesByRegionIds(regionIds));
|
||||
}
|
||||
|
||||
// ========== zone ==========
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:zone:list')")
|
||||
@GetMapping("/item/list")
|
||||
public TableDataInfo zoneList(PrcZone zone)
|
||||
{
|
||||
startPage();
|
||||
List<PrcZone> list = zoneService.selectPrcZoneList(zone);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:zone:query')")
|
||||
@GetMapping("/item/{zoneId}")
|
||||
public AjaxResult getZone(@PathVariable Long zoneId)
|
||||
{
|
||||
return success(zoneService.selectPrcZoneById(zoneId));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:zone:add')")
|
||||
@Log(title = "Zone", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/item")
|
||||
public AjaxResult addZone(@Validated @RequestBody PrcZone zone)
|
||||
{
|
||||
return toAjax(zoneService.insertPrcZone(zone));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:zone:edit')")
|
||||
@Log(title = "Zone", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/item")
|
||||
public AjaxResult editZone(@Validated @RequestBody PrcZone zone)
|
||||
{
|
||||
return toAjax(zoneService.updatePrcZone(zone));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:zone:remove')")
|
||||
@Log(title = "Zone", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/item/{zoneIds}")
|
||||
public AjaxResult removeZone(@PathVariable Long[] zoneIds)
|
||||
{
|
||||
return toAjax(zoneService.deletePrcZoneByIds(zoneIds));
|
||||
}
|
||||
|
||||
// ========== detail ==========
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:zone:list')")
|
||||
@GetMapping("/detail/list")
|
||||
public TableDataInfo detailList(PrcZoneDetail detail)
|
||||
{
|
||||
startPage();
|
||||
List<PrcZoneDetail> list = zoneService.selectPrcZoneDetailList(detail);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:zone:add')")
|
||||
@Log(title = "ZoneDetail", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/detail")
|
||||
public AjaxResult addDetail(@Validated @RequestBody PrcZoneDetail detail)
|
||||
{
|
||||
return toAjax(zoneService.insertPrcZoneDetail(detail));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:zone:edit')")
|
||||
@Log(title = "ZoneDetail", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/detail")
|
||||
public AjaxResult editDetail(@Validated @RequestBody PrcZoneDetail detail)
|
||||
{
|
||||
return toAjax(zoneService.updatePrcZoneDetail(detail));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:zone:remove')")
|
||||
@Log(title = "ZoneDetail", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/detail/{detailIds}")
|
||||
public AjaxResult removeDetail(@PathVariable Long[] detailIds)
|
||||
{
|
||||
return toAjax(zoneService.deletePrcZoneDetailByIds(detailIds));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:zone:add')")
|
||||
@Log(title = "ZoneImport", businessType = BusinessType.IMPORT)
|
||||
@PostMapping("/importData")
|
||||
public AjaxResult importData(MultipartFile file) throws Exception
|
||||
{
|
||||
String message = zoneService.importZoneExcel(file, getUsername());
|
||||
return success(message);
|
||||
}
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package com.bms.web.controller.system;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.customer.customermoney.domain.CustomerCreditGrant;
|
||||
import com.bms.customer.customermoney.service.ICreditQuotaService;
|
||||
import com.bms.customer.customermoney.vo.RoleCreditQuotaVo;
|
||||
|
||||
/**
|
||||
* 角色可分配额度总额(角色额度池)管理
|
||||
*
|
||||
* @author bms
|
||||
* @date 2026-09-20
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/system/role/creditQuota")
|
||||
public class RoleCreditQuotaController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ICreditQuotaService creditQuotaService;
|
||||
|
||||
/**
|
||||
* 全部角色额度池列表(含已分配/剩余可分配,实时统计)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:role:list')")
|
||||
@GetMapping("/list")
|
||||
public AjaxResult list()
|
||||
{
|
||||
return success(creditQuotaService.listRoleQuotas());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置角色可分配额度总额(不能小于该池当前已分配额)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:role:edit')")
|
||||
@Log(title = "角色额度池设置", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult set(@RequestBody RoleCreditQuotaVo body)
|
||||
{
|
||||
creditQuotaService.setRoleQuota(body.getRoleId(), body.getTotalQuota(), body.getRemark());
|
||||
return success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 额度池占用台账查询(可按角色/客户/类型/状态筛选)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:role:list')")
|
||||
@GetMapping("/grants")
|
||||
public TableDataInfo grants(CustomerCreditGrant query)
|
||||
{
|
||||
startPage();
|
||||
List<CustomerCreditGrant> list = creditQuotaService.listGrants(query);
|
||||
return getDataTable(list);
|
||||
}
|
||||
}
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
package com.bms.web.controller.system;
|
||||
|
||||
import java.util.List;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.utils.poi.ExcelUtil;
|
||||
import com.bms.system.domain.SysConfig;
|
||||
import com.bms.system.service.ISysConfigService;
|
||||
|
||||
/**
|
||||
* 参数配置 信息操作处理
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/system/config")
|
||||
public class SysConfigController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISysConfigService configService;
|
||||
|
||||
/**
|
||||
* 获取参数配置列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:config:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SysConfig config)
|
||||
{
|
||||
startPage();
|
||||
List<SysConfig> list = configService.selectConfigList(config);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@Log(title = "参数管理", businessType = BusinessType.EXPORT)
|
||||
@PreAuthorize("@ss.hasPermi('system:config:export')")
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, SysConfig config)
|
||||
{
|
||||
List<SysConfig> list = configService.selectConfigList(config);
|
||||
ExcelUtil<SysConfig> util = new ExcelUtil<SysConfig>(SysConfig.class);
|
||||
util.exportExcel(response, list, "参数数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据参数编号获取详细信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:config:query')")
|
||||
@GetMapping(value = "/{configId}")
|
||||
public AjaxResult getInfo(@PathVariable Long configId)
|
||||
{
|
||||
return success(configService.selectConfigById(configId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据参数键名查询参数值
|
||||
*/
|
||||
@GetMapping(value = "/configKey/{configKey}")
|
||||
public AjaxResult getConfigKey(@PathVariable String configKey)
|
||||
{
|
||||
return success(configService.selectConfigByKey(configKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增参数配置
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:config:add')")
|
||||
@Log(title = "参数管理", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@Validated @RequestBody SysConfig config)
|
||||
{
|
||||
if (!configService.checkConfigKeyUnique(config))
|
||||
{
|
||||
return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在");
|
||||
}
|
||||
config.setCreateBy(getUsername());
|
||||
return toAjax(configService.insertConfig(config));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改参数配置
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:config:edit')")
|
||||
@Log(title = "参数管理", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@Validated @RequestBody SysConfig config)
|
||||
{
|
||||
if (!configService.checkConfigKeyUnique(config))
|
||||
{
|
||||
return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在");
|
||||
}
|
||||
config.setUpdateBy(getUsername());
|
||||
return toAjax(configService.updateConfig(config));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除参数配置
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:config:remove')")
|
||||
@Log(title = "参数管理", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{configIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] configIds)
|
||||
{
|
||||
configService.deleteConfigByIds(configIds);
|
||||
return success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新参数缓存
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:config:remove')")
|
||||
@Log(title = "参数管理", businessType = BusinessType.CLEAN)
|
||||
@DeleteMapping("/refreshCache")
|
||||
public AjaxResult refreshCache()
|
||||
{
|
||||
configService.resetConfigCache();
|
||||
return success();
|
||||
}
|
||||
}
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
package com.bms.web.controller.system;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.constant.UserConstants;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.domain.entity.SysDept;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.system.service.ISysDeptService;
|
||||
|
||||
/**
|
||||
* 部门信息
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/system/dept")
|
||||
public class SysDeptController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISysDeptService deptService;
|
||||
|
||||
/**
|
||||
* 获取部门列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:dept:list')")
|
||||
@GetMapping("/list")
|
||||
public AjaxResult list(SysDept dept)
|
||||
{
|
||||
List<SysDept> depts = deptService.selectDeptList(dept);
|
||||
return success(depts);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询部门列表(排除节点)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:dept:list')")
|
||||
@GetMapping("/list/exclude/{deptId}")
|
||||
public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId)
|
||||
{
|
||||
List<SysDept> depts = deptService.selectDeptList(new SysDept());
|
||||
depts.removeIf(d -> d.getDeptId().intValue() == deptId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + ""));
|
||||
return success(depts);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据部门编号获取详细信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:dept:query')")
|
||||
@GetMapping(value = "/{deptId}")
|
||||
public AjaxResult getInfo(@PathVariable Long deptId)
|
||||
{
|
||||
deptService.checkDeptDataScope(deptId);
|
||||
return success(deptService.selectDeptById(deptId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增部门
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:dept:add')")
|
||||
@Log(title = "部门管理", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@Validated @RequestBody SysDept dept)
|
||||
{
|
||||
if (!deptService.checkDeptNameUnique(dept))
|
||||
{
|
||||
return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在");
|
||||
}
|
||||
dept.setCreateBy(getUsername());
|
||||
return toAjax(deptService.insertDept(dept));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改部门
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:dept:edit')")
|
||||
@Log(title = "部门管理", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@Validated @RequestBody SysDept dept)
|
||||
{
|
||||
Long deptId = dept.getDeptId();
|
||||
deptService.checkDeptDataScope(deptId);
|
||||
if (!deptService.checkDeptNameUnique(dept))
|
||||
{
|
||||
return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
|
||||
}
|
||||
else if (dept.getParentId().equals(deptId))
|
||||
{
|
||||
return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己");
|
||||
}
|
||||
else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0)
|
||||
{
|
||||
return error("该部门包含未停用的子部门!");
|
||||
}
|
||||
dept.setUpdateBy(getUsername());
|
||||
return toAjax(deptService.updateDept(dept));
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存部门排序
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:dept:edit')")
|
||||
@Log(title = "保存部门排序", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/updateSort")
|
||||
public AjaxResult updateSort(@RequestBody Map<String, String> params)
|
||||
{
|
||||
String[] deptIds = params.get("deptIds").split(",");
|
||||
String[] orderNums = params.get("orderNums").split(",");
|
||||
deptService.updateDeptSort(deptIds, orderNums);
|
||||
return success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除部门
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:dept:remove')")
|
||||
@Log(title = "部门管理", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{deptId}")
|
||||
public AjaxResult remove(@PathVariable Long deptId)
|
||||
{
|
||||
if (deptService.hasChildByDeptId(deptId))
|
||||
{
|
||||
return warn("存在下级部门,不允许删除");
|
||||
}
|
||||
if (deptService.checkDeptExistUser(deptId))
|
||||
{
|
||||
return warn("部门存在用户,不允许删除");
|
||||
}
|
||||
deptService.checkDeptDataScope(deptId);
|
||||
return toAjax(deptService.deleteDeptById(deptId));
|
||||
}
|
||||
}
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
package com.bms.web.controller.system;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.domain.entity.SysDictData;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.common.utils.poi.ExcelUtil;
|
||||
import com.bms.system.service.ISysDictDataService;
|
||||
import com.bms.system.service.ISysDictTypeService;
|
||||
|
||||
/**
|
||||
* 数据字典信息
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/system/dict/data")
|
||||
public class SysDictDataController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISysDictDataService dictDataService;
|
||||
|
||||
@Autowired
|
||||
private ISysDictTypeService dictTypeService;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('system:dict:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SysDictData dictData)
|
||||
{
|
||||
startPage();
|
||||
List<SysDictData> list = dictDataService.selectDictDataList(dictData);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@Log(title = "字典数据", businessType = BusinessType.EXPORT)
|
||||
@PreAuthorize("@ss.hasPermi('system:dict:export')")
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, SysDictData dictData)
|
||||
{
|
||||
List<SysDictData> list = dictDataService.selectDictDataList(dictData);
|
||||
ExcelUtil<SysDictData> util = new ExcelUtil<SysDictData>(SysDictData.class);
|
||||
util.exportExcel(response, list, "字典数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 全量查询正常状态字典数据(按 dictType 分组)
|
||||
*/
|
||||
@GetMapping(value = "/all")
|
||||
public AjaxResult all()
|
||||
{
|
||||
Map<String, List<SysDictData>> data = dictTypeService.selectDictDataAllMap();
|
||||
return success(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询字典数据详细
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:dict:query')")
|
||||
@GetMapping(value = "/{dictCode}")
|
||||
public AjaxResult getInfo(@PathVariable Long dictCode)
|
||||
{
|
||||
return success(dictDataService.selectDictDataById(dictCode));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型查询字典数据信息
|
||||
*/
|
||||
@GetMapping(value = "/type/{dictType}")
|
||||
public AjaxResult dictType(@PathVariable String dictType)
|
||||
{
|
||||
List<SysDictData> data = dictTypeService.selectDictDataByType(dictType);
|
||||
if (StringUtils.isNull(data))
|
||||
{
|
||||
data = new ArrayList<SysDictData>();
|
||||
}
|
||||
return success(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增字典类型
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:dict:add')")
|
||||
@Log(title = "字典数据", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@Validated @RequestBody SysDictData dict)
|
||||
{
|
||||
dict.setCreateBy(getUsername());
|
||||
return toAjax(dictDataService.insertDictData(dict));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改保存字典类型
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:dict:edit')")
|
||||
@Log(title = "字典数据", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@Validated @RequestBody SysDictData dict)
|
||||
{
|
||||
dict.setUpdateBy(getUsername());
|
||||
return toAjax(dictDataService.updateDictData(dict));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除字典类型
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:dict:remove')")
|
||||
@Log(title = "字典类型", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{dictCodes}")
|
||||
public AjaxResult remove(@PathVariable Long[] dictCodes)
|
||||
{
|
||||
dictDataService.deleteDictDataByIds(dictCodes);
|
||||
return success();
|
||||
}
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
package com.bms.web.controller.system;
|
||||
|
||||
import java.util.List;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.domain.entity.SysDictType;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.utils.poi.ExcelUtil;
|
||||
import com.bms.system.service.ISysDictTypeService;
|
||||
|
||||
/**
|
||||
* 数据字典信息
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/system/dict/type")
|
||||
public class SysDictTypeController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISysDictTypeService dictTypeService;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('system:dict:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SysDictType dictType)
|
||||
{
|
||||
startPage();
|
||||
List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@Log(title = "字典类型", businessType = BusinessType.EXPORT)
|
||||
@PreAuthorize("@ss.hasPermi('system:dict:export')")
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, SysDictType dictType)
|
||||
{
|
||||
List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
|
||||
ExcelUtil<SysDictType> util = new ExcelUtil<SysDictType>(SysDictType.class);
|
||||
util.exportExcel(response, list, "字典类型");
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询字典类型详细
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:dict:query')")
|
||||
@GetMapping(value = "/{dictId}")
|
||||
public AjaxResult getInfo(@PathVariable Long dictId)
|
||||
{
|
||||
return success(dictTypeService.selectDictTypeById(dictId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增字典类型
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:dict:add')")
|
||||
@Log(title = "字典类型", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@Validated @RequestBody SysDictType dict)
|
||||
{
|
||||
if (!dictTypeService.checkDictTypeUnique(dict))
|
||||
{
|
||||
return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在");
|
||||
}
|
||||
dict.setCreateBy(getUsername());
|
||||
return toAjax(dictTypeService.insertDictType(dict));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改字典类型
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:dict:edit')")
|
||||
@Log(title = "字典类型", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@Validated @RequestBody SysDictType dict)
|
||||
{
|
||||
if (!dictTypeService.checkDictTypeUnique(dict))
|
||||
{
|
||||
return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在");
|
||||
}
|
||||
dict.setUpdateBy(getUsername());
|
||||
return toAjax(dictTypeService.updateDictType(dict));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除字典类型
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:dict:remove')")
|
||||
@Log(title = "字典类型", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{dictIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] dictIds)
|
||||
{
|
||||
dictTypeService.deleteDictTypeByIds(dictIds);
|
||||
return success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新字典缓存
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:dict:remove')")
|
||||
@Log(title = "字典类型", businessType = BusinessType.CLEAN)
|
||||
@DeleteMapping("/refreshCache")
|
||||
public AjaxResult refreshCache()
|
||||
{
|
||||
dictTypeService.resetDictCache();
|
||||
return success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字典选择框列表
|
||||
*/
|
||||
@GetMapping("/optionselect")
|
||||
public AjaxResult optionselect()
|
||||
{
|
||||
List<SysDictType> dictTypes = dictTypeService.selectDictTypeAll();
|
||||
return success(dictTypes);
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
package com.bms.web.controller.system;
|
||||
|
||||
import java.util.Map;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.config.BmsConfig;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.domain.entity.SysUser;
|
||||
import com.bms.common.utils.SecurityUtils;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.system.service.ISysUserService;
|
||||
|
||||
/**
|
||||
* 首页
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
public class SysIndexController
|
||||
{
|
||||
/** 系统基础配置 */
|
||||
@Autowired
|
||||
private BmsConfig bmsConfig;
|
||||
|
||||
@Autowired
|
||||
private ISysUserService userService;
|
||||
|
||||
/**
|
||||
* 访问首页,提示语
|
||||
*/
|
||||
@RequestMapping("/")
|
||||
public String index()
|
||||
{
|
||||
return StringUtils.format("欢迎使用{}后台管理框架,当前版本:v{},请通过前端地址访问。", bmsConfig.getName(), bmsConfig.getVersion());
|
||||
}
|
||||
|
||||
/**
|
||||
* 解锁屏幕
|
||||
*/
|
||||
@PostMapping("/unlockscreen")
|
||||
public AjaxResult unlockScreen(@RequestBody Map<String, String> body)
|
||||
{
|
||||
String password = body.get("password");
|
||||
if (StringUtils.isEmpty(password))
|
||||
{
|
||||
return AjaxResult.error("密码不能为空");
|
||||
}
|
||||
String username = SecurityUtils.getUsername();
|
||||
SysUser user = userService.selectUserByUserName(username);
|
||||
if (user == null)
|
||||
{
|
||||
return AjaxResult.error("服务器超时,请重新登录");
|
||||
}
|
||||
if (!SecurityUtils.matchesPassword(password, user.getPassword()))
|
||||
{
|
||||
return AjaxResult.error("密码错误,请重新输入");
|
||||
}
|
||||
|
||||
return AjaxResult.success("解锁成功");
|
||||
}
|
||||
}
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
package com.bms.web.controller.system;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.constant.Constants;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.domain.entity.SysMenu;
|
||||
import com.bms.common.core.domain.entity.SysUser;
|
||||
import com.bms.common.core.domain.model.LoginBody;
|
||||
import com.bms.common.core.domain.model.LoginUser;
|
||||
import com.bms.common.core.text.Convert;
|
||||
import com.bms.common.utils.DateUtils;
|
||||
import com.bms.common.utils.SecurityUtils;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.framework.web.service.SysLoginService;
|
||||
import com.bms.framework.web.service.SysPermissionService;
|
||||
import com.bms.framework.web.service.TokenService;
|
||||
import com.bms.system.service.ISysConfigService;
|
||||
import com.bms.system.service.ISysMenuService;
|
||||
|
||||
/**
|
||||
* 登录验证
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
public class SysLoginController
|
||||
{
|
||||
@Autowired
|
||||
private SysLoginService loginService;
|
||||
|
||||
@Autowired
|
||||
private ISysMenuService menuService;
|
||||
|
||||
@Autowired
|
||||
private SysPermissionService permissionService;
|
||||
|
||||
@Autowired
|
||||
private TokenService tokenService;
|
||||
|
||||
@Autowired
|
||||
private ISysConfigService configService;
|
||||
|
||||
/**
|
||||
* 登录方法
|
||||
*
|
||||
* @param loginBody 登录信息
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/login")
|
||||
public AjaxResult login(@RequestBody LoginBody loginBody)
|
||||
{
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
// 生成令牌
|
||||
String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
|
||||
loginBody.getUuid());
|
||||
ajax.put(Constants.TOKEN, token);
|
||||
return ajax;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
*
|
||||
* @return 用户信息
|
||||
*/
|
||||
@GetMapping("getInfo")
|
||||
public AjaxResult getInfo()
|
||||
{
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
SysUser user = loginUser.getUser();
|
||||
// 角色集合
|
||||
Set<String> roles = permissionService.getRolePermission(user);
|
||||
// 权限集合
|
||||
Set<String> permissions = permissionService.getMenuPermission(user);
|
||||
if (!loginUser.getPermissions().equals(permissions))
|
||||
{
|
||||
loginUser.setPermissions(permissions);
|
||||
tokenService.refreshToken(loginUser);
|
||||
}
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
ajax.put("user", user);
|
||||
ajax.put("roles", roles);
|
||||
ajax.put("permissions", permissions);
|
||||
ajax.put("pwdChrtype", getSysAccountChrtype());
|
||||
ajax.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate()));
|
||||
ajax.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate()));
|
||||
return ajax;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取路由信息
|
||||
*
|
||||
* @return 路由信息
|
||||
*/
|
||||
@GetMapping("getRouters")
|
||||
public AjaxResult getRouters()
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
|
||||
return AjaxResult.success(menuService.buildMenus(menus));
|
||||
}
|
||||
|
||||
// 获取用户密码自定义配置规则
|
||||
public String getSysAccountChrtype()
|
||||
{
|
||||
return Convert.toStr(configService.selectConfigByKey("sys.account.chrtype"), "0");
|
||||
}
|
||||
|
||||
// 检查初始密码是否提醒修改
|
||||
public boolean initPasswordIsModify(Date pwdUpdateDate)
|
||||
{
|
||||
Integer initPasswordModify = Convert.toInt(configService.selectConfigByKey("sys.account.initPasswordModify"));
|
||||
return initPasswordModify != null && initPasswordModify == 1 && pwdUpdateDate == null;
|
||||
}
|
||||
|
||||
// 检查密码是否过期
|
||||
public boolean passwordIsExpiration(Date pwdUpdateDate)
|
||||
{
|
||||
Integer passwordValidateDays = Convert.toInt(configService.selectConfigByKey("sys.account.passwordValidateDays"));
|
||||
if (passwordValidateDays != null && passwordValidateDays > 0)
|
||||
{
|
||||
if (StringUtils.isNull(pwdUpdateDate))
|
||||
{
|
||||
// 如果从未修改过初始密码,直接提醒过期
|
||||
return true;
|
||||
}
|
||||
Date nowDate = DateUtils.getNowDate();
|
||||
return DateUtils.differentDaysByMillisecond(nowDate, pwdUpdateDate) > passwordValidateDays;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
package com.bms.web.controller.system;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.constant.UserConstants;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.domain.entity.SysMenu;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.system.service.ISysMenuService;
|
||||
|
||||
/**
|
||||
* 菜单信息
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/system/menu")
|
||||
public class SysMenuController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISysMenuService menuService;
|
||||
|
||||
/**
|
||||
* 获取菜单列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:menu:list')")
|
||||
@GetMapping("/list")
|
||||
public AjaxResult list(SysMenu menu)
|
||||
{
|
||||
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
|
||||
return success(menus);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据菜单编号获取详细信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:menu:query')")
|
||||
@GetMapping(value = "/{menuId}")
|
||||
public AjaxResult getInfo(@PathVariable Long menuId)
|
||||
{
|
||||
return success(menuService.selectMenuById(menuId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取菜单下拉树列表
|
||||
*/
|
||||
@GetMapping("/treeselect")
|
||||
public AjaxResult treeselect(SysMenu menu)
|
||||
{
|
||||
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
|
||||
return success(menuService.buildMenuTreeSelect(menus));
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载对应角色菜单列表树
|
||||
*/
|
||||
@GetMapping(value = "/roleMenuTreeselect/{roleId}")
|
||||
public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId)
|
||||
{
|
||||
List<SysMenu> menus = menuService.selectMenuList(getUserId());
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId));
|
||||
ajax.put("menus", menuService.buildMenuTreeSelect(menus));
|
||||
return ajax;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增菜单
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:menu:add')")
|
||||
@Log(title = "菜单管理", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@Validated @RequestBody SysMenu menu)
|
||||
{
|
||||
if (!menuService.checkMenuNameUnique(menu))
|
||||
{
|
||||
return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
|
||||
}
|
||||
else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
|
||||
{
|
||||
return error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
|
||||
}
|
||||
else if (!menuService.checkRouteConfigUnique(menu))
|
||||
{
|
||||
return error("新增菜单'" + menu.getMenuName() + "'失败,路由名称或地址已存在");
|
||||
}
|
||||
menu.setCreateBy(getUsername());
|
||||
return toAjax(menuService.insertMenu(menu));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改菜单
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:menu:edit')")
|
||||
@Log(title = "菜单管理", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@Validated @RequestBody SysMenu menu)
|
||||
{
|
||||
if (!menuService.checkMenuNameUnique(menu))
|
||||
{
|
||||
return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
|
||||
}
|
||||
else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
|
||||
{
|
||||
return error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
|
||||
}
|
||||
else if (menu.getMenuId().equals(menu.getParentId()))
|
||||
{
|
||||
return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
|
||||
}
|
||||
else if (!menuService.checkRouteConfigUnique(menu))
|
||||
{
|
||||
return error("修改菜单'" + menu.getMenuName() + "'失败,路由名称或地址已存在");
|
||||
}
|
||||
menu.setUpdateBy(getUsername());
|
||||
return toAjax(menuService.updateMenu(menu));
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存菜单排序
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:menu:edit')")
|
||||
@Log(title = "保存菜单排序", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/updateSort")
|
||||
public AjaxResult updateSort(@RequestBody Map<String, String> params)
|
||||
{
|
||||
String[] menuIds = params.get("menuIds").split(",");
|
||||
String[] orderNums = params.get("orderNums").split(",");
|
||||
menuService.updateMenuSort(menuIds, orderNums);
|
||||
return success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除菜单
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:menu:remove')")
|
||||
@Log(title = "菜单管理", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{menuId}")
|
||||
public AjaxResult remove(@PathVariable("menuId") Long menuId)
|
||||
{
|
||||
if (menuService.hasChildByMenuId(menuId))
|
||||
{
|
||||
return warn("存在子菜单,不允许删除");
|
||||
}
|
||||
if (menuService.checkMenuExistRole(menuId))
|
||||
{
|
||||
return warn("菜单已分配,不允许删除");
|
||||
}
|
||||
return toAjax(menuService.deleteMenuById(menuId));
|
||||
}
|
||||
}
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
package com.bms.web.controller.system;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.core.text.Convert;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.system.domain.SysNotice;
|
||||
import com.bms.system.service.ISysNoticeReadService;
|
||||
import com.bms.system.service.ISysNoticeService;
|
||||
|
||||
/**
|
||||
* 公告 信息操作处理
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/system/notice")
|
||||
public class SysNoticeController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISysNoticeService noticeService;
|
||||
|
||||
@Autowired
|
||||
private ISysNoticeReadService noticeReadService;
|
||||
|
||||
/**
|
||||
* 获取通知公告列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:notice:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SysNotice notice)
|
||||
{
|
||||
startPage();
|
||||
List<SysNotice> list = noticeService.selectNoticeList(notice);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据通知公告编号获取详细信息
|
||||
*/
|
||||
@GetMapping(value = "/{noticeId}")
|
||||
public AjaxResult getInfo(@PathVariable Long noticeId)
|
||||
{
|
||||
return success(noticeService.selectNoticeById(noticeId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增通知公告
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:notice:add')")
|
||||
@Log(title = "通知公告", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@Validated @RequestBody SysNotice notice)
|
||||
{
|
||||
notice.setCreateBy(getUsername());
|
||||
return toAjax(noticeService.insertNotice(notice));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改通知公告
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:notice:edit')")
|
||||
@Log(title = "通知公告", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@Validated @RequestBody SysNotice notice)
|
||||
{
|
||||
notice.setUpdateBy(getUsername());
|
||||
return toAjax(noticeService.updateNotice(notice));
|
||||
}
|
||||
|
||||
/**
|
||||
* 首页顶部公告列表(返回全部正常公告,带当前用户已读标记,最多5条)
|
||||
*/
|
||||
@GetMapping("/listTop")
|
||||
@ResponseBody
|
||||
public AjaxResult listTop()
|
||||
{
|
||||
Long userId = getUserId();
|
||||
List<SysNotice> list = noticeReadService.selectNoticeListWithReadStatus(userId, 5);
|
||||
long unreadCount = list.stream().filter(n -> !n.getIsRead()).count();
|
||||
AjaxResult result = AjaxResult.success(list);
|
||||
result.put("unreadCount", unreadCount);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记公告已读
|
||||
*/
|
||||
@PostMapping("/markRead")
|
||||
@ResponseBody
|
||||
public AjaxResult markRead(Long noticeId)
|
||||
{
|
||||
Long userId = getUserId();
|
||||
noticeReadService.markRead(noticeId, userId);
|
||||
return success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量标记已读
|
||||
*/
|
||||
@PostMapping("/markReadAll")
|
||||
@ResponseBody
|
||||
public AjaxResult markReadAll(String ids)
|
||||
{
|
||||
Long userId = getUserId();
|
||||
Long[] noticeIds = Convert.toLongArray(ids);
|
||||
noticeReadService.markReadBatch(userId, noticeIds);
|
||||
return success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 已读用户列表数据
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:notice:list')")
|
||||
@GetMapping("/readUsers/list")
|
||||
@ResponseBody
|
||||
public TableDataInfo readUsersList(Long noticeId, String searchValue)
|
||||
{
|
||||
startPage();
|
||||
List<?> list = noticeReadService.selectReadUsersByNoticeId(noticeId, searchValue);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除通知公告
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:notice:remove')")
|
||||
@Log(title = "通知公告", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{noticeIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] noticeIds)
|
||||
{
|
||||
noticeReadService.deleteByNoticeIds(noticeIds);
|
||||
return toAjax(noticeService.deleteNoticeByIds(noticeIds));
|
||||
}
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
package com.bms.web.controller.system;
|
||||
|
||||
import java.util.List;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.utils.poi.ExcelUtil;
|
||||
import com.bms.system.domain.SysPost;
|
||||
import com.bms.system.service.ISysPostService;
|
||||
|
||||
/**
|
||||
* 岗位信息操作处理
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/system/post")
|
||||
public class SysPostController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISysPostService postService;
|
||||
|
||||
/**
|
||||
* 获取岗位列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:post:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SysPost post)
|
||||
{
|
||||
startPage();
|
||||
List<SysPost> list = postService.selectPostList(post);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@Log(title = "岗位管理", businessType = BusinessType.EXPORT)
|
||||
@PreAuthorize("@ss.hasPermi('system:post:export')")
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, SysPost post)
|
||||
{
|
||||
List<SysPost> list = postService.selectPostList(post);
|
||||
ExcelUtil<SysPost> util = new ExcelUtil<SysPost>(SysPost.class);
|
||||
util.exportExcel(response, list, "岗位数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据岗位编号获取详细信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:post:query')")
|
||||
@GetMapping(value = "/{postId}")
|
||||
public AjaxResult getInfo(@PathVariable Long postId)
|
||||
{
|
||||
return success(postService.selectPostById(postId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增岗位
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:post:add')")
|
||||
@Log(title = "岗位管理", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@Validated @RequestBody SysPost post)
|
||||
{
|
||||
if (!postService.checkPostNameUnique(post))
|
||||
{
|
||||
return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在");
|
||||
}
|
||||
else if (!postService.checkPostCodeUnique(post))
|
||||
{
|
||||
return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在");
|
||||
}
|
||||
post.setCreateBy(getUsername());
|
||||
return toAjax(postService.insertPost(post));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改岗位
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:post:edit')")
|
||||
@Log(title = "岗位管理", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@Validated @RequestBody SysPost post)
|
||||
{
|
||||
if (!postService.checkPostNameUnique(post))
|
||||
{
|
||||
return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在");
|
||||
}
|
||||
else if (!postService.checkPostCodeUnique(post))
|
||||
{
|
||||
return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在");
|
||||
}
|
||||
post.setUpdateBy(getUsername());
|
||||
return toAjax(postService.updatePost(post));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除岗位
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:post:remove')")
|
||||
@Log(title = "岗位管理", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{postIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] postIds)
|
||||
{
|
||||
return toAjax(postService.deletePostByIds(postIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取岗位选择框列表
|
||||
*/
|
||||
@GetMapping("/optionselect")
|
||||
public AjaxResult optionselect()
|
||||
{
|
||||
List<SysPost> posts = postService.selectPostAll();
|
||||
return success(posts);
|
||||
}
|
||||
}
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
package com.bms.web.controller.system;
|
||||
|
||||
import java.util.Map;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.config.BmsConfig;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.domain.entity.SysUser;
|
||||
import com.bms.common.core.domain.model.LoginUser;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.utils.DateUtils;
|
||||
import com.bms.common.utils.SecurityUtils;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.common.utils.file.FileUploadUtils;
|
||||
import com.bms.common.utils.file.FileUtils;
|
||||
import com.bms.common.utils.file.MimeTypeUtils;
|
||||
import com.bms.framework.web.service.TokenService;
|
||||
import com.bms.system.service.ISysUserService;
|
||||
|
||||
/**
|
||||
* 个人信息 业务处理
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/system/user/profile")
|
||||
public class SysProfileController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISysUserService userService;
|
||||
|
||||
@Autowired
|
||||
private TokenService tokenService;
|
||||
|
||||
/**
|
||||
* 个人信息
|
||||
*/
|
||||
@GetMapping
|
||||
public AjaxResult profile()
|
||||
{
|
||||
LoginUser loginUser = getLoginUser();
|
||||
SysUser user = loginUser.getUser();
|
||||
AjaxResult ajax = AjaxResult.success(user);
|
||||
ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername()));
|
||||
ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername()));
|
||||
return ajax;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户
|
||||
*/
|
||||
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult updateProfile(@RequestBody SysUser user)
|
||||
{
|
||||
LoginUser loginUser = getLoginUser();
|
||||
SysUser currentUser = loginUser.getUser();
|
||||
currentUser.setNickName(user.getNickName());
|
||||
currentUser.setEmail(user.getEmail());
|
||||
currentUser.setPhonenumber(user.getPhonenumber());
|
||||
currentUser.setSex(user.getSex());
|
||||
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser))
|
||||
{
|
||||
return error("修改用户'" + loginUser.getUsername() + "'失败,手机号码已存在");
|
||||
}
|
||||
if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser))
|
||||
{
|
||||
return error("修改用户'" + loginUser.getUsername() + "'失败,邮箱账号已存在");
|
||||
}
|
||||
if (userService.updateUserProfile(currentUser) > 0)
|
||||
{
|
||||
// 更新缓存用户信息
|
||||
tokenService.setLoginUser(loginUser);
|
||||
return success();
|
||||
}
|
||||
return error("修改个人信息异常,请联系管理员");
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置密码
|
||||
*/
|
||||
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/updatePwd")
|
||||
public AjaxResult updatePwd(@RequestBody Map<String, String> params)
|
||||
{
|
||||
String oldPassword = params.get("oldPassword");
|
||||
String newPassword = params.get("newPassword");
|
||||
LoginUser loginUser = getLoginUser();
|
||||
Long userId = loginUser.getUserId();
|
||||
SysUser user = userService.selectUserById(userId);
|
||||
String password = user.getPassword();
|
||||
if (!SecurityUtils.matchesPassword(oldPassword, password))
|
||||
{
|
||||
return error("修改密码失败,旧密码错误");
|
||||
}
|
||||
if (SecurityUtils.matchesPassword(newPassword, password))
|
||||
{
|
||||
return error("新密码不能与旧密码相同");
|
||||
}
|
||||
newPassword = SecurityUtils.encryptPassword(newPassword);
|
||||
if (userService.resetUserPwd(userId, newPassword) > 0)
|
||||
{
|
||||
// 更新缓存用户密码&密码最后更新时间
|
||||
loginUser.getUser().setPwdUpdateDate(DateUtils.getNowDate());
|
||||
loginUser.getUser().setPassword(newPassword);
|
||||
tokenService.setLoginUser(loginUser);
|
||||
return success();
|
||||
}
|
||||
return error("修改密码异常,请联系管理员");
|
||||
}
|
||||
|
||||
/**
|
||||
* 头像上传
|
||||
*/
|
||||
@Log(title = "用户头像", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/avatar")
|
||||
public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception
|
||||
{
|
||||
if (!file.isEmpty())
|
||||
{
|
||||
LoginUser loginUser = getLoginUser();
|
||||
String avatar = FileUploadUtils.upload(BmsConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION, true);
|
||||
if (userService.updateUserAvatar(loginUser.getUserId(), avatar))
|
||||
{
|
||||
String oldAvatar = loginUser.getUser().getAvatar();
|
||||
if (StringUtils.isNotEmpty(oldAvatar))
|
||||
{
|
||||
FileUtils.deleteFile(BmsConfig.getProfile() + FileUtils.stripPrefix(oldAvatar));
|
||||
}
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
ajax.put("imgUrl", avatar);
|
||||
// 更新缓存用户头像
|
||||
loginUser.getUser().setAvatar(avatar);
|
||||
tokenService.setLoginUser(loginUser);
|
||||
return ajax;
|
||||
}
|
||||
}
|
||||
return error("上传图片异常,请联系管理员");
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.bms.web.controller.system;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.domain.model.RegisterBody;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.framework.web.service.SysRegisterService;
|
||||
import com.bms.system.service.ISysConfigService;
|
||||
|
||||
/**
|
||||
* 注册验证
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
public class SysRegisterController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private SysRegisterService registerService;
|
||||
|
||||
@Autowired
|
||||
private ISysConfigService configService;
|
||||
|
||||
@PostMapping("/register")
|
||||
public AjaxResult register(@RequestBody RegisterBody user)
|
||||
{
|
||||
if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser"))))
|
||||
{
|
||||
return error("当前系统没有开启注册功能!");
|
||||
}
|
||||
String msg = registerService.register(user);
|
||||
return StringUtils.isEmpty(msg) ? success() : error(msg);
|
||||
}
|
||||
}
|
||||
+254
@@ -0,0 +1,254 @@
|
||||
package com.bms.web.controller.system;
|
||||
|
||||
import java.util.List;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.domain.entity.SysDept;
|
||||
import com.bms.common.core.domain.entity.SysRole;
|
||||
import com.bms.common.core.domain.entity.SysUser;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.utils.poi.ExcelUtil;
|
||||
import com.bms.framework.web.service.SysPermissionService;
|
||||
import com.bms.framework.web.service.TokenService;
|
||||
import com.bms.system.domain.SysUserRole;
|
||||
import com.bms.system.service.ISysDeptService;
|
||||
import com.bms.system.service.ISysRoleService;
|
||||
import com.bms.system.service.ISysUserService;
|
||||
|
||||
/**
|
||||
* 角色信息
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/system/role")
|
||||
public class SysRoleController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISysRoleService roleService;
|
||||
|
||||
@Autowired
|
||||
private TokenService tokenService;
|
||||
|
||||
@Autowired
|
||||
private SysPermissionService permissionService;
|
||||
|
||||
@Autowired
|
||||
private ISysUserService userService;
|
||||
|
||||
@Autowired
|
||||
private ISysDeptService deptService;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('system:role:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SysRole role)
|
||||
{
|
||||
startPage();
|
||||
List<SysRole> list = roleService.selectRoleList(role);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@Log(title = "角色管理", businessType = BusinessType.EXPORT)
|
||||
@PreAuthorize("@ss.hasPermi('system:role:export')")
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, SysRole role)
|
||||
{
|
||||
List<SysRole> list = roleService.selectRoleList(role);
|
||||
ExcelUtil<SysRole> util = new ExcelUtil<SysRole>(SysRole.class);
|
||||
util.exportExcel(response, list, "角色数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据角色编号获取详细信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:role:query')")
|
||||
@GetMapping(value = "/{roleId}")
|
||||
public AjaxResult getInfo(@PathVariable Long roleId)
|
||||
{
|
||||
roleService.checkRoleDataScope(roleId);
|
||||
return success(roleService.selectRoleById(roleId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增角色
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:role:add')")
|
||||
@Log(title = "角色管理", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@Validated @RequestBody SysRole role)
|
||||
{
|
||||
if (!roleService.checkRoleNameUnique(role))
|
||||
{
|
||||
return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");
|
||||
}
|
||||
else if (!roleService.checkRoleKeyUnique(role))
|
||||
{
|
||||
return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
|
||||
}
|
||||
role.setCreateBy(getUsername());
|
||||
return toAjax(roleService.insertRole(role));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改保存角色
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:role:edit')")
|
||||
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@Validated @RequestBody SysRole role)
|
||||
{
|
||||
roleService.checkRoleAllowed(role);
|
||||
roleService.checkRoleDataScope(role.getRoleId());
|
||||
if (!roleService.checkRoleNameUnique(role))
|
||||
{
|
||||
return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
|
||||
}
|
||||
else if (!roleService.checkRoleKeyUnique(role))
|
||||
{
|
||||
return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
|
||||
}
|
||||
role.setUpdateBy(getUsername());
|
||||
|
||||
if (roleService.updateRole(role) > 0)
|
||||
{
|
||||
// 刷新所有持有该角色的在线用户权限
|
||||
tokenService.refreshPermissionByRoleId(role.getRoleId(), permissionService);
|
||||
return success();
|
||||
}
|
||||
return error("修改角色'" + role.getRoleName() + "'失败,请联系管理员");
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改保存数据权限
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:role:edit')")
|
||||
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/dataScope")
|
||||
public AjaxResult dataScope(@RequestBody SysRole role)
|
||||
{
|
||||
roleService.checkRoleAllowed(role);
|
||||
roleService.checkRoleDataScope(role.getRoleId());
|
||||
return toAjax(roleService.authDataScope(role));
|
||||
}
|
||||
|
||||
/**
|
||||
* 状态修改
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:role:edit')")
|
||||
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/changeStatus")
|
||||
public AjaxResult changeStatus(@RequestBody SysRole role)
|
||||
{
|
||||
roleService.checkRoleAllowed(role);
|
||||
roleService.checkRoleDataScope(role.getRoleId());
|
||||
role.setUpdateBy(getUsername());
|
||||
return toAjax(roleService.updateRoleStatus(role));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除角色
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:role:remove')")
|
||||
@Log(title = "角色管理", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{roleIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] roleIds)
|
||||
{
|
||||
return toAjax(roleService.deleteRoleByIds(roleIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色选择框列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:role:query')")
|
||||
@GetMapping("/optionselect")
|
||||
public AjaxResult optionselect()
|
||||
{
|
||||
return success(roleService.selectRoleAll());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询已分配用户角色列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:role:list')")
|
||||
@GetMapping("/authUser/allocatedList")
|
||||
public TableDataInfo allocatedList(SysUser user)
|
||||
{
|
||||
startPage();
|
||||
List<SysUser> list = userService.selectAllocatedList(user);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询未分配用户角色列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:role:list')")
|
||||
@GetMapping("/authUser/unallocatedList")
|
||||
public TableDataInfo unallocatedList(SysUser user)
|
||||
{
|
||||
startPage();
|
||||
List<SysUser> list = userService.selectUnallocatedList(user);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消授权用户
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:role:edit')")
|
||||
@Log(title = "角色管理", businessType = BusinessType.GRANT)
|
||||
@PutMapping("/authUser/cancel")
|
||||
public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole)
|
||||
{
|
||||
return toAjax(roleService.deleteAuthUser(userRole));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量取消授权用户
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:role:edit')")
|
||||
@Log(title = "角色管理", businessType = BusinessType.GRANT)
|
||||
@PutMapping("/authUser/cancelAll")
|
||||
public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds)
|
||||
{
|
||||
return toAjax(roleService.deleteAuthUsers(roleId, userIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量选择用户授权
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:role:edit')")
|
||||
@Log(title = "角色管理", businessType = BusinessType.GRANT)
|
||||
@PutMapping("/authUser/selectAll")
|
||||
public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds)
|
||||
{
|
||||
roleService.checkRoleDataScope(roleId);
|
||||
return toAjax(roleService.insertAuthUsers(roleId, userIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对应角色部门树列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:role:query')")
|
||||
@GetMapping(value = "/deptTree/{roleId}")
|
||||
public AjaxResult deptTree(@PathVariable("roleId") Long roleId)
|
||||
{
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId));
|
||||
ajax.put("depts", deptService.selectDeptTreeList(new SysDept()));
|
||||
return ajax;
|
||||
}
|
||||
}
|
||||
+279
@@ -0,0 +1,279 @@
|
||||
package com.bms.web.controller.system;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.domain.entity.SysDept;
|
||||
import com.bms.common.core.domain.entity.SysRole;
|
||||
import com.bms.common.core.domain.entity.SysUser;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.utils.SecurityUtils;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.common.utils.poi.ExcelUtil;
|
||||
import com.bms.system.service.ISysDeptService;
|
||||
import com.bms.system.service.ISysPostService;
|
||||
import com.bms.system.service.ISysRoleService;
|
||||
import com.bms.system.service.ISysUserService;
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/system/user")
|
||||
public class SysUserController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISysUserService userService;
|
||||
|
||||
@Autowired
|
||||
private ISysRoleService roleService;
|
||||
|
||||
@Autowired
|
||||
private ISysDeptService deptService;
|
||||
|
||||
@Autowired
|
||||
private ISysPostService postService;
|
||||
|
||||
/**
|
||||
* 获取用户列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:user:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SysUser user)
|
||||
{
|
||||
startPage();
|
||||
List<SysUser> list = userService.selectUserList(user);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户下拉选项(业务员/客服/采购员等选择用)。
|
||||
* 不加 @PreAuthorize:登录即可访问,只返回 id/账号/姓名/部门等展示字段,
|
||||
* 避免给业务角色额外开放 system:user:list(含手机号/邮箱等完整信息)。
|
||||
*/
|
||||
@GetMapping("/optionselect")
|
||||
public AjaxResult optionselect()
|
||||
{
|
||||
List<Map<String, Object>> options = userService.selectUserOptions().stream().map(u -> {
|
||||
Map<String, Object> m = new LinkedHashMap<>();
|
||||
m.put("userId", u.getUserId());
|
||||
m.put("userName", u.getUserName());
|
||||
m.put("nickName", u.getNickName());
|
||||
m.put("deptId", u.getDeptId());
|
||||
m.put("deptName", u.getDept() == null ? null : u.getDept().getDeptName());
|
||||
m.put("status", u.getStatus());
|
||||
return m;
|
||||
}).collect(Collectors.toList());
|
||||
return AjaxResult.success(options);
|
||||
}
|
||||
|
||||
@Log(title = "用户管理", businessType = BusinessType.EXPORT)
|
||||
@PreAuthorize("@ss.hasPermi('system:user:export')")
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, SysUser user)
|
||||
{
|
||||
List<SysUser> list = userService.selectUserList(user);
|
||||
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
|
||||
util.exportExcel(response, list, "用户数据");
|
||||
}
|
||||
|
||||
@Log(title = "用户管理", businessType = BusinessType.IMPORT)
|
||||
@PreAuthorize("@ss.hasPermi('system:user:import')")
|
||||
@PostMapping("/importData")
|
||||
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
|
||||
{
|
||||
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
|
||||
List<SysUser> userList = util.importExcel(file.getInputStream());
|
||||
String operName = getUsername();
|
||||
String message = userService.importUser(userList, updateSupport, operName);
|
||||
return success(message);
|
||||
}
|
||||
|
||||
@PostMapping("/importTemplate")
|
||||
public void importTemplate(HttpServletResponse response)
|
||||
{
|
||||
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
|
||||
util.importTemplateExcel(response, "用户数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户编号获取详细信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:user:query')")
|
||||
@GetMapping(value = { "/", "/{userId}" })
|
||||
public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId)
|
||||
{
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
if (StringUtils.isNotNull(userId))
|
||||
{
|
||||
userService.checkUserDataScope(userId);
|
||||
SysUser sysUser = userService.selectUserById(userId);
|
||||
ajax.put(AjaxResult.DATA_TAG, sysUser);
|
||||
ajax.put("postIds", postService.selectPostListByUserId(userId));
|
||||
ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList()));
|
||||
}
|
||||
List<SysRole> roles = roleService.selectRoleAll();
|
||||
ajax.put("roles", SecurityUtils.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
|
||||
ajax.put("posts", postService.selectPostAll());
|
||||
return ajax;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增用户
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:user:add')")
|
||||
@Log(title = "用户管理", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@Validated @RequestBody SysUser user)
|
||||
{
|
||||
deptService.checkDeptDataScope(user.getDeptId());
|
||||
roleService.checkRoleDataScope(user.getRoleIds());
|
||||
if (!userService.checkUserNameUnique(user))
|
||||
{
|
||||
return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
|
||||
}
|
||||
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
|
||||
{
|
||||
return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
|
||||
}
|
||||
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
|
||||
{
|
||||
return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
|
||||
}
|
||||
user.setCreateBy(getUsername());
|
||||
user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
|
||||
return toAjax(userService.insertUser(user));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:user:edit')")
|
||||
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@Validated @RequestBody SysUser user)
|
||||
{
|
||||
userService.checkUserAllowed(user);
|
||||
userService.checkUserDataScope(user.getUserId());
|
||||
deptService.checkDeptDataScope(user.getDeptId());
|
||||
roleService.checkRoleDataScope(user.getRoleIds());
|
||||
if (!userService.checkUserNameUnique(user))
|
||||
{
|
||||
return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
|
||||
}
|
||||
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
|
||||
{
|
||||
return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
|
||||
}
|
||||
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
|
||||
{
|
||||
return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
|
||||
}
|
||||
user.setUpdateBy(getUsername());
|
||||
return toAjax(userService.updateUser(user));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:user:remove')")
|
||||
@Log(title = "用户管理", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{userIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] userIds)
|
||||
{
|
||||
if (ArrayUtils.contains(userIds, getUserId()))
|
||||
{
|
||||
return error("当前用户不能删除");
|
||||
}
|
||||
return toAjax(userService.deleteUserByIds(userIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置密码
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:user:resetPwd')")
|
||||
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/resetPwd")
|
||||
public AjaxResult resetPwd(@RequestBody SysUser user)
|
||||
{
|
||||
userService.checkUserAllowed(user);
|
||||
userService.checkUserDataScope(user.getUserId());
|
||||
user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
|
||||
user.setUpdateBy(getUsername());
|
||||
return toAjax(userService.resetPwd(user));
|
||||
}
|
||||
|
||||
/**
|
||||
* 状态修改
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:user:edit')")
|
||||
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/changeStatus")
|
||||
public AjaxResult changeStatus(@RequestBody SysUser user)
|
||||
{
|
||||
userService.checkUserAllowed(user);
|
||||
userService.checkUserDataScope(user.getUserId());
|
||||
user.setUpdateBy(getUsername());
|
||||
return toAjax(userService.updateUserStatus(user));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户编号获取授权角色
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:user:query')")
|
||||
@GetMapping("/authRole/{userId}")
|
||||
public AjaxResult authRole(@PathVariable("userId") Long userId)
|
||||
{
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
SysUser user = userService.selectUserById(userId);
|
||||
List<SysRole> roles = roleService.selectRolesByUserId(userId);
|
||||
ajax.put("user", user);
|
||||
ajax.put("roles", SecurityUtils.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
|
||||
return ajax;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户授权角色
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:user:edit')")
|
||||
@Log(title = "用户管理", businessType = BusinessType.GRANT)
|
||||
@PutMapping("/authRole")
|
||||
public AjaxResult insertAuthRole(Long userId, Long[] roleIds)
|
||||
{
|
||||
userService.checkUserDataScope(userId);
|
||||
roleService.checkRoleDataScope(roleIds);
|
||||
userService.insertUserAuth(userId, roleIds);
|
||||
return success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取部门树列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:user:list')")
|
||||
@GetMapping("/deptTree")
|
||||
public AjaxResult deptTree(SysDept dept)
|
||||
{
|
||||
return success(deptService.selectDeptTreeList(dept));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
package com.bms.web.controller.tool;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.R;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
/**
|
||||
* swagger 用户测试方法
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@Tag(name = "用户信息管理")
|
||||
@RestController
|
||||
@RequestMapping("/test/user")
|
||||
public class TestController extends BaseController
|
||||
{
|
||||
private final static Map<Integer, UserEntity> users = new LinkedHashMap<Integer, UserEntity>();
|
||||
{
|
||||
users.put(1, new UserEntity(1, "admin", "admin123", "15888888888"));
|
||||
users.put(2, new UserEntity(2, "ry", "admin123", "15666666666"));
|
||||
}
|
||||
|
||||
@Operation(summary = "获取用户列表")
|
||||
@GetMapping("/list")
|
||||
public R<List<UserEntity>> userList()
|
||||
{
|
||||
List<UserEntity> userList = new ArrayList<UserEntity>(users.values());
|
||||
return R.ok(userList);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取用户详细")
|
||||
@GetMapping("/{userId}")
|
||||
public R<UserEntity> getUser(@PathVariable(name = "userId")
|
||||
Integer userId)
|
||||
{
|
||||
if (!users.isEmpty() && users.containsKey(userId))
|
||||
{
|
||||
return R.ok(users.get(userId));
|
||||
}
|
||||
else
|
||||
{
|
||||
return R.fail("用户不存在");
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "新增用户")
|
||||
@PostMapping("/save")
|
||||
public R<String> save(UserEntity user)
|
||||
{
|
||||
if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
|
||||
{
|
||||
return R.fail("用户ID不能为空");
|
||||
}
|
||||
users.put(user.getUserId(), user);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@Operation(summary = "更新用户")
|
||||
@PutMapping("/update")
|
||||
public R<String> update(@RequestBody
|
||||
UserEntity user)
|
||||
{
|
||||
if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
|
||||
{
|
||||
return R.fail("用户ID不能为空");
|
||||
}
|
||||
if (users.isEmpty() || !users.containsKey(user.getUserId()))
|
||||
{
|
||||
return R.fail("用户不存在");
|
||||
}
|
||||
users.remove(user.getUserId());
|
||||
users.put(user.getUserId(), user);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@Operation(summary = "删除用户信息")
|
||||
@DeleteMapping("/{userId}")
|
||||
public R<String> delete(@PathVariable(name = "userId")
|
||||
Integer userId)
|
||||
{
|
||||
if (!users.isEmpty() && users.containsKey(userId))
|
||||
{
|
||||
users.remove(userId);
|
||||
return R.ok();
|
||||
}
|
||||
else
|
||||
{
|
||||
return R.fail("用户不存在");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Schema(description = "用户实体")
|
||||
class UserEntity
|
||||
{
|
||||
@Schema(title = "用户ID")
|
||||
private Integer userId;
|
||||
|
||||
@Schema(title = "用户名称")
|
||||
private String username;
|
||||
|
||||
@Schema(title = "用户密码")
|
||||
private String password;
|
||||
|
||||
@Schema(title = "用户手机")
|
||||
private String mobile;
|
||||
|
||||
public UserEntity()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public UserEntity(Integer userId, String username, String password, String mobile)
|
||||
{
|
||||
this.userId = userId;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.mobile = mobile;
|
||||
}
|
||||
|
||||
public Integer getUserId()
|
||||
{
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Integer userId)
|
||||
{
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getUsername()
|
||||
{
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username)
|
||||
{
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword()
|
||||
{
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password)
|
||||
{
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getMobile()
|
||||
{
|
||||
return mobile;
|
||||
}
|
||||
|
||||
public void setMobile(String mobile)
|
||||
{
|
||||
this.mobile = mobile;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,288 @@
|
||||
package com.bms.web.controller.tool;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
import javax.xml.stream.XMLStreamConstants;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
/**
|
||||
* BMS TMS 计费接口 demo(单文件,纯 JDK,无第三方依赖)
|
||||
*
|
||||
* 功能:读取 D:\code\view\orders_10000.xlsx 的每一行(跳过表头),
|
||||
* 组装为 JSON 后 POST 到本地 BMS 计费接口。
|
||||
*
|
||||
* 接口:POST http://127.0.0.1:8080/api/tms/price/bill
|
||||
* 鉴权:Header X-Api-Code
|
||||
*
|
||||
* 编译运行:
|
||||
* javac TmsPriceBillDemo.java
|
||||
* java TmsPriceBillDemo
|
||||
*/
|
||||
public class TmsPriceBillDemo {
|
||||
|
||||
// ===== 可配置项 =====
|
||||
private static final String BASE_URL = "http://127.0.0.1:8080";
|
||||
private static final String BILL_PATH = "/api/tms/price/bill";
|
||||
private static final String API_CODE = "BMS.TMS.ZYaOvlQzpcfau8TUaCFfO3Hp8ieHIqGw";
|
||||
private static final String EXCEL_PATH = "D:\\code\\view\\orders_10000.xlsx";
|
||||
private static final int CONNECT_TIMEOUT_MS = 10_000;
|
||||
private static final int READ_TIMEOUT_MS = 30_000;
|
||||
/** 每多少条打印一次进度 */
|
||||
private static final int PROGRESS_STEP = 200;
|
||||
|
||||
/** 数值字段:JSON 中不加引号,直接输出 Excel 中的原始数字字符串 */
|
||||
private static final Set<String> NUMERIC_FIELDS = new HashSet<>(Arrays.asList(
|
||||
"weight", "pieces", "actualWeight", "volume", "volumeWeight",
|
||||
"pkgLength", "pkgWidth", "pkgHeight", "tmsId"
|
||||
));
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// 可通过命令行参数覆盖 Excel 路径
|
||||
String excel = (args.length > 0 && !args[0].isEmpty()) ? args[0] : EXCEL_PATH;
|
||||
System.out.println("[config] base=" + BASE_URL + BILL_PATH);
|
||||
System.out.println("[config] xApiCode=" + API_CODE);
|
||||
System.out.println("[config] excel=" + excel);
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
int ok = 0, fail = 0, rowIdx = 0;
|
||||
|
||||
try (ZipFile zf = new ZipFile(excel)) {
|
||||
List<String> sst = readSharedStrings(zf);
|
||||
System.out.println("[read] sharedStrings uniqueCount=" + sst.size());
|
||||
|
||||
SheetReader sr = new SheetReader(zf, sst);
|
||||
String[] headers = null;
|
||||
List<String> row;
|
||||
|
||||
while ((row = sr.nextRow()) != null) {
|
||||
rowIdx++;
|
||||
if (headers == null) {
|
||||
headers = row.toArray(new String[0]);
|
||||
System.out.println("[read] headers=" + row);
|
||||
continue;
|
||||
}
|
||||
String json = buildJson(row, headers);
|
||||
String resp;
|
||||
try {
|
||||
resp = postJson(BASE_URL + BILL_PATH, API_CODE, json);
|
||||
} catch (Exception e) {
|
||||
resp = "ERR: " + e.getMessage();
|
||||
}
|
||||
if (resp.contains("\"code\":200") || resp.contains("\"code\": 200")) {
|
||||
ok++;
|
||||
} else {
|
||||
fail++;
|
||||
}
|
||||
if (rowIdx % PROGRESS_STEP == 0 || rowIdx == 1) {
|
||||
String snippet = resp.length() > 120 ? resp.substring(0, 120) + "..." : resp;
|
||||
System.out.printf("[progress] %d ok=%d fail=%d last=%s%n", rowIdx, ok, fail, snippet);
|
||||
}
|
||||
}
|
||||
System.out.printf("[done] rows=%d ok=%d fail=%d cost=%dms%n",
|
||||
rowIdx, ok, fail, System.currentTimeMillis() - start);
|
||||
}
|
||||
}
|
||||
|
||||
// ===== JSON 构造 =====
|
||||
|
||||
private static String buildJson(List<String> row, String[] headers) {
|
||||
StringBuilder sb = new StringBuilder(256);
|
||||
sb.append('{');
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
if (i > 0) sb.append(',');
|
||||
String k = headers[i];
|
||||
String v = (i < row.size()) ? row.get(i) : "";
|
||||
sb.append('"').append(escape(k)).append("\":");
|
||||
boolean isNumeric = NUMERIC_FIELDS.contains(k)
|
||||
&& v != null && !v.isEmpty() && !"null".equals(v);
|
||||
if (isNumeric) {
|
||||
sb.append(v);
|
||||
} else if (v == null || v.isEmpty() || "null".equals(v)) {
|
||||
sb.append("null");
|
||||
} else {
|
||||
sb.append('"').append(escape(v)).append('"');
|
||||
}
|
||||
}
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String escape(String s) {
|
||||
if (s == null) return "";
|
||||
StringBuilder sb = new StringBuilder(s.length());
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char c = s.charAt(i);
|
||||
switch (c) {
|
||||
case '"': sb.append("\\\""); break;
|
||||
case '\\': sb.append("\\\\"); break;
|
||||
case '\n': sb.append("\\n"); break;
|
||||
case '\r': sb.append("\\r"); break;
|
||||
case '\t': sb.append("\\t"); break;
|
||||
default:
|
||||
if (c < 0x20) sb.append(String.format("\\u%04x", (int) c));
|
||||
else sb.append(c);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
// ===== HTTP =====
|
||||
|
||||
private static String postJson(String url, String apiCode, String json) throws Exception {
|
||||
HttpURLConnection conn = null;
|
||||
try {
|
||||
conn = (HttpURLConnection) new URL(url).openConnection();
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setDoOutput(true);
|
||||
conn.setConnectTimeout(CONNECT_TIMEOUT_MS);
|
||||
conn.setReadTimeout(READ_TIMEOUT_MS);
|
||||
conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
|
||||
conn.setRequestProperty("X-Api-Code", apiCode);
|
||||
conn.setRequestProperty("Accept", "application/json");
|
||||
|
||||
byte[] body = json.getBytes(StandardCharsets.UTF_8);
|
||||
conn.setRequestProperty("Content-Length", String.valueOf(body.length));
|
||||
try (OutputStream os = conn.getOutputStream()) {
|
||||
os.write(body);
|
||||
os.flush();
|
||||
}
|
||||
|
||||
int code = conn.getResponseCode();
|
||||
InputStream is = (code >= 200 && code < 300) ? conn.getInputStream() : conn.getErrorStream();
|
||||
String respBody = readAll(is);
|
||||
return "HTTP " + code + " " + respBody;
|
||||
} finally {
|
||||
if (conn != null) conn.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
private static String readAll(InputStream is) throws Exception {
|
||||
if (is == null) return "";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
try (BufferedReader r = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
|
||||
String line;
|
||||
while ((line = r.readLine()) != null) {
|
||||
if (sb.length() > 0) sb.append('\n');
|
||||
sb.append(line);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
// ===== XLSX 解析(纯 JDK) =====
|
||||
|
||||
/** 读取 xl/sharedStrings.xml,返回共享字符串表 */
|
||||
private static List<String> readSharedStrings(ZipFile zf) throws Exception {
|
||||
ZipEntry e = zf.getEntry("xl/sharedStrings.xml");
|
||||
if (e == null) return Collections.emptyList();
|
||||
List<String> out = new ArrayList<>();
|
||||
try (InputStream in = zf.getInputStream(e)) {
|
||||
XMLInputFactory f = XMLInputFactory.newInstance();
|
||||
// 禁用 DTD 以避免 XXE
|
||||
f.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
|
||||
f.setProperty(XMLInputFactory.SUPPORT_DTD, false);
|
||||
XMLStreamReader r = f.createXMLStreamReader(in);
|
||||
StringBuilder text = new StringBuilder();
|
||||
boolean inT = false;
|
||||
while (r.hasNext()) {
|
||||
int ev = r.next();
|
||||
if (ev == XMLStreamConstants.START_ELEMENT) {
|
||||
if ("t".equals(r.getLocalName())) {
|
||||
inT = true;
|
||||
text.setLength(0);
|
||||
}
|
||||
} else if (ev == XMLStreamConstants.CHARACTERS) {
|
||||
if (inT) text.append(r.getText());
|
||||
} else if (ev == XMLStreamConstants.END_ELEMENT) {
|
||||
String ln = r.getLocalName();
|
||||
if ("t".equals(ln)) {
|
||||
inT = false;
|
||||
} else if ("si".equals(ln)) {
|
||||
out.add(text.toString());
|
||||
text.setLength(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
r.close();
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/** 流式读取 xl/worksheets/sheet1.xml,nextRow() 逐行返回 */
|
||||
static class SheetReader {
|
||||
private final XMLStreamReader r;
|
||||
private final List<String> sst;
|
||||
private final InputStream stream;
|
||||
|
||||
SheetReader(ZipFile zf, List<String> sst) throws Exception {
|
||||
ZipEntry e = zf.getEntry("xl/worksheets/sheet1.xml");
|
||||
this.stream = zf.getInputStream(e);
|
||||
this.sst = sst;
|
||||
XMLInputFactory f = XMLInputFactory.newInstance();
|
||||
f.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
|
||||
f.setProperty(XMLInputFactory.SUPPORT_DTD, false);
|
||||
this.r = f.createXMLStreamReader(stream);
|
||||
}
|
||||
|
||||
List<String> nextRow() throws Exception {
|
||||
List<String> row = null;
|
||||
String curType = null;
|
||||
StringBuilder curVal = new StringBuilder();
|
||||
boolean inV = false;
|
||||
while (r.hasNext()) {
|
||||
int ev = r.next();
|
||||
if (ev == XMLStreamConstants.START_ELEMENT) {
|
||||
String ln = r.getLocalName();
|
||||
if ("row".equals(ln)) {
|
||||
row = new ArrayList<>();
|
||||
} else if ("c".equals(ln) && row != null) {
|
||||
curType = r.getAttributeValue(null, "t");
|
||||
curVal.setLength(0);
|
||||
} else if ("v".equals(ln) && row != null) {
|
||||
inV = true;
|
||||
} else if ("t".equals(ln) && row != null) {
|
||||
inV = true; // inlineStr 的 <t>
|
||||
}
|
||||
} else if (ev == XMLStreamConstants.CHARACTERS) {
|
||||
if (inV && row != null) curVal.append(r.getText());
|
||||
} else if (ev == XMLStreamConstants.END_ELEMENT) {
|
||||
String ln = r.getLocalName();
|
||||
if ("v".equals(ln) || "t".equals(ln)) {
|
||||
inV = false;
|
||||
} else if ("c".equals(ln) && row != null) {
|
||||
String v = curVal.toString();
|
||||
String val;
|
||||
if ("s".equals(curType)) {
|
||||
int idx = Integer.parseInt(v.trim());
|
||||
val = idx < sst.size() ? sst.get(idx) : "";
|
||||
} else if ("b".equals(curType)) {
|
||||
val = "1".equals(v.trim()) ? "true" : "false";
|
||||
} else {
|
||||
// 数值、str、inlineStr、空等,直接取原值
|
||||
val = v;
|
||||
}
|
||||
row.add(val);
|
||||
} else if ("row".equals(ln) && row != null) {
|
||||
return row;
|
||||
}
|
||||
}
|
||||
}
|
||||
try { r.close(); stream.close(); } catch (Exception ignored) {}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.bms.web.core.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import com.bms.common.config.BmsConfig;
|
||||
import io.swagger.v3.oas.models.Components;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.info.Contact;
|
||||
import io.swagger.v3.oas.models.info.Info;
|
||||
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
||||
import io.swagger.v3.oas.models.security.SecurityScheme;
|
||||
|
||||
/**
|
||||
* Swagger2的接口配置
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@Configuration
|
||||
public class SwaggerConfig
|
||||
{
|
||||
/** 系统基础配置 */
|
||||
@Autowired
|
||||
private BmsConfig bmsConfig;
|
||||
|
||||
/**
|
||||
* 自定义的 OpenAPI 对象
|
||||
*/
|
||||
@Bean
|
||||
public OpenAPI customOpenApi()
|
||||
{
|
||||
return new OpenAPI().components(new Components()
|
||||
// 设置认证的请求头
|
||||
.addSecuritySchemes("apikey", securityScheme()))
|
||||
.addSecurityItem(new SecurityRequirement().addList("apikey"))
|
||||
.info(getApiInfo());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SecurityScheme securityScheme()
|
||||
{
|
||||
return new SecurityScheme()
|
||||
.type(SecurityScheme.Type.APIKEY)
|
||||
.name("Authorization")
|
||||
.in(SecurityScheme.In.HEADER)
|
||||
.scheme("Bearer");
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加摘要信息
|
||||
*/
|
||||
public Info getApiInfo()
|
||||
{
|
||||
return new Info()
|
||||
// 设置标题
|
||||
.title("标题:BMS 管理系统_接口文档")
|
||||
// 描述
|
||||
.description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
|
||||
// 作者信息
|
||||
.contact(new Contact().name(bmsConfig.getName()))
|
||||
// 版本
|
||||
.version("版本号:" + bmsConfig.getVersion());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
restart.include.json=/com.alibaba.fastjson2.*.jar
|
||||
@@ -0,0 +1,80 @@
|
||||
# 本地配置(默认生效)
|
||||
# 启动:不传 profile,或 --spring.profiles.active=local
|
||||
# Elasticsearch:本机 Docker http://127.0.0.1:9200
|
||||
# 数据源暂与线上相同,换本地库时只改本文件
|
||||
|
||||
bms:
|
||||
elasticsearch:
|
||||
enabled: true
|
||||
uris: http://127.0.0.1:9200
|
||||
username:
|
||||
password:
|
||||
index: bms_biz_log
|
||||
|
||||
# 数据源配置
|
||||
spring:
|
||||
datasource:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
druid:
|
||||
# 主库数据源
|
||||
master:
|
||||
url: jdbc:mysql://47.106.220.100:3307/bms?useUnicode=true&characterEncoding=utf8&connectionCollation=utf8mb4_unicode_ci&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
|
||||
username: bms
|
||||
password: D3wsHf2ZMfFtWtKX
|
||||
connectionInitSqls: SET NAMES utf8mb4
|
||||
# Slave DS: Oracle upstream order (TAB_ORDER)
|
||||
slave:
|
||||
enabled: true
|
||||
driverClassName: oracle.jdbc.OracleDriver
|
||||
url: jdbc:oracle:thin:@//120.79.189.203:15281/WSDB
|
||||
username: readonly_report
|
||||
password: k5x15WP1hE
|
||||
# Oracle remote query may need longer read timeout than MySQL
|
||||
connectTimeout: 30000
|
||||
socketTimeout: 120000
|
||||
validationQuery: SELECT 1 FROM DUAL
|
||||
# 初始连接数
|
||||
initialSize: 5
|
||||
# 最小连接池数量
|
||||
minIdle: 10
|
||||
# 最大连接池数量
|
||||
maxActive: 20
|
||||
# 配置获取连接等待超时的时间
|
||||
maxWait: 60000
|
||||
# 配置连接超时时间
|
||||
connectTimeout: 30000
|
||||
# 配置网络超时时间
|
||||
socketTimeout: 60000
|
||||
# 配置间隔多久检测一次空闲连接,避免远程数据库断开后连接池继续复用失效连接,单位是毫秒
|
||||
timeBetweenEvictionRunsMillis: 30000
|
||||
# 配置一个连接在池中最小生存的时间,单位是毫秒
|
||||
minEvictableIdleTimeMillis: 300000
|
||||
# 配置一个连接在池中最大生存的时间,单位是毫秒
|
||||
maxEvictableIdleTimeMillis: 900000
|
||||
# 配置检测连接是否有效
|
||||
validationQuery: SELECT 1 FROM DUAL
|
||||
testWhileIdle: true
|
||||
# 异步账单任务借用连接时校验连接有效性,避免拿到已被数据库断开的连接
|
||||
testOnBorrow: true
|
||||
testOnReturn: false
|
||||
webStatFilter:
|
||||
enabled: true
|
||||
statViewServlet:
|
||||
enabled: true
|
||||
# 设置白名单,不填则允许所有访问
|
||||
allow:
|
||||
url-pattern: /druid/*
|
||||
# 控制台管理用户名和密码
|
||||
login-username: bms
|
||||
login-password: 123456
|
||||
filter:
|
||||
stat:
|
||||
enabled: true
|
||||
# 慢SQL记录
|
||||
log-slow-sql: true
|
||||
slow-sql-millis: 1000
|
||||
merge-sql: true
|
||||
wall:
|
||||
config:
|
||||
multi-statement-allow: true
|
||||
@@ -0,0 +1,90 @@
|
||||
# 线上配置
|
||||
# 启动:--spring.profiles.active=prod
|
||||
# Elasticsearch:172.19.64.13:9200
|
||||
|
||||
# 生产环境文件存储根目录
|
||||
# 上传、导入、头像及账单下载文件都会基于此目录保存
|
||||
bms:
|
||||
profile: /www/server/bms/data
|
||||
elasticsearch:
|
||||
enabled: true
|
||||
uris: https://127.0.0.1:9200
|
||||
username: elastic
|
||||
password: d4aoZYB2yQHXmWZiH6Gw
|
||||
index: bms_biz_log
|
||||
|
||||
logging:
|
||||
level:
|
||||
com.bms: info
|
||||
org.springframework: warn
|
||||
|
||||
# 数据源配置
|
||||
spring:
|
||||
devtools:
|
||||
restart:
|
||||
enabled: false
|
||||
datasource:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
druid:
|
||||
# 主库数据源
|
||||
master:
|
||||
url: jdbc:mysql://127.0.0.1:3306/bms?useUnicode=true&characterEncoding=utf8&connectionCollation=utf8mb4_unicode_ci&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
|
||||
username: bms
|
||||
password: JnE6nTRSNZjnhrcP
|
||||
connectionInitSqls: SET NAMES utf8mb4
|
||||
# Slave DS: Oracle upstream order (TAB_ORDER)
|
||||
slave:
|
||||
enabled: true
|
||||
driverClassName: oracle.jdbc.OracleDriver
|
||||
url: jdbc:oracle:thin:@//120.79.189.203:15281/WSDB
|
||||
username: readonly_report
|
||||
password: k5x15WP1hE
|
||||
# Oracle remote query may need longer read timeout than MySQL
|
||||
connectTimeout: 30000
|
||||
socketTimeout: 120000
|
||||
validationQuery: SELECT 1 FROM DUAL
|
||||
# 初始连接数
|
||||
initialSize: 5
|
||||
# 最小连接池数量
|
||||
minIdle: 10
|
||||
# 最大连接池数量
|
||||
maxActive: 20
|
||||
# 配置获取连接等待超时的时间
|
||||
maxWait: 60000
|
||||
# 配置连接超时时间
|
||||
connectTimeout: 30000
|
||||
# 配置网络超时时间
|
||||
socketTimeout: 60000
|
||||
# 配置间隔多久检测一次空闲连接,避免远程数据库断开后连接池继续复用失效连接,单位是毫秒
|
||||
timeBetweenEvictionRunsMillis: 30000
|
||||
# 配置一个连接在池中最小生存的时间,单位是毫秒
|
||||
minEvictableIdleTimeMillis: 300000
|
||||
# 配置一个连接在池中最大生存的时间,单位是毫秒
|
||||
maxEvictableIdleTimeMillis: 900000
|
||||
# 配置检测连接是否有效
|
||||
validationQuery: SELECT 1 FROM DUAL
|
||||
testWhileIdle: true
|
||||
# 异步账单任务借用连接时校验连接有效性,避免拿到已被数据库断开的连接
|
||||
testOnBorrow: true
|
||||
testOnReturn: false
|
||||
webStatFilter:
|
||||
enabled: true
|
||||
statViewServlet:
|
||||
enabled: true
|
||||
# 设置白名单,不填则允许所有访问
|
||||
allow:
|
||||
url-pattern: /druid/*
|
||||
# 控制台管理用户名和密码
|
||||
login-username: bms
|
||||
login-password: 123456
|
||||
filter:
|
||||
stat:
|
||||
enabled: true
|
||||
# 慢SQL记录
|
||||
log-slow-sql: true
|
||||
slow-sql-millis: 1000
|
||||
merge-sql: true
|
||||
wall:
|
||||
config:
|
||||
multi-statement-allow: true
|
||||
@@ -0,0 +1,171 @@
|
||||
# 项目相关配置
|
||||
bms:
|
||||
# 名称
|
||||
name: BMS
|
||||
# 版本
|
||||
version: 3.9.2
|
||||
# 版权年份
|
||||
copyrightYear: 2026
|
||||
# 文件路径 示例( Windows配置D:/bms/uploadPath,Linux配置 /home/bms/uploadPath)
|
||||
profile: D:/bms/uploadPath
|
||||
# 获取ip地址开关
|
||||
addressEnabled: false
|
||||
# 验证码类型 math 数字计算 char 字符验证
|
||||
captchaType: math
|
||||
# TMS open API
|
||||
tms:
|
||||
# Agreed API identification code for TMS callers
|
||||
api-code: BMS.TMS.ZYaOvlQzpcfau8TUaCFfO3Hp8ieHIqGw
|
||||
billing:
|
||||
# MQ mode: redis (default list queue) | local (Spring event)
|
||||
mq-mode: redis
|
||||
mq-queue-key: bms:billing:task
|
||||
consumer-enabled: true
|
||||
# Pop/process interval after previous tick finishes
|
||||
consumer-delay-ms: 200
|
||||
# Max messages popped per tick; processed by consumer-threads pool
|
||||
consumer-batch-size: 32
|
||||
consumer-threads: 8
|
||||
oracle:
|
||||
# SLAVE datasource Oracle main-order table (schema.table allowed)
|
||||
order-table: WEISHI_USER.TAB_ORDER
|
||||
# Fallback product when Oracle row has no PRODUCT_CODE
|
||||
default-product-code: ""
|
||||
|
||||
# 开发环境配置
|
||||
server:
|
||||
# 服务器的HTTP端口,默认为8080
|
||||
port: 8080
|
||||
servlet:
|
||||
# 应用的访问路径
|
||||
context-path: /
|
||||
tomcat:
|
||||
# tomcat的URI编码
|
||||
uri-encoding: UTF-8
|
||||
# 连接数满后的排队数,默认为100
|
||||
accept-count: 1000
|
||||
threads:
|
||||
# tomcat最大线程数,默认为200
|
||||
max: 800
|
||||
# Tomcat启动初始化的线程数,默认值10
|
||||
min-spare: 100
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
com.bms: debug
|
||||
org.springframework: warn
|
||||
|
||||
# 用户配置
|
||||
user:
|
||||
password:
|
||||
# 密码最大错误次数
|
||||
maxRetryCount: 5
|
||||
# 密码锁定时间(默认10分钟)
|
||||
lockTime: 10
|
||||
|
||||
# Spring配置
|
||||
spring:
|
||||
# 允许循环引用(price 模块 PrcOrderBillServiceImpl <-> PrcCreditArrearsClearAsyncRunner 互依赖)
|
||||
main:
|
||||
allow-circular-references: true
|
||||
# 资源信息
|
||||
messages:
|
||||
# 国际化资源文件路径
|
||||
basename: i18n/messages
|
||||
profiles:
|
||||
# local -> application-local.yml ; prod -> application-prod.yml
|
||||
active: '@profiles.active@'
|
||||
# 文件上传
|
||||
servlet:
|
||||
multipart:
|
||||
# 单个文件大小
|
||||
max-file-size: 10MB
|
||||
# 设置总上传的文件大小
|
||||
max-request-size: 20MB
|
||||
jackson:
|
||||
time-zone: GMT+8
|
||||
date-format: yyyy-MM-dd HH:mm:ss
|
||||
# 服务模块
|
||||
devtools:
|
||||
restart:
|
||||
# 热部署开关
|
||||
enabled: true
|
||||
data:
|
||||
# redis 配置
|
||||
redis:
|
||||
# 地址
|
||||
host: localhost
|
||||
# 端口,默认为6379
|
||||
port: 6379
|
||||
# 数据库索引
|
||||
database: 0
|
||||
# 密码
|
||||
password:
|
||||
# 连接超时时间
|
||||
timeout: 10s
|
||||
lettuce:
|
||||
pool:
|
||||
# 连接池中的最小空闲连接
|
||||
min-idle: 0
|
||||
# 连接池中的最大空闲连接
|
||||
max-idle: 8
|
||||
# 连接池的最大数据库连接数
|
||||
max-active: 8
|
||||
# #连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||
max-wait: -1ms
|
||||
|
||||
# token配置
|
||||
token:
|
||||
# 令牌自定义标识
|
||||
header: Authorization
|
||||
# 令牌密钥
|
||||
secret: abcdefghijklmnopqrstuvwxyz
|
||||
# 令牌有效期(默认30分钟)
|
||||
expireTime: 30
|
||||
|
||||
# MyBatis配置
|
||||
mybatis:
|
||||
# 搜索指定包别名
|
||||
typeAliasesPackage: com.bms.**.domain
|
||||
# 配置mapper的扫描,找到所有的mapper.xml映射文件
|
||||
mapperLocations: classpath*:mapper/**/*Mapper.xml
|
||||
# 加载全局的配置文件
|
||||
configLocation: classpath:mybatis/mybatis-config.xml
|
||||
|
||||
# PageHelper分页插件
|
||||
pagehelper:
|
||||
helperDialect: mysql
|
||||
supportMethodsArguments: true
|
||||
params: count=countSql
|
||||
|
||||
# Springdoc配置
|
||||
springdoc:
|
||||
api-docs:
|
||||
path: /v3/api-docs
|
||||
swagger-ui:
|
||||
enabled: true
|
||||
path: /swagger-ui.html
|
||||
tags-sorter: alpha
|
||||
group-configs:
|
||||
- group: 'default'
|
||||
display-name: '测试模块'
|
||||
paths-to-match: '/**'
|
||||
packages-to-scan: com.bms.web.controller.tool
|
||||
|
||||
# 防盗链配置
|
||||
referer:
|
||||
# 防盗链开关
|
||||
enabled: false
|
||||
# 允许的域名列表
|
||||
allowed-domains: localhost,127.0.0.1
|
||||
|
||||
# 防止XSS攻击
|
||||
xss:
|
||||
# 过滤开关
|
||||
enabled: true
|
||||
# 排除链接(多个用逗号分隔)
|
||||
excludes: /system/notice
|
||||
# 匹配链接
|
||||
urlPatterns: /system/*,/monitor/*,/tool/*
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
Application Version: ${bms.version}
|
||||
Spring Boot Version: ${spring-boot.version}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// _ooOoo_ //
|
||||
// o8888888o //
|
||||
// 88" . "88 //
|
||||
// (| ^_^ |) //
|
||||
// O\ = /O //
|
||||
// ____/`---'\____ //
|
||||
// .' \\| |// `. //
|
||||
// / \\||| : |||// \ //
|
||||
// / _||||| -:- |||||- \ //
|
||||
// | | \\\ - /// | | //
|
||||
// | \_| ''\---/'' | | //
|
||||
// \ .-\__ `-` ___/-. / //
|
||||
// ___`. .' /--.--\ `. . ___ //
|
||||
// ."" '< `.___\_<|>_/___.' >'"". //
|
||||
// | | : `- \`.;`\ _ /`;.`/ - ` : | | //
|
||||
// \ \ `-. \_ __\ /__ _/ .-` / / //
|
||||
// ========`-.____`-.___\_____/___.-`____.-'======== //
|
||||
// `=---=' //
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //
|
||||
// 佛祖保佑 永不宕机 永无BUG //
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,107 @@
|
||||
[
|
||||
{"name":{"common":"China","official":"People's Republic of China"},"cca2":"CN","cca3":"CHN","region":"Asia","subregion":"Eastern Asia","currencies":{"CNY":{"name":"Chinese yuan","symbol":"¥"}},"idd":{"root":"+86","suffixes":[""]},"flag":"🇨🇳","flags":{"png":"https://flagcdn.com/w320/cn.png"},"independent":true},
|
||||
{"name":{"common":"United States","official":"United States of America"},"cca2":"US","cca3":"USA","region":"Americas","subregion":"North America","currencies":{"USD":{"name":"United States dollar","symbol":"$"}},"idd":{"root":"+1","suffixes":[""]},"flag":"🇺🇸","flags":{"png":"https://flagcdn.com/w320/us.png"},"independent":true},
|
||||
{"name":{"common":"Germany","official":"Federal Republic of Germany"},"cca2":"DE","cca3":"DEU","region":"Europe","subregion":"Western Europe","currencies":{"EUR":{"name":"Euro","symbol":"€"}},"idd":{"root":"+49","suffixes":[""]},"flag":"🇩🇪","flags":{"png":"https://flagcdn.com/w320/de.png"},"independent":true},
|
||||
{"name":{"common":"Japan","official":"Japan"},"cca2":"JP","cca3":"JPN","region":"Asia","subregion":"Eastern Asia","currencies":{"JPY":{"name":"Japanese yen","symbol":"¥"}},"idd":{"root":"+81","suffixes":[""]},"flag":"🇯🇵","flags":{"png":"https://flagcdn.com/w320/jp.png"},"independent":true},
|
||||
{"name":{"common":"South Korea","official":"Republic of Korea"},"cca2":"KR","cca3":"KOR","region":"Asia","subregion":"Eastern Asia","currencies":{"KRW":{"name":"South Korean won","symbol":"₩"}},"idd":{"root":"+82","suffixes":[""]},"flag":"🇰🇷","flags":{"png":"https://flagcdn.com/w320/kr.png"},"independent":true},
|
||||
{"name":{"common":"United Kingdom","official":"United Kingdom of Great Britain and Northern Ireland"},"cca2":"GB","cca3":"GBR","region":"Europe","subregion":"Northern Europe","currencies":{"GBP":{"name":"British pound","symbol":"£"}},"idd":{"root":"+44","suffixes":[""]},"flag":"🇬🇧","flags":{"png":"https://flagcdn.com/w320/gb.png"},"independent":true},
|
||||
{"name":{"common":"France","official":"French Republic"},"cca2":"FR","cca3":"FRA","region":"Europe","subregion":"Western Europe","currencies":{"EUR":{"name":"Euro","symbol":"€"}},"idd":{"root":"+33","suffixes":[""]},"flag":"🇫🇷","flags":{"png":"https://flagcdn.com/w320/fr.png"},"independent":true},
|
||||
{"name":{"common":"Italy","official":"Italian Republic"},"cca2":"IT","cca3":"ITA","region":"Europe","subregion":"Southern Europe","currencies":{"EUR":{"name":"Euro","symbol":"€"}},"idd":{"root":"+39","suffixes":[""]},"flag":"🇮🇹","flags":{"png":"https://flagcdn.com/w320/it.png"},"independent":true},
|
||||
{"name":{"common":"Spain","official":"Kingdom of Spain"},"cca2":"ES","cca3":"ESP","region":"Europe","subregion":"Southern Europe","currencies":{"EUR":{"name":"Euro","symbol":"€"}},"idd":{"root":"+34","suffixes":[""]},"flag":"🇪🇸","flags":{"png":"https://flagcdn.com/w320/es.png"},"independent":true},
|
||||
{"name":{"common":"Netherlands","official":"Kingdom of the Netherlands"},"cca2":"NL","cca3":"NLD","region":"Europe","subregion":"Western Europe","currencies":{"EUR":{"name":"Euro","symbol":"€"}},"idd":{"root":"+31","suffixes":[""]},"flag":"🇳🇱","flags":{"png":"https://flagcdn.com/w320/nl.png"},"independent":true},
|
||||
{"name":{"common":"Belgium","official":"Kingdom of Belgium"},"cca2":"BE","cca3":"BEL","region":"Europe","subregion":"Western Europe","currencies":{"EUR":{"name":"Euro","symbol":"€"}},"idd":{"root":"+32","suffixes":[""]},"flag":"🇧🇪","flags":{"png":"https://flagcdn.com/w320/be.png"},"independent":true},
|
||||
{"name":{"common":"Switzerland","official":"Swiss Confederation"},"cca2":"CH","cca3":"CHE","region":"Europe","subregion":"Western Europe","currencies":{"CHF":{"name":"Swiss franc","symbol":"Fr."}},"idd":{"root":"+41","suffixes":[""]},"flag":"🇨🇭","flags":{"png":"https://flagcdn.com/w320/ch.png"},"independent":true},
|
||||
{"name":{"common":"Austria","official":"Republic of Austria"},"cca2":"AT","cca3":"AUT","region":"Europe","subregion":"Western Europe","currencies":{"EUR":{"name":"Euro","symbol":"€"}},"idd":{"root":"+43","suffixes":[""]},"flag":"🇦🇹","flags":{"png":"https://flagcdn.com/w320/at.png"},"independent":true},
|
||||
{"name":{"common":"Sweden","official":"Kingdom of Sweden"},"cca2":"SE","cca3":"SWE","region":"Europe","subregion":"Northern Europe","currencies":{"SEK":{"name":"Swedish krona","symbol":"kr"}},"idd":{"root":"+46","suffixes":[""]},"flag":"🇸🇪","flags":{"png":"https://flagcdn.com/w320/se.png"},"independent":true},
|
||||
{"name":{"common":"Norway","official":"Kingdom of Norway"},"cca2":"NO","cca3":"NOR","region":"Europe","subregion":"Northern Europe","currencies":{"NOK":{"name":"Norwegian krone","symbol":"kr"}},"idd":{"root":"+47","suffixes":[""]},"flag":"🇳🇴","flags":{"png":"https://flagcdn.com/w320/no.png"},"independent":true},
|
||||
{"name":{"common":"Denmark","official":"Kingdom of Denmark"},"cca2":"DK","cca3":"DNK","region":"Europe","subregion":"Northern Europe","currencies":{"DKK":{"name":"Danish krone","symbol":"kr"}},"idd":{"root":"+45","suffixes":[""]},"flag":"🇩🇰","flags":{"png":"https://flagcdn.com/w320/dk.png"},"independent":true},
|
||||
{"name":{"common":"Finland","official":"Republic of Finland"},"cca2":"FI","cca3":"FIN","region":"Europe","subregion":"Northern Europe","currencies":{"EUR":{"name":"Euro","symbol":"€"}},"idd":{"root":"+358","suffixes":[""]},"flag":"🇫🇮","flags":{"png":"https://flagcdn.com/w320/fi.png"},"independent":true},
|
||||
{"name":{"common":"Poland","official":"Republic of Poland"},"cca2":"PL","cca3":"POL","region":"Europe","subregion":"Central Europe","currencies":{"PLN":{"name":"Polish zloty","symbol":"zł"}},"idd":{"root":"+48","suffixes":[""]},"flag":"🇵🇱","flags":{"png":"https://flagcdn.com/w320/pl.png"},"independent":true},
|
||||
{"name":{"common":"Russia","official":"Russian Federation"},"cca2":"RU","cca3":"RUS","region":"Europe","subregion":"Eastern Europe","currencies":{"RUB":{"name":"Russian ruble","symbol":"₽"}},"idd":{"root":"+7","suffixes":[""]},"flag":"🇷🇺","flags":{"png":"https://flagcdn.com/w320/ru.png"},"independent":true},
|
||||
{"name":{"common":"India","official":"Republic of India"},"cca2":"IN","cca3":"IND","region":"Asia","subregion":"Southern Asia","currencies":{"INR":{"name":"Indian rupee","symbol":"₹"}},"idd":{"root":"+91","suffixes":[""]},"flag":"🇮🇳","flags":{"png":"https://flagcdn.com/w320/in.png"},"independent":true},
|
||||
{"name":{"common":"Brazil","official":"Federative Republic of Brazil"},"cca2":"BR","cca3":"BRA","region":"Americas","subregion":"South America","currencies":{"BRL":{"name":"Brazilian real","symbol":"R$"}},"idd":{"root":"+55","suffixes":[""]},"flag":"🇧🇷","flags":{"png":"https://flagcdn.com/w320/br.png"},"independent":true},
|
||||
{"name":{"common":"Canada","official":"Canada"},"cca2":"CA","cca3":"CAN","region":"Americas","subregion":"North America","currencies":{"CAD":{"name":"Canadian dollar","symbol":"$"}},"idd":{"root":"+1","suffixes":[""]},"flag":"🇨🇦","flags":{"png":"https://flagcdn.com/w320/ca.png"},"independent":true},
|
||||
{"name":{"common":"Australia","official":"Commonwealth of Australia"},"cca2":"AU","cca3":"AUS","region":"Oceania","subregion":"Australia and New Zealand","currencies":{"AUD":{"name":"Australian dollar","symbol":"$"}},"idd":{"root":"+61","suffixes":[""]},"flag":"🇦🇺","flags":{"png":"https://flagcdn.com/w320/au.png"},"independent":true},
|
||||
{"name":{"common":"Mexico","official":"United Mexican States"},"cca2":"MX","cca3":"MEX","region":"Americas","subregion":"North America","currencies":{"MXN":{"name":"Mexican peso","symbol":"$"}},"idd":{"root":"+52","suffixes":[""]},"flag":"🇲🇽","flags":{"png":"https://flagcdn.com/w320/mx.png"},"independent":true},
|
||||
{"name":{"common":"Indonesia","official":"Republic of Indonesia"},"cca2":"ID","cca3":"IDN","region":"Asia","subregion":"South-Eastern Asia","currencies":{"IDR":{"name":"Indonesian rupiah","symbol":"Rp"}},"idd":{"root":"+62","suffixes":[""]},"flag":"🇮🇩","flags":{"png":"https://flagcdn.com/w320/id.png"},"independent":true},
|
||||
{"name":{"common":"Thailand","official":"Kingdom of Thailand"},"cca2":"TH","cca3":"THA","region":"Asia","subregion":"South-Eastern Asia","currencies":{"THB":{"name":"Thai baht","symbol":"฿"}},"idd":{"root":"+66","suffixes":[""]},"flag":"🇹🇭","flags":{"png":"https://flagcdn.com/w320/th.png"},"independent":true},
|
||||
{"name":{"common":"Vietnam","official":"Socialist Republic of Vietnam"},"cca2":"VN","cca3":"VNM","region":"Asia","subregion":"South-Eastern Asia","currencies":{"VND":{"name":"Vietnamese đồng","symbol":"₫"}},"idd":{"root":"+84","suffixes":[""]},"flag":"🇻🇳","flags":{"png":"https://flagcdn.com/w320/vn.png"},"independent":true},
|
||||
{"name":{"common":"Malaysia","official":"Malaysia"},"cca2":"MY","cca3":"MYS","region":"Asia","subregion":"South-Eastern Asia","currencies":{"MYR":{"name":"Malaysian ringgit","symbol":"RM"}},"idd":{"root":"+60","suffixes":[""]},"flag":"🇲🇾","flags":{"png":"https://flagcdn.com/w320/my.png"},"independent":true},
|
||||
{"name":{"common":"Singapore","official":"Republic of Singapore"},"cca2":"SG","cca3":"SGP","region":"Asia","subregion":"South-Eastern Asia","currencies":{"SGD":{"name":"Singapore dollar","symbol":"$"}},"idd":{"root":"+65","suffixes":[""]},"flag":"🇸🇬","flags":{"png":"https://flagcdn.com/w320/sg.png"},"independent":true},
|
||||
{"name":{"common":"Philippines","official":"Republic of the Philippines"},"cca2":"PH","cca3":"PHL","region":"Asia","subregion":"South-Eastern Asia","currencies":{"PHP":{"name":"Philippine peso","symbol":"₱"}},"idd":{"root":"+63","suffixes":[""]},"flag":"🇵🇭","flags":{"png":"https://flagcdn.com/w320/ph.png"},"independent":true},
|
||||
{"name":{"common":"Turkey","official":"Republic of Türkiye"},"cca2":"TR","cca3":"TUR","region":"Asia","subregion":"Western Asia","currencies":{"TRY":{"name":"Turkish lira","symbol":"₺"}},"idd":{"root":"+90","suffixes":[""]},"flag":"🇹🇷","flags":{"png":"https://flagcdn.com/w320/tr.png"},"independent":true},
|
||||
{"name":{"common":"Saudi Arabia","official":"Kingdom of Saudi Arabia"},"cca2":"SA","cca3":"SAU","region":"Asia","subregion":"Western Asia","currencies":{"SAR":{"name":"Saudi riyal","symbol":"ر.س"}},"idd":{"root":"+966","suffixes":[""]},"flag":"🇸🇦","flags":{"png":"https://flagcdn.com/w320/sa.png"},"independent":true},
|
||||
{"name":{"common":"United Arab Emirates","official":"United Arab Emirates"},"cca2":"AE","cca3":"ARE","region":"Asia","subregion":"Western Asia","currencies":{"AED":{"name":"United Arab Emirates dirham","symbol":"د.إ"}},"idd":{"root":"+971","suffixes":[""]},"flag":"🇦🇪","flags":{"png":"https://flagcdn.com/w320/ae.png"},"independent":true},
|
||||
{"name":{"common":"Israel","official":"State of Israel"},"cca2":"IL","cca3":"ISR","region":"Asia","subregion":"Western Asia","currencies":{"ILS":{"name":"Israeli new shekel","symbol":"₪"}},"idd":{"root":"+972","suffixes":[""]},"flag":"🇮🇱","flags":{"png":"https://flagcdn.com/w320/il.png"},"independent":true},
|
||||
{"name":{"common":"Egypt","official":"Arab Republic of Egypt"},"cca2":"EG","cca3":"EGY","region":"Africa","subregion":"Northern Africa","currencies":{"EGP":{"name":"Egyptian pound","symbol":"£"}},"idd":{"root":"+20","suffixes":[""]},"flag":"🇪🇬","flags":{"png":"https://flagcdn.com/w320/eg.png"},"independent":true},
|
||||
{"name":{"common":"South Africa","official":"Republic of South Africa"},"cca2":"ZA","cca3":"ZAF","region":"Africa","subregion":"Southern Africa","currencies":{"ZAR":{"name":"South African rand","symbol":"R"}},"idd":{"root":"+27","suffixes":[""]},"flag":"🇿🇦","flags":{"png":"https://flagcdn.com/w320/za.png"},"independent":true},
|
||||
{"name":{"common":"Nigeria","official":"Federal Republic of Nigeria"},"cca2":"NG","cca3":"NGA","region":"Africa","subregion":"Western Africa","currencies":{"NGN":{"name":"Nigerian naira","symbol":"₦"}},"idd":{"root":"+234","suffixes":[""]},"flag":"🇳🇬","flags":{"png":"https://flagcdn.com/w320/ng.png"},"independent":true},
|
||||
{"name":{"common":"Argentina","official":"Argentine Republic"},"cca2":"AR","cca3":"ARG","region":"Americas","subregion":"South America","currencies":{"ARS":{"name":"Argentine peso","symbol":"$"}},"idd":{"root":"+54","suffixes":[""]},"flag":"🇦🇷","flags":{"png":"https://flagcdn.com/w320/ar.png"},"independent":true},
|
||||
{"name":{"common":"Chile","official":"Republic of Chile"},"cca2":"CL","cca3":"CHL","region":"Americas","subregion":"South America","currencies":{"CLP":{"name":"Chilean peso","symbol":"$"}},"idd":{"root":"+56","suffixes":[""]},"flag":"🇨🇱","flags":{"png":"https://flagcdn.com/w320/cl.png"},"independent":true},
|
||||
{"name":{"common":"Colombia","official":"Republic of Colombia"},"cca2":"CO","cca3":"COL","region":"Americas","subregion":"South America","currencies":{"COP":{"name":"Colombian peso","symbol":"$"}},"idd":{"root":"+57","suffixes":[""]},"flag":"🇨🇴","flags":{"png":"https://flagcdn.com/w320/co.png"},"independent":true},
|
||||
{"name":{"common":"Peru","official":"Republic of Peru"},"cca2":"PE","cca3":"PER","region":"Americas","subregion":"South America","currencies":{"PEN":{"name":"Peruvian sol","symbol":"S/"}},"idd":{"root":"+51","suffixes":[""]},"flag":"🇵🇪","flags":{"png":"https://flagcdn.com/w320/pe.png"},"independent":true},
|
||||
{"name":{"common":"New Zealand","official":"New Zealand"},"cca2":"NZ","cca3":"NZL","region":"Oceania","subregion":"Australia and New Zealand","currencies":{"NZD":{"name":"New Zealand dollar","symbol":"$"}},"idd":{"root":"+64","suffixes":[""]},"flag":"🇳🇿","flags":{"png":"https://flagcdn.com/w320/nz.png"},"independent":true},
|
||||
{"name":{"common":"Ireland","official":"Republic of Ireland"},"cca2":"IE","cca3":"IRL","region":"Europe","subregion":"Northern Europe","currencies":{"EUR":{"name":"Euro","symbol":"€"}},"idd":{"root":"+353","suffixes":[""]},"flag":"🇮🇪","flags":{"png":"https://flagcdn.com/w320/ie.png"},"independent":true},
|
||||
{"name":{"common":"Portugal","official":"Portuguese Republic"},"cca2":"PT","cca3":"PRT","region":"Europe","subregion":"Southern Europe","currencies":{"EUR":{"name":"Euro","symbol":"€"}},"idd":{"root":"+351","suffixes":[""]},"flag":"🇵🇹","flags":{"png":"https://flagcdn.com/w320/pt.png"},"independent":true},
|
||||
{"name":{"common":"Greece","official":"Hellenic Republic"},"cca2":"GR","cca3":"GRC","region":"Europe","subregion":"Southern Europe","currencies":{"EUR":{"name":"Euro","symbol":"€"}},"idd":{"root":"+30","suffixes":[""]},"flag":"🇬🇷","flags":{"png":"https://flagcdn.com/w320/gr.png"},"independent":true},
|
||||
{"name":{"common":"Czechia","official":"Czech Republic"},"cca2":"CZ","cca3":"CZE","region":"Europe","subregion":"Central Europe","currencies":{"CZK":{"name":"Czech koruna","symbol":"Kč"}},"idd":{"root":"+420","suffixes":[""]},"flag":"🇨🇿","flags":{"png":"https://flagcdn.com/w320/cz.png"},"independent":true},
|
||||
{"name":{"common":"Hungary","official":"Hungary"},"cca2":"HU","cca3":"HUN","region":"Europe","subregion":"Central Europe","currencies":{"HUF":{"name":"Hungarian forint","symbol":"Ft"}},"idd":{"root":"+36","suffixes":[""]},"flag":"🇭🇺","flags":{"png":"https://flagcdn.com/w320/hu.png"},"independent":true},
|
||||
{"name":{"common":"Romania","official":"Romania"},"cca2":"RO","cca3":"ROU","region":"Europe","subregion":"Central Europe","currencies":{"RON":{"name":"Romanian leu","symbol":"lei"}},"idd":{"root":"+40","suffixes":[""]},"flag":"🇷🇴","flags":{"png":"https://flagcdn.com/w320/ro.png"},"independent":true},
|
||||
{"name":{"common":"Bulgaria","official":"Republic of Bulgaria"},"cca2":"BG","cca3":"BGR","region":"Europe","subregion":"Southeast Europe","currencies":{"BGN":{"name":"Bulgarian lev","symbol":"лв"}},"idd":{"root":"+359","suffixes":[""]},"flag":"🇧🇬","flags":{"png":"https://flagcdn.com/w320/bg.png"},"independent":true},
|
||||
{"name":{"common":"Croatia","official":"Republic of Croatia"},"cca2":"HR","cca3":"HRV","region":"Europe","subregion":"Southeast Europe","currencies":{"EUR":{"name":"Euro","symbol":"€"}},"idd":{"root":"+385","suffixes":[""]},"flag":"🇭🇷","flags":{"png":"https://flagcdn.com/w320/hr.png"},"independent":true},
|
||||
{"name":{"common":"Slovakia","official":"Slovak Republic"},"cca2":"SK","cca3":"SVK","region":"Europe","subregion":"Central Europe","currencies":{"EUR":{"name":"Euro","symbol":"€"}},"idd":{"root":"+421","suffixes":[""]},"flag":"🇸🇰","flags":{"png":"https://flagcdn.com/w320/sk.png"},"independent":true},
|
||||
{"name":{"common":"Slovenia","official":"Republic of Slovenia"},"cca2":"SI","cca3":"SVN","region":"Europe","subregion":"Central Europe","currencies":{"EUR":{"name":"Euro","symbol":"€"}},"idd":{"root":"+386","suffixes":[""]},"flag":"🇸🇮","flags":{"png":"https://flagcdn.com/w320/si.png"},"independent":true},
|
||||
{"name":{"common":"Lithuania","official":"Republic of Lithuania"},"cca2":"LT","cca3":"LTU","region":"Europe","subregion":"Northern Europe","currencies":{"EUR":{"name":"Euro","symbol":"€"}},"idd":{"root":"+370","suffixes":[""]},"flag":"🇱🇹","flags":{"png":"https://flagcdn.com/w320/lt.png"},"independent":true},
|
||||
{"name":{"common":"Latvia","official":"Republic of Latvia"},"cca2":"LV","cca3":"LVA","region":"Europe","subregion":"Northern Europe","currencies":{"EUR":{"name":"Euro","symbol":"€"}},"idd":{"root":"+371","suffixes":[""]},"flag":"🇱🇻","flags":{"png":"https://flagcdn.com/w320/lv.png"},"independent":true},
|
||||
{"name":{"common":"Estonia","official":"Republic of Estonia"},"cca2":"EE","cca3":"EST","region":"Europe","subregion":"Northern Europe","currencies":{"EUR":{"name":"Euro","symbol":"€"}},"idd":{"root":"+372","suffixes":[""]},"flag":"🇪🇪","flags":{"png":"https://flagcdn.com/w320/ee.png"},"independent":true},
|
||||
{"name":{"common":"Ukraine","official":"Ukraine"},"cca2":"UA","cca3":"UKR","region":"Europe","subregion":"Eastern Europe","currencies":{"UAH":{"name":"Ukrainian hryvnia","symbol":"₴"}},"idd":{"root":"+380","suffixes":[""]},"flag":"🇺🇦","flags":{"png":"https://flagcdn.com/w320/ua.png"},"independent":true},
|
||||
{"name":{"common":"Morocco","official":"Kingdom of Morocco"},"cca2":"MA","cca3":"MAR","region":"Africa","subregion":"Northern Africa","currencies":{"MAD":{"name":"Moroccan dirham","symbol":"د.م."}},"idd":{"root":"+212","suffixes":[""]},"flag":"🇲🇦","flags":{"png":"https://flagcdn.com/w320/ma.png"},"independent":true},
|
||||
{"name":{"common":"Kenya","official":"Republic of Kenya"},"cca2":"KE","cca3":"KEN","region":"Africa","subregion":"Eastern Africa","currencies":{"KES":{"name":"Kenyan shilling","symbol":"KSh"}},"idd":{"root":"+254","suffixes":[""]},"flag":"🇰🇪","flags":{"png":"https://flagcdn.com/w320/ke.png"},"independent":true},
|
||||
{"name":{"common":"Pakistan","official":"Islamic Republic of Pakistan"},"cca2":"PK","cca3":"PAK","region":"Asia","subregion":"Southern Asia","currencies":{"PKR":{"name":"Pakistani rupee","symbol":"₨"}},"idd":{"root":"+92","suffixes":[""]},"flag":"🇵🇰","flags":{"png":"https://flagcdn.com/w320/pk.png"},"independent":true},
|
||||
{"name":{"common":"Bangladesh","official":"People's Republic of Bangladesh"},"cca2":"BD","cca3":"BGD","region":"Asia","subregion":"Southern Asia","currencies":{"BDT":{"name":"Bangladeshi taka","symbol":"৳"}},"idd":{"root":"+880","suffixes":[""]},"flag":"🇧🇩","flags":{"png":"https://flagcdn.com/w320/bd.png"},"independent":true},
|
||||
{"name":{"common":"Iran","official":"Islamic Republic of Iran"},"cca2":"IR","cca3":"IRN","region":"Asia","subregion":"Southern Asia","currencies":{"IRR":{"name":"Iranian rial","symbol":"﷼"}},"idd":{"root":"+98","suffixes":[""]},"flag":"🇮🇷","flags":{"png":"https://flagcdn.com/w320/ir.png"},"independent":true},
|
||||
{"name":{"common":"Iraq","official":"Republic of Iraq"},"cca2":"IQ","cca3":"IRQ","region":"Asia","subregion":"Western Asia","currencies":{"IQD":{"name":"Iraqi dinar","symbol":"د.ع"}},"idd":{"root":"+964","suffixes":[""]},"flag":"🇮🇶","flags":{"png":"https://flagcdn.com/w320/iq.png"},"independent":true},
|
||||
{"name":{"common":"Kuwait","official":"State of Kuwait"},"cca2":"KW","cca3":"KWT","region":"Asia","subregion":"Western Asia","currencies":{"KWD":{"name":"Kuwaiti dinar","symbol":"د.ك"}},"idd":{"root":"+965","suffixes":[""]},"flag":"🇰🇼","flags":{"png":"https://flagcdn.com/w320/kw.png"},"independent":true},
|
||||
{"name":{"common":"Qatar","official":"State of Qatar"},"cca2":"QA","cca3":"QAT","region":"Asia","subregion":"Western Asia","currencies":{"QAR":{"name":"Qatari riyal","symbol":"ر.ق"}},"idd":{"root":"+974","suffixes":[""]},"flag":"🇶🇦","flags":{"png":"https://flagcdn.com/w320/qa.png"},"independent":true},
|
||||
{"name":{"common":"Hong Kong","official":"Hong Kong Special Administrative Region of China"},"cca2":"HK","cca3":"HKG","region":"Asia","subregion":"Eastern Asia","currencies":{"HKD":{"name":"Hong Kong dollar","symbol":"$"}},"idd":{"root":"+852","suffixes":[""]},"flag":"🇭🇰","flags":{"png":"https://flagcdn.com/w320/hk.png"},"independent":false},
|
||||
{"name":{"common":"Taiwan","official":"Republic of China"},"cca2":"TW","cca3":"TWN","region":"Asia","subregion":"Eastern Asia","currencies":{"TWD":{"name":"New Taiwan dollar","symbol":"$"}},"idd":{"root":"+886","suffixes":[""]},"flag":"🇹🇼","flags":{"png":"https://flagcdn.com/w320/tw.png"},"independent":false},
|
||||
{"name":{"common":"Iceland","official":"Iceland"},"cca2":"IS","cca3":"ISL","region":"Europe","subregion":"Northern Europe","currencies":{"ISK":{"name":"Icelandic króna","symbol":"kr"}},"idd":{"root":"+354","suffixes":[""]},"flag":"🇮🇸","flags":{"png":"https://flagcdn.com/w320/is.png"},"independent":true},
|
||||
{"name":{"common":"Luxembourg","official":"Grand Duchy of Luxembourg"},"cca2":"LU","cca3":"LUX","region":"Europe","subregion":"Western Europe","currencies":{"EUR":{"name":"Euro","symbol":"€"}},"idd":{"root":"+352","suffixes":[""]},"flag":"🇱🇺","flags":{"png":"https://flagcdn.com/w320/lu.png"},"independent":true},
|
||||
{"name":{"common":"Malta","official":"Republic of Malta"},"cca2":"MT","cca3":"MLT","region":"Europe","subregion":"Southern Europe","currencies":{"EUR":{"name":"Euro","symbol":"€"}},"idd":{"root":"+356","suffixes":[""]},"flag":"🇲🇹","flags":{"png":"https://flagcdn.com/w320/mt.png"},"independent":true},
|
||||
{"name":{"common":"Cyprus","official":"Republic of Cyprus"},"cca2":"CY","cca3":"CYP","region":"Europe","subregion":"Southern Europe","currencies":{"EUR":{"name":"Euro","symbol":"€"}},"idd":{"root":"+357","suffixes":[""]},"flag":"🇨🇾","flags":{"png":"https://flagcdn.com/w320/cy.png"},"independent":true},
|
||||
{"name":{"common":"Albania","official":"Republic of Albania"},"cca2":"AL","cca3":"ALB","region":"Europe","subregion":"Southeast Europe","currencies":{"ALL":{"name":"Albanian lek","symbol":"L"}},"idd":{"root":"+355","suffixes":[""]},"flag":"🇦🇱","flags":{"png":"https://flagcdn.com/w320/al.png"},"independent":true},
|
||||
{"name":{"common":"Serbia","official":"Republic of Serbia"},"cca2":"RS","cca3":"SRB","region":"Europe","subregion":"Southeast Europe","currencies":{"RSD":{"name":"Serbian dinar","symbol":"дин"}},"idd":{"root":"+381","suffixes":[""]},"flag":"🇷🇸","flags":{"png":"https://flagcdn.com/w320/rs.png"},"independent":true},
|
||||
{"name":{"common":"Belarus","official":"Republic of Belarus"},"cca2":"BY","cca3":"BLR","region":"Europe","subregion":"Eastern Europe","currencies":{"BYN":{"name":"Belarusian ruble","symbol":"Br"}},"idd":{"root":"+375","suffixes":[""]},"flag":"🇧🇾","flags":{"png":"https://flagcdn.com/w320/by.png"},"independent":true},
|
||||
{"name":{"common":"Kazakhstan","official":"Republic of Kazakhstan"},"cca2":"KZ","cca3":"KAZ","region":"Asia","subregion":"Central Asia","currencies":{"KZT":{"name":"Kazakhstani tenge","symbol":"₸"}},"idd":{"root":"+7","suffixes":[""]},"flag":"🇰🇿","flags":{"png":"https://flagcdn.com/w320/kz.png"},"independent":true},
|
||||
{"name":{"common":"Uzbekistan","official":"Republic of Uzbekistan"},"cca2":"UZ","cca3":"UZB","region":"Asia","subregion":"Central Asia","currencies":{"UZS":{"name":"Uzbekistani soʻm","symbol":"so'm"}},"idd":{"root":"+998","suffixes":[""]},"flag":"🇺🇿","flags":{"png":"https://flagcdn.com/w320/uz.png"},"independent":true},
|
||||
{"name":{"common":"Sri Lanka","official":"Democratic Socialist Republic of Sri Lanka"},"cca2":"LK","cca3":"LKA","region":"Asia","subregion":"Southern Asia","currencies":{"LKR":{"name":"Sri Lankan rupee","symbol":"Rs"}},"idd":{"root":"+94","suffixes":[""]},"flag":"🇱🇰","flags":{"png":"https://flagcdn.com/w320/lk.png"},"independent":true},
|
||||
{"name":{"common":"Cambodia","official":"Kingdom of Cambodia"},"cca2":"KH","cca3":"KHM","region":"Asia","subregion":"South-Eastern Asia","currencies":{"KHR":{"name":"Cambodian riel","symbol":"៛"}},"idd":{"root":"+855","suffixes":[""]},"flag":"🇰🇭","flags":{"png":"https://flagcdn.com/w320/kh.png"},"independent":true},
|
||||
{"name":{"common":"Myanmar","official":"Republic of the Union of Myanmar"},"cca2":"MM","cca3":"MMR","region":"Asia","subregion":"South-Eastern Asia","currencies":{"MMK":{"name":"Burmese kyat","symbol":"K"}},"idd":{"root":"+95","suffixes":[""]},"flag":"🇲🇲","flags":{"png":"https://flagcdn.com/w320/mm.png"},"independent":true},
|
||||
{"name":{"common":"Laos","official":"Lao People's Democratic Republic"},"cca2":"LA","cca3":"LAO","region":"Asia","subregion":"South-Eastern Asia","currencies":{"LAK":{"name":"Lao kip","symbol":"₭"}},"idd":{"root":"+856","suffixes":[""]},"flag":"🇱🇦","flags":{"png":"https://flagcdn.com/w320/la.png"},"independent":true},
|
||||
{"name":{"common":"Nepal","official":"Federal Democratic Republic of Nepal"},"cca2":"NP","cca3":"NPL","region":"Asia","subregion":"Southern Asia","currencies":{"NPR":{"name":"Nepalese rupee","symbol":"रू"}},"idd":{"root":"+977","suffixes":[""]},"flag":"🇳🇵","flags":{"png":"https://flagcdn.com/w320/np.png"},"independent":true},
|
||||
{"name":{"common":"Afghanistan","official":"Islamic Republic of Afghanistan"},"cca2":"AF","cca3":"AFG","region":"Asia","subregion":"Southern Asia","currencies":{"AFN":{"name":"Afghan afghani","symbol":"؋"}},"idd":{"root":"+93","suffixes":[""]},"flag":"🇦🇫","flags":{"png":"https://flagcdn.com/w320/af.png"},"independent":true},
|
||||
{"name":{"common":"Jordan","official":"Hashemite Kingdom of Jordan"},"cca2":"JO","cca3":"JOR","region":"Asia","subregion":"Western Asia","currencies":{"JOD":{"name":"Jordanian dinar","symbol":"د.ا"}},"idd":{"root":"+962","suffixes":[""]},"flag":"🇯🇴","flags":{"png":"https://flagcdn.com/w320/jo.png"},"independent":true},
|
||||
{"name":{"common":"Lebanon","official":"Lebanese Republic"},"cca2":"LB","cca3":"LBN","region":"Asia","subregion":"Western Asia","currencies":{"LBP":{"name":"Lebanese pound","symbol":"ل.ل"}},"idd":{"root":"+961","suffixes":[""]},"flag":"🇱🇧","flags":{"png":"https://flagcdn.com/w320/lb.png"},"independent":true},
|
||||
{"name":{"common":"Oman","official":"Sultanate of Oman"},"cca2":"OM","cca3":"OMN","region":"Asia","subregion":"Western Asia","currencies":{"OMR":{"name":"Omani rial","symbol":"ر.ع."}},"idd":{"root":"+968","suffixes":[""]},"flag":"🇴🇲","flags":{"png":"https://flagcdn.com/w320/om.png"},"independent":true},
|
||||
{"name":{"common":"Bahrain","official":"Kingdom of Bahrain"},"cca2":"BH","cca3":"BHR","region":"Asia","subregion":"Western Asia","currencies":{"BHD":{"name":"Bahraini dinar","symbol":"د.ب"}},"idd":{"root":"+973","suffixes":[""]},"flag":"🇧🇭","flags":{"png":"https://flagcdn.com/w320/bh.png"},"independent":true},
|
||||
{"name":{"common":"Algeria","official":"People's Democratic Republic of Algeria"},"cca2":"DZ","cca3":"DZA","region":"Africa","subregion":"Northern Africa","currencies":{"DZD":{"name":"Algerian dinar","symbol":"دج"}},"idd":{"root":"+213","suffixes":[""]},"flag":"🇩🇿","flags":{"png":"https://flagcdn.com/w320/dz.png"},"independent":true},
|
||||
{"name":{"common":"Tunisia","official":"Republic of Tunisia"},"cca2":"TN","cca3":"TUN","region":"Africa","subregion":"Northern Africa","currencies":{"TND":{"name":"Tunisian dinar","symbol":"د.ت"}},"idd":{"root":"+216","suffixes":[""]},"flag":"🇹🇳","flags":{"png":"https://flagcdn.com/w320/tn.png"},"independent":true},
|
||||
{"name":{"common":"Ghana","official":"Republic of Ghana"},"cca2":"GH","cca3":"GHA","region":"Africa","subregion":"Western Africa","currencies":{"GHS":{"name":"Ghanaian cedi","symbol":"₵"}},"idd":{"root":"+233","suffixes":[""]},"flag":"🇬🇭","flags":{"png":"https://flagcdn.com/w320/gh.png"},"independent":true},
|
||||
{"name":{"common":"Ethiopia","official":"Federal Democratic Republic of Ethiopia"},"cca2":"ET","cca3":"ETH","region":"Africa","subregion":"Eastern Africa","currencies":{"ETB":{"name":"Ethiopian birr","symbol":"Br"}},"idd":{"root":"+251","suffixes":[""]},"flag":"🇪🇹","flags":{"png":"https://flagcdn.com/w320/et.png"},"independent":true},
|
||||
{"name":{"common":"Tanzania","official":"United Republic of Tanzania"},"cca2":"TZ","cca3":"TZA","region":"Africa","subregion":"Eastern Africa","currencies":{"TZS":{"name":"Tanzanian shilling","symbol":"Sh"}},"idd":{"root":"+255","suffixes":[""]},"flag":"🇹🇿","flags":{"png":"https://flagcdn.com/w320/tz.png"},"independent":true},
|
||||
{"name":{"common":"Uganda","official":"Republic of Uganda"},"cca2":"UG","cca3":"UGA","region":"Africa","subregion":"Eastern Africa","currencies":{"UGX":{"name":"Ugandan shilling","symbol":"Sh"}},"idd":{"root":"+256","suffixes":[""]},"flag":"🇺🇬","flags":{"png":"https://flagcdn.com/w320/ug.png"},"independent":true},
|
||||
{"name":{"common":"Cameroon","official":"Republic of Cameroon"},"cca2":"CM","cca3":"CMR","region":"Africa","subregion":"Middle Africa","currencies":{"XAF":{"name":"Central African CFA franc","symbol":"FCFA"}},"idd":{"root":"+237","suffixes":[""]},"flag":"🇨🇲","flags":{"png":"https://flagcdn.com/w320/cm.png"},"independent":true},
|
||||
{"name":{"common":"Angola","official":"Republic of Angola"},"cca2":"AO","cca3":"AGO","region":"Africa","subregion":"Middle Africa","currencies":{"AOA":{"name":"Angolan kwanza","symbol":"Kz"}},"idd":{"root":"+244","suffixes":[""]},"flag":"🇦🇴","flags":{"png":"https://flagcdn.com/w320/ao.png"},"independent":true},
|
||||
{"name":{"common":"Senegal","official":"Republic of Senegal"},"cca2":"SN","cca3":"SEN","region":"Africa","subregion":"Western Africa","currencies":{"XOF":{"name":"West African CFA franc","symbol":"FCFA"}},"idd":{"root":"+221","suffixes":[""]},"flag":"🇸🇳","flags":{"png":"https://flagcdn.com/w320/sn.png"},"independent":true},
|
||||
{"name":{"common":"Zimbabwe","official":"Republic of Zimbabwe"},"cca2":"ZW","cca3":"ZWE","region":"Africa","subregion":"Eastern Africa","currencies":{"ZWL":{"name":"Zimbabwean dollar","symbol":"$"}},"idd":{"root":"+263","suffixes":[""]},"flag":"🇿🇼","flags":{"png":"https://flagcdn.com/w320/zw.png"},"independent":true},
|
||||
{"name":{"common":"Bolivia","official":"Plurinational State of Bolivia"},"cca2":"BO","cca3":"BOL","region":"Americas","subregion":"South America","currencies":{"BOB":{"name":"Bolivian boliviano","symbol":"Bs"}},"idd":{"root":"+591","suffixes":[""]},"flag":"🇧🇴","flags":{"png":"https://flagcdn.com/w320/bo.png"},"independent":true},
|
||||
{"name":{"common":"Ecuador","official":"Republic of Ecuador"},"cca2":"EC","cca3":"ECU","region":"Americas","subregion":"South America","currencies":{"USD":{"name":"United States dollar","symbol":"$"}},"idd":{"root":"+593","suffixes":[""]},"flag":"🇪🇨","flags":{"png":"https://flagcdn.com/w320/ec.png"},"independent":true},
|
||||
{"name":{"common":"Uruguay","official":"Oriental Republic of Uruguay"},"cca2":"UY","cca3":"URY","region":"Americas","subregion":"South America","currencies":{"UYU":{"name":"Uruguayan peso","symbol":"$"}},"idd":{"root":"+598","suffixes":[""]},"flag":"🇺🇾","flags":{"png":"https://flagcdn.com/w320/uy.png"},"independent":true},
|
||||
{"name":{"common":"Paraguay","official":"Republic of Paraguay"},"cca2":"PY","cca3":"PRY","region":"Americas","subregion":"South America","currencies":{"PYG":{"name":"Paraguayan guaraní","symbol":"₲"}},"idd":{"root":"+595","suffixes":[""]},"flag":"🇵🇾","flags":{"png":"https://flagcdn.com/w320/py.png"},"independent":true},
|
||||
{"name":{"common":"Venezuela","official":"Bolivarian Republic of Venezuela"},"cca2":"VE","cca3":"VEN","region":"Americas","subregion":"South America","currencies":{"VES":{"name":"Venezuelan bolívar soberano","symbol":"Bs.S"}},"idd":{"root":"+58","suffixes":[""]},"flag":"🇻🇪","flags":{"png":"https://flagcdn.com/w320/ve.png"},"independent":true},
|
||||
{"name":{"common":"Dominican Republic","official":"Dominican Republic"},"cca2":"DO","cca3":"DOM","region":"Americas","subregion":"Caribbean","currencies":{"DOP":{"name":"Dominican peso","symbol":"$"}},"idd":{"root":"+1","suffixes":["809"]},"flag":"🇩🇴","flags":{"png":"https://flagcdn.com/w320/do.png"},"independent":true},
|
||||
{"name":{"common":"Guatemala","official":"Republic of Guatemala"},"cca2":"GT","cca3":"GTM","region":"Americas","subregion":"Central America","currencies":{"GTQ":{"name":"Guatemalan quetzal","symbol":"Q"}},"idd":{"root":"+502","suffixes":[""]},"flag":"🇬🇹","flags":{"png":"https://flagcdn.com/w320/gt.png"},"independent":true},
|
||||
{"name":{"common":"Panama","official":"Republic of Panama"},"cca2":"PA","cca3":"PAN","region":"Americas","subregion":"Central America","currencies":{"USD":{"name":"United States dollar","symbol":"$"}},"idd":{"root":"+507","suffixes":[""]},"flag":"🇵🇦","flags":{"png":"https://flagcdn.com/w320/pa.png"},"independent":true},
|
||||
{"name":{"common":"Costa Rica","official":"Republic of Costa Rica"},"cca2":"CR","cca3":"CRI","region":"Americas","subregion":"Central America","currencies":{"CRC":{"name":"Costa Rican colón","symbol":"₡"}},"idd":{"root":"+506","suffixes":[""]},"flag":"🇨🇷","flags":{"png":"https://flagcdn.com/w320/cr.png"},"independent":true},
|
||||
{"name":{"common":"Vietnam","official":"Socialist Republic of Vietnam"},"cca2":"VN","cca3":"VNM","region":"Asia","subregion":"South-Eastern Asia","currencies":{"VND":{"name":"Vietnamese đồng","symbol":"₫"}},"idd":{"root":"+84","suffixes":[""]},"flag":"🇻🇳","flags":{"png":"https://flagcdn.com/w320/vn.png"},"independent":true}
|
||||
]
|
||||
@@ -0,0 +1,175 @@
|
||||
#错误消息
|
||||
not.null=* 必须填写
|
||||
user.jcaptcha.error=验证码错误
|
||||
user.jcaptcha.expire=验证码已失效
|
||||
user.not.exists=用户不存在/密码错误
|
||||
user.password.not.match=用户不存在/密码错误
|
||||
user.password.retry.limit.count=密码输入错误{0}次
|
||||
user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟
|
||||
user.password.delete=对不起,您的账号已被删除
|
||||
user.blocked=用户已封禁,请联系管理员
|
||||
role.blocked=角色已封禁,请联系管理员
|
||||
login.blocked=很遗憾,访问IP已被列入系统黑名单
|
||||
user.logout.success=退出成功
|
||||
|
||||
length.not.valid=长度必须在{min}到{max}个字符之间
|
||||
|
||||
user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头
|
||||
user.password.not.valid=* 5-50个字符
|
||||
|
||||
user.email.not.valid=邮箱格式错误
|
||||
user.mobile.phone.number.not.valid=手机号格式错误
|
||||
user.login.success=登录成功
|
||||
user.register.success=注册成功
|
||||
user.notfound=请重新登录
|
||||
user.forcelogout=管理员强制退出,请重新登录
|
||||
user.unknown.error=未知错误,请重新登录
|
||||
|
||||
##文件上传消息
|
||||
upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB!
|
||||
upload.filename.exceed.length=上传的文件名最长{0}个字符
|
||||
|
||||
##权限
|
||||
no.permission=您没有数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}]
|
||||
|
||||
##价格模块提示语(price)
|
||||
# 附加费 PrcSurcharge
|
||||
price.surcharge.scName.empty=附加费名称不能为空
|
||||
price.surcharge.chargeType.empty=计费方式不能为空
|
||||
price.surcharge.chargeValue.empty=计费数值不能为空
|
||||
price.surcharge.chargeValue.negative=计费数值不能为负数
|
||||
# 附加费关联 PrcSurchargeRel
|
||||
price.surchargeRel.scId.empty=附加费ID不能为空
|
||||
price.surchargeRel.productId.empty=产品ID不能为空
|
||||
price.surchargeRel.productCode.empty=产品代码不能为空
|
||||
# 套餐 PrcPriceSet
|
||||
price.set.notExists=套餐不存在
|
||||
price.set.name.empty=套餐名称不能为空
|
||||
price.set.name.exists=套餐名称已存在
|
||||
price.set.effectiveDate.empty=生效日期不能为空
|
||||
price.set.date.invalid=生效日期不能晚于失效日期
|
||||
price.set.discount.range=折扣模式默认折扣需在 1~99
|
||||
price.set.delete.statusNotAllowed=仅待启用或驳回状态的套餐允许删除:{0}
|
||||
price.set.delete.boundCustomer=套餐【{0}】已绑定客户,请先解绑后再删除
|
||||
price.set.submit.statusNotAllowed=当前状态不允许提交审核
|
||||
price.set.approve.statusNotAllowed=仅审核中的套餐可以生效
|
||||
price.set.reject.statusNotAllowed=仅审核中的套餐可以驳回
|
||||
price.set.disable.statusNotAllowed=仅生效中的套餐可停用
|
||||
price.set.enable.statusNotAllowed=套餐已是生效状态
|
||||
price.set.edit.audit=审核中的套餐不允许修改
|
||||
price.set.edit.stopped=已停用的套餐不允许修改,请使用复用新建
|
||||
price.set.childEdit.audit=审核中的套餐不允许改明细或客户
|
||||
price.set.childEdit.stopped=已停用的套餐不允许改明细或客户
|
||||
price.set.detail.notExists=套餐明细不存在
|
||||
price.set.detail.productCode.empty=明细产品代码不能为空
|
||||
price.set.detail.country.empty=固定价明细必须填写国家
|
||||
price.set.detail.weight.empty=固定价明细必须填写重量段
|
||||
price.set.detail.freight.empty=固定价明细必须填写运费单价
|
||||
price.set.detail.registration.empty=固定价明细必须填写挂号费
|
||||
price.set.detail.zone.empty=固定价明细必须选择分区
|
||||
price.set.detail.roundMode.invalid=取值方式仅支持 UP / DOWN / HALF_UP
|
||||
price.set.detail.freight.belowBase=套餐运费不能低于导入基准价 {0}
|
||||
price.set.detail.registration.belowBase=套餐挂号费不能低于导入基准价 {0}
|
||||
price.set.customer.notExists=客户绑定不存在
|
||||
price.set.customer.unbindAudit=审核中的套餐不允许解绑客户
|
||||
price.set.customer.customerId.empty=客户ID不能为空
|
||||
price.set.customer.beginDate.empty=客户绑定生效日期不能为空
|
||||
price.set.customer.date.invalid=客户绑定生效日期不能晚于失效日期
|
||||
price.set.customer.alreadyBound=该客户已绑定套餐,一个客户只能绑定一个套餐
|
||||
price.set.customer.masterNotFound=客户主数据不存在
|
||||
price.set.customer.priority.invalid=优先级必须大于等于 1
|
||||
# 重量段 PrcWeight
|
||||
price.weight.range.empty=起始重量和结束重量不能为空
|
||||
price.weight.range.invalid=起始重量必须小于结束重量
|
||||
# Zone PrcZone (country -> zone -> postcode)
|
||||
price.zone.import.fileEmpty=上传文件不能为空
|
||||
price.zone.import.fileType=仅支持 xls / xlsx 文件
|
||||
price.zone.import.noSheet=未找到可导入的分区 sheet(澳大利亚分区/加拿大偏远附加费/法国MR邮编/日本附加费/英国附加费)
|
||||
price.zone.import.noData=分区 sheet 无有效邮编/分区数据
|
||||
price.zone.import.success=导入成功:{0} 个国家,{1} 个分区,{2} 条邮编明细({3})
|
||||
price.zone.import.unmatched=;未匹配国家已跳过:{0}
|
||||
price.zone.import.regionNotFound=未在 bms_region 匹配到国家:{0}
|
||||
price.zone.import.regionEmpty=bms_region 无可用国家数据,请先同步/维护国家表
|
||||
price.zone.region.notFound=国家不存在或已删除
|
||||
price.zone.region.required=请选择国家(bms_region)
|
||||
price.zone.countryCode.empty=国家编码不能为空,请检查 bms_region.country_code_2
|
||||
# 产品导入 BmsProduct
|
||||
price.product.codeDate.exists=同一产品代码与生效日期已存在,不能覆盖历史数据
|
||||
price.product.effectiveDate.empty=生效日期不能为空
|
||||
price.product.import.effEmpty=缺少生效日期,已跳过
|
||||
price.product.import.fileEmpty=上传文件不能为空
|
||||
price.product.import.fileType=仅支持 xls / xlsx 文件
|
||||
price.product.import.sheetNotFound=未找到「产品目录」sheet,请上传威狮B2C小包价表格格式文件
|
||||
price.product.import.noData=产品目录无有效数据行
|
||||
price.product.import.regionEmpty=bms_region 无可用国家数据,请先同步/维护国家表后再导入
|
||||
price.product.import.partialFail=导入完成但存在失败项:新增 {0},跳过 {1};失败明细:{2}
|
||||
price.product.import.effTooEarly=生效日期 {0} 早于当前开放版 {1},请使用更晚的生效日期导入
|
||||
price.product.import.needFeeAlter=请先执行 SQL:bms-back/sql/price/product_country_fee_alter.sql(缺少运费/挂号费字段)
|
||||
price.product.import.needExpireAlter=请先执行 SQL:bms-back/sql/price/product_country_expire_alter.sql(缺少失效日期/版本唯一键)
|
||||
price.product.import.needCodeEffUnique=无法新增「同代码、不同生效日」的产品。请先执行 SQL:bms-back/sql/price/product_code_eff_unique_alter.sql(去掉 product_code 单列唯一,改为代码+生效日唯一)
|
||||
price.product.import.success=导入成功:新增 {0} 个产品,跳过 {1} 个(同代码同生效日不覆盖);写入国家/重量段明细 {2} 行。
|
||||
price.product.import.success.detail1=产品主数据按「产品代码+生效日期」新增,不覆盖已有记录。国家明细:新生效日晚于上次则保留历史,上次失效日=本次生效日。
|
||||
price.product.import.success.detail2=范围:产品目录 + 重量段 + 运费/挂号费 + 尺寸/尾程/时效;国家码来自 bms_region。
|
||||
price.product.import.noSheet=未找到产品明细sheet(需与产品名称一致):{0}
|
||||
price.product.import.noCountry=产品明细sheet无有效国家/重量段数据:{0}
|
||||
price.product.import.euEmpty=国家表无欧盟成员(is_eu=1),无法展开「欧盟」
|
||||
price.product.import.success.unmatched=未匹配国家表(country_code 为空):{0}
|
||||
price.product.import.countryRequired=请选择目的国家
|
||||
price.product.import.countryNotFound=国家不存在或已停用:{0}
|
||||
price.product.import.countrySheetNotFound=未找到「产品目录」sheet,请上传单国专线成本价表
|
||||
price.product.import.countryNoPrice=未找到该产品的重量段价格:{0}
|
||||
price.product.import.countrySuccess=按国家导入成功({0}):新增 {1} 个产品,跳过 {2} 个(同代码同生效日不覆盖主数据);写入重量段 {3} 行。
|
||||
# 报价试算 TmsPriceQuote(对外 TMS API 错误码,保持英文契约)
|
||||
price.quote.postcodeRequired=该国家/产品有分区,请填写目的邮编
|
||||
price.quote.postcodeZoneNotFound=邮编未匹配到分区,请核对目的邮编
|
||||
price.quote.zonePriceNotHit=已匹配分区,但该分区无对应产品重量段价格
|
||||
price.quote.priceNotHit=没有产品/国家/重量段绑定,暂无价格
|
||||
price.quote.freightMissing1=产品默认运费为空
|
||||
price.quote.freightMissing2=产品默认运费或挂号费为空
|
||||
price.quote.freightMissing3=运费为空
|
||||
price.quote.requestBodyRequired=请求体为空
|
||||
price.quote.customerIdRequired=客户ID为空
|
||||
price.quote.customerCodeRequired=客户代码不能为空
|
||||
price.quote.customerCodeNotFound=客户代码不存在
|
||||
price.quote.customerDisabled=客户已停用,不可计费
|
||||
price.quote.productCodeRequired=产品代码为空
|
||||
price.quote.countryRequired=国家代码或国家名称为空
|
||||
price.quote.weightInvalid=重量必须大于0
|
||||
price.quote.bizDateInvalid=业务日期格式必须为yyyy-MM-dd
|
||||
price.quote.fixedPackageNoDetails=套餐固定价格没有明细,使用产品默认价格
|
||||
price.quote.noCustomerPackageOverride=没有客户套餐覆盖,使用产品默认运费/挂号费
|
||||
price.quote.noCustomerPackage=客户未绑定套餐,无法试算
|
||||
price.quote.quoteIdRequired=报价ID为空
|
||||
price.quote.hitCustomerFixedPackageDetail=命中客户套餐固定价格明细
|
||||
|
||||
# receivable bill
|
||||
price.bill.orderNoRequired=订单号为空
|
||||
price.bill.billIdRequired=计费ID为空
|
||||
price.bill.notFound=计费记录不存在
|
||||
price.bill.customerRequired=订单同步缺少有效客户
|
||||
price.bill.alreadyInArBill=订单{0}已生成应收账单,作废后方可重新计费
|
||||
price.bill.bizDateRequired=业务日期为空
|
||||
price.bill.noCustomerPackage=客户未绑定套餐,无法计费
|
||||
price.bill.fee.scIdRequired=附加费不能为空
|
||||
price.bill.fee.surchargeNotFound=附加费配置不存在或已停用
|
||||
price.bill.fee.notFound=费用明细不存在
|
||||
price.bill.fee.notManual=仅手动增加的费用可编辑或删除
|
||||
price.bill.fee.alreadyBilled=费用已生成账单,不可编辑或删除
|
||||
price.bill.fee.idRequired=费用ID不能为空
|
||||
|
||||
price.set.version.effectiveTime.empty=版本生效时间不能为空
|
||||
price.set.version.notExists=套餐版本不存在
|
||||
price.set.version.activate.statusNotAllowed=仅草稿或待生效版本可设置生效时间
|
||||
price.set.version.delete.statusNotAllowed=仅草稿版本可删除
|
||||
price.set.version.copy.draftExists=已有草稿版本,请先启动或删除后再复制
|
||||
price.set.save.task.notExists=保存任务不存在或已过期
|
||||
price.set.library.empty=产品库无可用价格明细,请检查产品国家配置
|
||||
price.set.detail.duplicate.fixed=产品{0} 国家{1} 重量段{2} {3}(共{4}条)
|
||||
price.set.detail.duplicate.discount=产品{0}(共{1}条)
|
||||
price.set.detail.duplicate.hasZone=有分区({0})
|
||||
price.set.detail.duplicate.noZone=无分区
|
||||
@@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<!-- 日志存放路径 -->
|
||||
<property name="log.path" value="${user.dir}/logs" />
|
||||
<!-- 日志输出格式 -->
|
||||
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
||||
|
||||
<!-- 控制台输出 -->
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 系统日志输出 -->
|
||||
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/sys-info.log</file>
|
||||
<!-- 循环政策:基于时间创建日志文件 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 日志文件名格式 -->
|
||||
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大的历史 60天 -->
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<!-- 过滤的级别 -->
|
||||
<level>INFO</level>
|
||||
<!-- 匹配时的操作:接收(记录) -->
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/sys-error.log</file>
|
||||
<!-- 循环政策:基于时间创建日志文件 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 日志文件名格式 -->
|
||||
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大的历史 60天 -->
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<!-- 过滤的级别 -->
|
||||
<level>ERROR</level>
|
||||
<!-- 匹配时的操作:接收(记录) -->
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!-- 用户访问日志输出 -->
|
||||
<appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/sys-user.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 按天回滚 daily -->
|
||||
<fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大的历史 60天 -->
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 系统模块日志级别控制 -->
|
||||
<logger name="com.bms" level="info" />
|
||||
<!-- Spring日志级别控制 -->
|
||||
<logger name="org.springframework" level="warn" />
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
<!--系统操作日志-->
|
||||
<root level="info">
|
||||
<appender-ref ref="file_info" />
|
||||
<appender-ref ref="file_error" />
|
||||
</root>
|
||||
|
||||
<!--系统用户操作日志-->
|
||||
<logger name="sys-user" level="info">
|
||||
<appender-ref ref="sys-user"/>
|
||||
</logger>
|
||||
</configuration>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE configuration
|
||||
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-config.dtd">
|
||||
<configuration>
|
||||
<!-- 全局参数 -->
|
||||
<settings>
|
||||
<!-- 使全局的映射器启用或禁用缓存 -->
|
||||
<setting name="cacheEnabled" value="true" />
|
||||
<!-- 允许JDBC 支持自动生成主键 -->
|
||||
<setting name="useGeneratedKeys" value="true" />
|
||||
<!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
|
||||
<setting name="defaultExecutorType" value="SIMPLE" />
|
||||
<!-- 指定 MyBatis 所用日志的具体实现 -->
|
||||
<setting name="logImpl" value="SLF4J" />
|
||||
<!-- 使用驼峰命名法转换字段 -->
|
||||
<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
|
||||
</settings>
|
||||
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user