Compare commits

...

3 Commits

@ -6,12 +6,6 @@ import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.ruoyi.system.domain.RecordWarehousing;
import com.ruoyi.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@ -157,14 +151,15 @@ public class SysIndexController extends BaseController
{
Map map =new HashMap();
//查询库存、在用轮胎数量、车辆数量
int n = iBaseInventoryService.querytotal();
int m = iBaseInventoryService.queryInCar();
int k = iBaseInventoryService.queryCarTotal();
Map tireTypeTotal = iBaseInventoryService.querytotal();
List<Map> mapList = iRecordWarehousingService.selectRecord();
map.put("InventoryTotal",n);
map.put("TyreInCar",m);
map.put("CarTotal",k);
//规格占比
List<Map> mapListTyreModel = iRecordWarehousingService.selectTyreModel();
//新胎装车统计
List<Map> mapListInstall = iRecordWarehousingService.selectTyreInstall();
map.put("mapListInstall",mapListInstall);
map.put("mapListTyreModel",mapListTyreModel);
map.put("tireTypeTotal",tireTypeTotal);
map.put("mapList",mapList);
return AjaxResult.success(map);
}

@ -150,10 +150,10 @@ public class BaseCarController extends BaseController
}
@PostMapping("/PdaQueryCarList")
@ResponseBody
public List<BaseCar> PdaQueryCarList(BaseCar baseCar)
public AjaxResult PdaQueryCarList(BaseCar baseCar)
{
List<BaseCar> list = baseCarService.selectBaseCarList(baseCar);
return list;
return AjaxResult.success(list);
}
@PostMapping("/PdaBingCarRfid")

@ -123,6 +123,7 @@ public class BaseInventoryController extends BaseController
return toAjax(baseInventoryService.deleteBaseInventoryByIds(ids));
}
@Log(title = "手持添加库存", businessType = BusinessType.INSERT)
@PostMapping("/pdaAddInventory")
@ResponseBody
public AjaxResult pdaAddInventory(BaseInventory baseInventory, BaseTyre baseTyre)

@ -1,388 +1,145 @@
package com.ruoyi.web.controller.tyre;
import java.util.List;
import java.util.stream.Collectors;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.file.MimeTypeUtils;
import com.ruoyi.common.utils.uuid.Seq;
import com.ruoyi.system.domain.BaseCar;
import com.ruoyi.system.service.IBaseCarService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
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.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.common.config.ServerConfig;
import com.ruoyi.system.domain.BizMaintenanceOrder;
import com.ruoyi.system.domain.BizOrderTireDetail;
import com.ruoyi.system.domain.SysAttachment;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.system.service.IBizMaintenanceOrderService;
import com.ruoyi.system.service.IBizOrderTireDetailService;
import com.ruoyi.system.service.ISysAttachmentService;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* Controller
*
* @author yangwanli
* @date 2026-04-15
* Controller
*
* @author yangwl
* @date 2026-04-16
*/
@Controller
@RequestMapping("/tyre/order")
public class BizMaintenanceOrderController extends BaseController {
public class BizMaintenanceOrderController extends BaseController
{
private String prefix = "tyre/order";
@Autowired
private IBizMaintenanceOrderService bizMaintenanceOrderService;
@Autowired
private ISysAttachmentService sysAttachmentService;
@Autowired
private ISysDeptService deptService;
@Autowired
private IBaseCarService baseCarService;
@Autowired
private IBizOrderTireDetailService tireDetailService;
@Autowired
private ServerConfig serverConfig;
@RequiresPermissions("system:order:view")
@GetMapping()
public String order() {
public String order()
{
return prefix + "/order";
}
/**
*
*
*/
@RequiresPermissions("system:order:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(BizMaintenanceOrder bizMaintenanceOrder) {
public TableDataInfo list(BizMaintenanceOrder bizMaintenanceOrder)
{
startPage();
List<BizMaintenanceOrder> list = bizMaintenanceOrderService.selectBizRepairOrderList(bizMaintenanceOrder);
List<BizMaintenanceOrder> list = bizMaintenanceOrderService.selectBizMaintenanceOrderList(bizMaintenanceOrder);
return getDataTable(list);
}
/**
*
*
*/
@RequiresPermissions("system:order:list")
@PostMapping("/listMaintenanceOrder")
@ResponseBody
public TableDataInfo listMaintenanceOrder(BizMaintenanceOrder bizMaintenanceOrder)
{
startPage();
List<BizMaintenanceOrder> list = bizMaintenanceOrderService.selectBizMaintenanceOrderListTwo(bizMaintenanceOrder);
return getDataTable(list);
}
/**
*
*/
@RequiresPermissions("system:order:export")
@Log(title = "维保工单主表", businessType = BusinessType.EXPORT)
@Log(title = "维保工单", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(BizMaintenanceOrder bizMaintenanceOrder) {
public AjaxResult export(BizMaintenanceOrder bizMaintenanceOrder)
{
List<BizMaintenanceOrder> list = bizMaintenanceOrderService.selectBizMaintenanceOrderList(bizMaintenanceOrder);
ExcelUtil<BizMaintenanceOrder> util = new ExcelUtil<BizMaintenanceOrder>(BizMaintenanceOrder.class);
return util.exportExcel(list, "维保工单数据");
}
/**
*
*
*/
@RequiresPermissions("system:order:add")
@GetMapping("/add")
public String add(ModelMap mmap) {
BizMaintenanceOrder bizMaintenanceOrder = new BizMaintenanceOrder();
bizMaintenanceOrder.setOrderType("1"); // 汽车类型
mmap.put("bizMaintenanceOrder", bizMaintenanceOrder);
public String add()
{
return prefix + "/add";
}
/**
*
*
*/
@RequiresPermissions("system:order:add")
@Log(title = "维保工单主表", businessType = BusinessType.INSERT)
@Log(title = "维保工单", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(BizMaintenanceOrder bizMaintenanceOrder) {
public AjaxResult addSave(BizMaintenanceOrder bizMaintenanceOrder)
{
return toAjax(bizMaintenanceOrderService.insertBizMaintenanceOrder(bizMaintenanceOrder));
}
/**
*
*
*/
@RequiresPermissions("system:order:edit")
@GetMapping("/edit/{orderId}")
public String edit(@PathVariable("orderId") Long orderId, ModelMap mmap) {
BizMaintenanceOrder bizMaintenanceOrder = bizMaintenanceOrderService.selectBizMaintenanceOrderById(orderId);
// 查询工单关联的附件(图片)
List<SysAttachment> attachments = sysAttachmentService.selectAttachmentsByOrderId(orderId);
public String edit(@PathVariable("orderId") Long orderId, ModelMap mmap)
{
BizMaintenanceOrder bizMaintenanceOrder = bizMaintenanceOrderService.selectBizMaintenanceOrderByOrderId(orderId);
mmap.put("bizMaintenanceOrder", bizMaintenanceOrder);
mmap.put("attachments", attachments);
return prefix + "/edit";
}
/**
*
*
*/
@RequiresPermissions("system:order:edit")
@Log(title = "维保工单主表", businessType = BusinessType.UPDATE)
@Log(title = "维保工单", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(BizMaintenanceOrder bizMaintenanceOrder, String attachmentUrls) {
// 更新工单
int result = bizMaintenanceOrderService.updateBizMaintenanceOrder(bizMaintenanceOrder);
if (result > 0 && bizMaintenanceOrder.getOrderId() != null) {
// 先删除该工单的所有附件记录
sysAttachmentService.deleteAttachmentsByOrderId(bizMaintenanceOrder.getOrderId());
// 重新插入新的附件记录
if (attachmentUrls != null && !attachmentUrls.trim().isEmpty()) {
String[] urls = attachmentUrls.split(",");
for (String url : urls) {
if (url != null && !url.trim().isEmpty()) {
SysAttachment attachment = new SysAttachment();
String fileName = url.substring(url.lastIndexOf("/") + 1);
attachment.setFileName(fileName);
attachment.setFilePath(url);
attachment.setOrderId(bizMaintenanceOrder.getOrderId());
attachment.setUploadBy(ShiroUtils.getLoginName());
sysAttachmentService.insertSysAttachment(attachment);
}
}
}
}
return toAjax(result);
public AjaxResult editSave(BizMaintenanceOrder bizMaintenanceOrder)
{
return toAjax(bizMaintenanceOrderService.updateBizMaintenanceOrder(bizMaintenanceOrder));
}
/**
*
*
*/
@RequiresPermissions("system:order:remove")
@Log(title = "维保工单主表", businessType = BusinessType.DELETE)
@PostMapping("/remove")
@Log(title = "维保工单", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids) {
return toAjax(bizMaintenanceOrderService.deleteBizMaintenanceOrderByIds(ids));
public AjaxResult remove(String ids)
{
return toAjax(bizMaintenanceOrderService.deleteBizMaintenanceOrderByOrderIds(ids));
}
/**
*
*/
@RequiresPermissions("system:order:view")
@GetMapping("/detail/{orderId}")
public String detail(@PathVariable("orderId") Long orderId, ModelMap mmap) {
BizMaintenanceOrder bizMaintenanceOrder = bizMaintenanceOrderService.selectBizMaintenanceOrderById(orderId);
// 查询工单关联的附件(图片)
List<SysAttachment> attachments = sysAttachmentService.selectAttachmentsByOrderId(orderId);
// 查询工单关联的轮胎明细
List<BizOrderTireDetail> tireDetails = tireDetailService.selectTireDetailByOrderId(orderId);
mmap.put("bizMaintenanceOrder", bizMaintenanceOrder);
mmap.put("attachments", attachments);
mmap.put("tireDetails", tireDetails);
return prefix + "/detail";
}
/**
*
*/
@PostMapping("/queryByPlate")
@PostMapping("/PDAGetMaintenanceOrder")
@ResponseBody
public AjaxResult queryByPlate(String plateNumber) {
List<BizMaintenanceOrder> list = bizMaintenanceOrderService.selectOrderByPlateNumber(plateNumber);
public AjaxResult PDAGetMaintenanceOrder(@RequestBody BizMaintenanceOrder bizMaintenanceOrder)
{
List<BizMaintenanceOrder> list = bizMaintenanceOrderService.selectBizMaintenanceOrderList(bizMaintenanceOrder);
return AjaxResult.success(list);
}
/**
*
*/
@PostMapping("/queryByTireCode")
@ResponseBody
public AjaxResult queryByTireCode(String tireCode) {
List<BizMaintenanceOrder> list = bizMaintenanceOrderService.selectOrderByTireCode(tireCode);
return AjaxResult.success(list);
}
/**
*
*/
@RequiresPermissions("system:order:edit")
@PostMapping("/updateStatus")
@ResponseBody
public AjaxResult updateStatus(Long orderId, String status) {
int result = bizMaintenanceOrderService.updateOrderStatus(orderId, status);
return toAjax(result);
}
/**
*
*/
@RequiresPermissions("system:order:submit")
@GetMapping("/submit")
public String submit(ModelMap mmap) {
BizMaintenanceOrder bizMaintenanceOrder = new BizMaintenanceOrder();
bizMaintenanceOrder.setOrderType("1"); // 汽车类型
bizMaintenanceOrder.setStatus("UNSTARTED"); // 未开始状态
mmap.put("bizMaintenanceOrder", bizMaintenanceOrder);
mmap.put("depts", deptService.selectDeptList(new SysDept()));
mmap.put("cars", baseCarService.selectBaseCarList(new BaseCar()));
return prefix + "/submit";
}
/**
*
*/
@RequiresPermissions("system:order:submit")
@Log(title = "提交工单", businessType = BusinessType.INSERT)
@PostMapping("/submit")
@ResponseBody
public AjaxResult submitSave(BizMaintenanceOrder bizMaintenanceOrder, String attachmentUrls) {
// 设置创建人
bizMaintenanceOrder.setCreateBy(ShiroUtils.getLoginName());
bizMaintenanceOrder.setOrderNo(Seq.getId(Seq.orderSeqType));
// 设置工单类型为汽车类型
bizMaintenanceOrder.setOrderType("1");
// 插入工单
int result = bizMaintenanceOrderService.insertBizMaintenanceOrder(bizMaintenanceOrder);
if (result > 0 && bizMaintenanceOrder.getOrderId() != null && attachmentUrls != null && !attachmentUrls.trim().isEmpty()) {
// 处理图片上传
String[] urls = attachmentUrls.split(",");
for (String url : urls) {
if (url != null && !url.trim().isEmpty()) {
SysAttachment attachment = new SysAttachment();
// 提取文件名
String fileName = url.substring(url.lastIndexOf("/") + 1);
attachment.setFileName(fileName);
attachment.setFilePath(url);
attachment.setOrderId(bizMaintenanceOrder.getOrderId());
attachment.setUploadBy(ShiroUtils.getLoginName());
sysAttachmentService.insertSysAttachment(attachment);
}
}
}
return toAjax(result);
}
/**
* WebUploader
*/
@Log(title = "上传工单图片", businessType = BusinessType.OTHER)
@PostMapping("/uploadImage")
@ResponseBody
public AjaxResult uploadImage(MultipartFile file) {
try {
String imagePath = FileUploadUtils.upload(RuoYiConfig.getUploadPath(), file, MimeTypeUtils.IMAGE_EXTENSION, true);
// 上传路径
// String uploadPath = RuoYiConfig.getUploadPath();
// // 上传并返回新文件名称
// String fileName = FileUploadUtils.upload(uploadPath, file);
// String url = serverConfig.getUrl() + fileName;
// WebUploader要求的返回格式
AjaxResult ajax = AjaxResult.success();
ajax.put("url", imagePath);
ajax.put("fileName", imagePath);
ajax.put("code", 0);
ajax.put("msg", "上传成功");
return ajax;
} catch (Exception e) {
AjaxResult ajax = AjaxResult.error("图片上传失败: " + e.getMessage());
ajax.put("code", 1);
return ajax;
}
}
/**
*
*/
@Log(title = "删除工单图片", businessType = BusinessType.DELETE)
@PostMapping("/deleteImage")
@ResponseBody
public AjaxResult deleteImage(String filePath) {
try {
// 从完整URL中提取文件名
String fileName = StringUtils.substringAfterLast(filePath, "/");
if (StringUtils.isNotEmpty(fileName)) {
// 构建完整文件路径
String fullPath = RuoYiConfig.getUploadPath() + StringUtils.substringAfter(filePath, Constants.RESOURCE_PREFIX);
FileUtils.deleteFile(fullPath);
return AjaxResult.success("图片删除成功");
}
return AjaxResult.error("文件路径无效");
} catch (Exception e) {
return AjaxResult.error("图片删除失败: " + e.getMessage());
}
}
/**
*
*/
@GetMapping("/getOrderImages")
@ResponseBody
public AjaxResult getOrderImages(Long orderId) {
List<SysAttachment> attachments = sysAttachmentService.selectAttachmentsByOrderId(orderId);
return AjaxResult.success(attachments);
}
/**
*
*/
@GetMapping("/getFactoryList")
@ResponseBody
public AjaxResult getFactoryList() {
// 获取部门列表
SysDept queryDept = new SysDept();
queryDept.setParentId(227L);
List<SysDept> deptList = deptService.selectDeptList(queryDept);
return AjaxResult.success(deptList);
}
/**
*
*/
@GetMapping("/getCarList")
@ResponseBody
public AjaxResult getCarList() {
// 获取部门列表
List<BaseCar> carList = baseCarService.selectBaseCarList(new BaseCar());
return AjaxResult.success(carList);
}
@RequiresPermissions("system:order:scrapView")
@GetMapping("/scrapOrder")
public String scrapOrder() {
return prefix + "/scrapOrder";
}
/**
*
*/
@RequiresPermissions("system:order:scrapList")
@PostMapping("/listScrap")
@ResponseBody
public TableDataInfo listScrap(BizMaintenanceOrder bizMaintenanceOrder) {
startPage();
List<BizMaintenanceOrder> list = bizMaintenanceOrderService.selectBizScrapOrderList(bizMaintenanceOrder);
return getDataTable(list);
}
}
}

@ -3,6 +3,9 @@ package com.ruoyi.web.controller.tyre;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import com.ruoyi.system.domain.BizMaintenanceOrder;
import com.ruoyi.system.service.IBizMaintenanceOrderService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@ -12,13 +15,7 @@ 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.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.TireMaintenance;
import com.ruoyi.system.service.ITireMaintenanceService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
/**
@ -34,7 +31,7 @@ public class TireMaintenanceController extends BaseController
private String prefix = "tyre/maintenance";
@Autowired
private ITireMaintenanceService tireMaintenanceService;
private IBizMaintenanceOrderService bizMaintenanceOrderService;
@RequiresPermissions("system:maintenance:view")
@GetMapping()
@ -49,94 +46,82 @@ public class TireMaintenanceController extends BaseController
@RequiresPermissions("system:maintenance:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(TireMaintenance tireMaintenance)
public TableDataInfo list(BizMaintenanceOrder bizMaintenanceOrder)
{
startPage();
// --- 模拟数据开始 (实际开发请调用 service.selectTireMaintenanceList(maintenance)) ---
List<TireMaintenance> mockList = new ArrayList<>();
TireMaintenance t1 = new TireMaintenance();
t1.setId(1L); t1.setPlateNumber("粤B-12345"); t1.setMaintType("二级保养");
t1.setMaintStation("南山修理厂"); t1.setMaintDate(java.sql.Date.valueOf("2026-04-09"));
t1.setMileage(new BigDecimal(50000)); t1.setStatus("0"); t1.setProject("常规检查");
mockList.add(t1);
TireMaintenance t2 = new TireMaintenance();
t2.setId(2L); t2.setPlateNumber("粤B-67890"); t2.setMaintType("抢碎修");
t2.setMaintStation("福田快修"); t2.setMaintDate(java.sql.Date.valueOf("2026-04-08"));
t2.setMileage(new BigDecimal(42000)); t2.setStatus("1"); t2.setProject("轮胎修补");
mockList.add(t2);
return getDataTable(mockList);
List<BizMaintenanceOrder> list = bizMaintenanceOrderService.selectBizMaintenanceOrderList(bizMaintenanceOrder);
return getDataTable(list);
}
/**
*
*/
@RequiresPermissions("system:maintenance:export")
@Log(title = "车辆维保记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(TireMaintenance tireMaintenance)
{
List<TireMaintenance> list = tireMaintenanceService.selectTireMaintenanceList(tireMaintenance);
ExcelUtil<TireMaintenance> util = new ExcelUtil<TireMaintenance>(TireMaintenance.class);
return util.exportExcel(list, "车辆维保记录数据");
}
/**
*
*/
@RequiresPermissions("system:maintenance:add")
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
*
*/
@RequiresPermissions("system:maintenance:add")
@Log(title = "车辆维保记录", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(TireMaintenance tireMaintenance)
{
return toAjax(tireMaintenanceService.insertTireMaintenance(tireMaintenance));
}
/**
*
*/
@RequiresPermissions("system:maintenance:edit")
@GetMapping("/edit/{id}")
public String edit(@PathVariable("id") Long id, ModelMap mmap)
{
TireMaintenance tireMaintenance = tireMaintenanceService.selectTireMaintenanceById(id);
mmap.put("tireMaintenance", tireMaintenance);
return prefix + "/edit";
}
/**
*
*/
@RequiresPermissions("system:maintenance:edit")
@Log(title = "车辆维保记录", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(TireMaintenance tireMaintenance)
{
return toAjax(tireMaintenanceService.updateTireMaintenance(tireMaintenance));
}
/**
*
*/
@RequiresPermissions("system:maintenance:remove")
@Log(title = "车辆维保记录", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(tireMaintenanceService.deleteTireMaintenanceByIds(ids));
}
// /**
// * 导出车辆维保记录列表
// */
// @RequiresPermissions("system:maintenance:export")
// @Log(title = "车辆维保记录", businessType = BusinessType.EXPORT)
// @PostMapping("/export")
// @ResponseBody
// public AjaxResult export(TireMaintenance tireMaintenance)
// {
// List<TireMaintenance> list = tireMaintenanceService.selectTireMaintenanceList(tireMaintenance);
// ExcelUtil<TireMaintenance> util = new ExcelUtil<TireMaintenance>(TireMaintenance.class);
// return util.exportExcel(list, "车辆维保记录数据");
// }
//
// /**
// * 新增车辆维保记录
// */
// @RequiresPermissions("system:maintenance:add")
// @GetMapping("/add")
// public String add()
// {
// return prefix + "/add";
// }
//
// /**
// * 新增保存车辆维保记录
// */
// @RequiresPermissions("system:maintenance:add")
// @Log(title = "车辆维保记录", businessType = BusinessType.INSERT)
// @PostMapping("/add")
// @ResponseBody
// public AjaxResult addSave(TireMaintenance tireMaintenance)
// {
// return toAjax(tireMaintenanceService.insertTireMaintenance(tireMaintenance));
// }
//
// /**
// * 修改车辆维保记录
// */
// @RequiresPermissions("system:maintenance:edit")
// @GetMapping("/edit/{id}")
// public String edit(@PathVariable("id") Long id, ModelMap mmap)
// {
// TireMaintenance tireMaintenance = tireMaintenanceService.selectTireMaintenanceById(id);
// mmap.put("tireMaintenance", tireMaintenance);
// return prefix + "/edit";
// }
//
// /**
// * 修改保存车辆维保记录
// */
// @RequiresPermissions("system:maintenance:edit")
// @Log(title = "车辆维保记录", businessType = BusinessType.UPDATE)
// @PostMapping("/edit")
// @ResponseBody
// public AjaxResult editSave(TireMaintenance tireMaintenance)
// {
// return toAjax(tireMaintenanceService.updateTireMaintenance(tireMaintenance));
// }
//
// /**
// * 删除车辆维保记录
// */
// @RequiresPermissions("system:maintenance:remove")
// @Log(title = "车辆维保记录", businessType = BusinessType.DELETE)
// @PostMapping( "/remove")
// @ResponseBody
// public AjaxResult remove(String ids)
// {
// return toAjax(tireMaintenanceService.deleteTireMaintenanceByIds(ids));
// }
}

@ -16,7 +16,7 @@ ruoyi:
# 开发环境配置
server:
# 服务器的HTTP端口默认为80
port: 80
port: 8020
servlet:
# 应用的访问路径
context-path: /

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="renderer" content="webkit">
<title>若依系统首页</title>
<title>智能轮胎管理系统</title>
<!-- 避免IE使用兼容模式 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link th:href="@{favicon.ico}" rel="shortcut icon"/>
@ -27,7 +27,7 @@
</div>
<a th:href="@{/index}">
<li class="logo hidden-xs">
<span class="logo-lg">RuoYi</span>
<span class="logo-lg">智能轮胎管理系统</span>
</li>
</a>
<div class="sidebar-collapse tab-content" id="side-menu">

@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="renderer" content="webkit">
<title>若依系统首页</title>
<title>智能轮胎管理系统</title>
<!-- 避免IE使用兼容模式 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link th:href="@{favicon.ico}" rel="shortcut icon"/>
@ -26,7 +26,7 @@
</div>
<a th:href="@{/index}">
<li class="logo hidden-xs">
<span class="logo-lg">RuoYi</span>
<span class="logo-lg">智能轮胎管理系统</span>
</li>
</a>
<div class="sidebar-collapse">
@ -196,7 +196,7 @@
</a>
</div>
<ul class="nav navbar-top-links navbar-right welcome-message">
<li><a data-toggle="tooltip" data-trigger="hover" data-placement="bottom" title="开发文档" href="http://doc.ruoyi.vip/ruoyi" target="_blank"><i class="fa fa-question-circle"></i> 文档</a></li>
<!-- <li><a data-toggle="tooltip" data-trigger="hover" data-placement="bottom" title="开发文档" href="http://doc.ruoyi.vip/ruoyi" target="_blank"><i class="fa fa-question-circle"></i> 文档</a></li>-->
<li><a data-toggle="tooltip" data-trigger="hover" data-placement="bottom" title="锁定屏幕" href="javascript:;" id="lockScreen"><i class="fa fa-lock"></i> 锁屏</a></li>
<li><a data-toggle="tooltip" data-trigger="hover" data-placement="bottom" title="全屏显示" href="javascript:;" id="fullScreen"><i class="fa fa-arrows-alt"></i> 全屏</a></li>
<li class="dropdown user-menu">

@ -4,84 +4,171 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<title>智能轮胎系统登录</title>
<meta name="description" content="若依后台管理框架">
<meta name="description" content="智能轮胎管理系统">
<!-- 原有CSS引用保持不变 -->
<link href="../static/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
<link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
<link href="../static/css/style.min.css" th:href="@{/css/style.min.css}" rel="stylesheet"/>
<link href="../static/css/login.min.css" th:href="@{/css/login.min.css}" rel="stylesheet"/>
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.8.3}" rel="stylesheet"/>
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.8.2}" rel="stylesheet"/>
<!-- 360浏览器急速模式 -->
<meta name="renderer" content="webkit">
<!-- 避免IE使用兼容模式 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="shortcut icon" href="../static/favicon.ico" th:href="@{favicon.ico}"/>
<style type="text/css">label.error { position:inherit; }</style>
<!-- ⭐ 核心优化:自定义内联样式 (覆盖原有样式) -->
<style type="text/css">
/* 1. 全屏背景图设置 */
body.signin {
background: url('../img/img.png') no-repeat center center fixed; /* 确保图片路径正确 */
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
/* 如果背景图太亮,可以加一层半透明黑色遮罩,让白色登录框更突出 */
position: relative;
overflow: hidden;
}
body.signin::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0, 0, 0, 0.3); /* 30%透明度的黑色遮罩 */
z-index: -1;
}
/* 2. 登录面板优化:增加磨砂玻璃质感和阴影 */
.signinpanel {
width: 400px;
margin: 10% auto;
padding: 30px 40px;
background: rgba(255, 255, 255, 0.92); /* 半透明白底 */
border-radius: 12px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.3);
backdrop-filter: blur(10px); /* 磨砂效果,现代浏览器支持 */
border: 1px solid rgba(255, 255, 255, 0.2);
}
/* 3. 输入框优化 */
.form-control {
height: 48px;
border: 1px solid #ddd;
border-radius: 8px;
font-size: 16px;
padding: 10px 15px;
transition: all 0.3s ease;
}
.form-control:focus {
border-color: #4285f4; /* 蓝色边框 */
box-shadow: 0 0 10px rgba(66, 133, 244, 0.3);
transform: scale(1.02); /* 聚焦时轻微放大 */
}
/* 4. 按钮优化 */
.btn-success {
background-color: #1890ff; /* 阿里系蓝色,比默认绿更专业 */
border-color: #1890ff;
height: 48px;
font-size: 18px;
border-radius: 8px;
transition: all 0.3s ease;
font-weight: bold;
}
.btn-success:hover {
background-color: #409eff;
border-color: #409eff;
transform: translateY(-2px);
}
/* 5. 验证码区域优化 */
.imgcode {
border-radius: 8px;
cursor: pointer;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
transition: transform 0.3s ease;
}
.imgcode:hover {
transform: scale(1.05);
}
/* 6. 标题优化 */
h1[style] {
color: #333 !important;
text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
}
</style>
<script>
if(window.top!==window.self){alert('未登录或登录超时。请重新登录');window.top.location=window.location};
</script>
</head>
<body class="signin">
<div class="signinpanel">
<div class="row">
<!-- <div class="col-sm-7">-->
<!-- <div class="signin-info">-->
<!-- <div class="logopanel m-b">-->
<!-- <h1><img alt="[ 若依 ]" src="../static/ruoyi.png" th:src="@{/ruoyi.png}"></h1>-->
<!-- </div>-->
<!-- <div class="m-b"></div>-->
<!-- <h4>欢迎使用 <strong>若依 后台管理系统</strong></h4>-->
<!-- <ul class="m-b">-->
<!-- <li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> SpringBoot</li>-->
<!-- <li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> Mybatis</li>-->
<!-- <li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> Shiro</li>-->
<!-- <li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> Thymeleaf</li>-->
<!-- <li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> Bootstrap</li>-->
<!-- </ul>-->
<!-- <strong th:if="${isAllowRegister}">还没有账号? <a th:href="@{/register}">立即注册&raquo;</a></strong>-->
<!-- </div>-->
<!-- </div>-->
<div class="col-sm-6">
<form id="signupForm" autocomplete="off">
<h1 class="no-margins" style="font-weight: bold;text-align: center;color: black">智能轮胎系统登录</h1>
<!-- <p class="m-t-md">你若不离不弃,我必生死相依</p>-->
<input type="text" name="username" class="form-control uname" placeholder="用户名" value="" />
<input type="password" name="password" class="form-control pword" placeholder="密码" value="" />
<div class="row m-t" th:if="${captchaEnabled==true}">
<div class="col-xs-6">
<input type="text" name="validateCode" class="form-control code" placeholder="验证码" maxlength="5" />
</div>
<div class="col-xs-6">
<a href="javascript:void(0);" title="点击更换验证码">
<img th:src="@{/captcha/captchaImage(type=${captchaType})}" class="imgcode" width="85%"/>
</a>
</div>
</div>
<div class="checkbox-custom" th:if="${isRemembered}" th:classappend="${captchaEnabled==false} ? 'm-t'">
<input type="checkbox" id="rememberme" name="rememberme"> <label for="rememberme">记住我</label>
</div>
<button class="btn btn-success btn-block" id="btnSubmit" data-loading="正在验证登录,请稍候...">登录</button>
</form>
</div>
<!-- <div class="col-sm-6">-->
<!-- <img th:src="@{/img/logo_ll.png}" style="height: 50px;width: 350px">-->
<!--&lt;!&ndash; <img th:src="@{/captcha/captchaImage(type=${captchaType})}" class="imgcode" width="85%"/>&ndash;&gt;-->
<!--&lt;!&ndash; <img src="your-image.jpg" alt="示例图片">&ndash;&gt;-->
<!-- </div>-->
<div class="signinpanel">
<div class="row">
<!-- ⭐ 内容微调:去除了原本的注释,保持结构清晰 -->
<div class="col-sm-12">
<!-- Logo或系统名称 -->
<h1 class="no-margins text-center" style="font-weight: bold; color: #1890ff; margin-bottom: 30px;">
<i class="fa fa-car"></i> 智能轮胎管理系统
</h1>
<!-- 登录表单 -->
<form id="signupForm" autocomplete="off">
<!-- 用户名 -->
<div class="form-group">
<input type="text" name="username" class="form-control uname" placeholder="请输入用户名" value="" />
</div>
<!-- 密码 -->
<div class="form-group">
<input type="password" name="password" class="form-control pword" placeholder="请输入密码" value="" />
</div>
<!-- 验证码 (根据后端配置显示) -->
<div class="row m-t" th:if="${captchaEnabled==true}">
<div class="col-xs-6">
<input type="text" name="validateCode" class="form-control code" placeholder="请输入验证码" maxlength="5" />
</div>
<div class="col-xs-6">
<a href="javascript:void(0);" title="点击更换验证码" onclick="this.src='/captcha/captchaImage?type='+captchaType+'&d='+new Date().getTime()">
<img th:src="@{/captcha/captchaImage(type=${captchaType})}" class="imgcode" width="100%"/>
</a>
</div>
</div>
<!-- 记住我 & 忘记密码 -->
<div class="checkbox-custom m-t" th:if="${isRemembered}" style="float: left;">
<input type="checkbox" id="rememberme" name="rememberme">
<label for="rememberme" style="color: black">记住我</label>
</div>
<!-- 如果需要“忘记密码”链接,取消下面的注释 -->
<!-- <a href="#" style="float: right; margin-top: 10px;">忘记密码?</a> -->
<div class="clearfix"></div>
<!-- 登录按钮 -->
<button class="btn btn-success btn-block" id="btnSubmit" data-loading="正在验证登录,请稍候...">
<i class="fa fa-sign-in"></i> 登 录
</button>
</form>
</div>
<!-- <div class="signup-footer">-->
<!-- <div class="pull-left">-->
<!-- Copyright © 2018-2026 ruoyi.vip All Rights Reserved. <br>-->
<!-- </div>-->
<!-- </div>-->
</div>
<script th:inline="javascript"> var ctx = [[@{/}]]; var captchaType = [[${captchaType}]]; var captchaEnabled = [[${captchaEnabled}]];</script>
</div>
<!-- 原有JS引用保持不变 -->
<script th:inline="javascript">
var ctx = [[@{/}]];
var captchaType = [[${captchaType}]];
var captchaEnabled = [[${captchaEnabled}]];
</script>
<!--[if lte IE 8]><script>window.location.href=ctx+'html/ie.html';</script><![endif]-->
<!-- 全局js -->
<script src="../static/js/jquery.min.js" th:src="@{/js/jquery.min.js}"></script>
<script src="../static/ajax/libs/validate/jquery.validate.min.js" th:src="@{/ajax/libs/validate/jquery.validate.min.js}"></script>
<script src="../static/ajax/libs/layer/layer.min.js" th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script src="../static/ajax/libs/blockUI/jquery.blockUI.js" th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.8.3}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.8.2}"></script>
<script src="../static/ruoyi/login.js" th:src="@{/ruoyi/login.js}"></script>
</body>
</html>
</html>

@ -1,354 +1,636 @@
<!DOCTYPE html>
<html lang="zh-CN">
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>智能轮胎管理系统 - 首页看板</title>
<link href="../static/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
<link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
<link href="../static/css/style.min.css" th:href="@{/css/style.min.css}" rel="stylesheet"/>
<link href="../static/css/login.min.css" th:href="@{/css/login.min.css}" rel="stylesheet"/>
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.8.2}" rel="stylesheet"/>
<!-- 引入Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- 引入Font Awesome图标 -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<!-- 引入Chart.js -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<!-- 自定义Tailwind配置 -->
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#165DFF',
secondary: '#36CFC9',
warning: '#FF7D00',
danger: '#F53F3F',
success: '#00B42A',
dark: '#1D2129',
light: '#F2F3F5'
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
},
}
}
}
</script>
<style type="text/tailwindcss">
@layer utilities {
.card-shadow {
box-shadow: 0 2px 14px 0 rgba(0, 0, 0, 0.06);
}
.dashboard-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
}
}
</style>
<th:block th:include="include :: header('首页')" />
</head>
<body class="bg-gray-50 font-sans text-dark">
<!-- 主要内容区域 -->
<!-- 概览统计卡片 -->
<section class="dashboard-grid mb-6">
<!-- 总库存 -->
<div class="bg-white rounded-lg p-5 card-shadow">
<div class="flex justify-between items-start mb-4">
<div>
<p class="text-gray-500 text-sm">轮胎总库存</p>
<h2 class="text-3xl font-bold mt-1" id="tireStock">0</h2>
</div>
<div class="w-10 h-10 rounded-full bg-primary/10 flex items-center justify-center">
<i class="fa-solid fa-boxes-stacked text-primary"></i>
<body class="gray-bg">
<div class="wrapper wrapper-content">
<div class="row">
<div class="col-sm-12 search-collapse">
<!-- 左边部分 (占 30% -> 近似使用 col-sm-4 即 33%) -->
<div class="col-sm-3">
<div class="card-box" style="height: 50px; display: flex; align-items: center; justify-content: center;">
<!-- 时间显示区域 -->
<div id="clock" style="font-size: 20px; text-align: center; width: 100%;">
<!-- 内容由 JS 动态填充 -->
</div>
</div>
</div>
<!-- <div class="flex items-center text-sm">-->
<!-- <span class="text-success flex items-center">-->
<!-- <i class="fa-solid fa-arrow-up mr-1"></i>5.2%-->
<!-- </span>-->
<!-- <span class="text-gray-400 ml-2">较上月</span>-->
<!-- </div>-->
</div>
<!-- 在用轮胎 -->
<div class="bg-white rounded-lg p-5 card-shadow">
<div class="flex justify-between items-start mb-4">
<div>
<p class="text-gray-500 text-sm">在用轮胎数量</p>
<h2 class="text-3xl font-bold mt-1" id="tireInuse">0</h2>
</div>
<div class="w-10 h-10 rounded-full bg-secondary/10 flex items-center justify-center">
<i class="fa-solid fa-car-side text-secondary"></i>
</div>
</div>
<!-- <div class="flex items-center text-sm">-->
<!-- <span class="text-success flex items-center">-->
<!-- <i class="fa-solid fa-arrow-up mr-1"></i>2.8%-->
<!-- </span>-->
<!-- <span class="text-gray-400 ml-2">较上月</span>-->
<!-- </div>-->
</div>
<div class="col-sm-9">
<form id="formId">
<div class="select-list">
<li class="select-time">
<label>创建时间: </label>
<input type="text" class="time-input" id="startTime" placeholder="开始时间" name="birthday"/>
<span>-</span>
<input type="text" class="time-input" id="endTime" placeholder="结束时间" name="params[endTime]"/>
</li>
<!-- 2. 分公司下拉框 (新增) -->
<li>
<label>分公司: </label>
<select id="branchCompany" name="branchCompany" class="form-control" onchange="handleCompanyChange()">
<option value="">-- 请选择 --</option>
<option value="one">一分公司</option>
<option value="three">三分公司</option>
</select>
</li>
<!-- 待保养轮胎 -->
<!-- <div class="bg-white rounded-lg p-5 card-shadow">-->
<!-- <div class="flex justify-between items-start mb-4">-->
<!-- <div>-->
<!-- <p class="text-gray-500 text-sm">待保养轮胎</p>-->
<!-- <h2 class="text-3xl font-bold mt-1">387</h2>-->
<!-- </div>-->
<!-- <div class="w-10 h-10 rounded-full bg-warning/10 flex items-center justify-center">-->
<!-- <i class="fa-solid fa-wrench text-warning"></i>-->
<!-- </div>-->
<!-- </div>-->
<!--&lt;!&ndash; <div class="flex items-center text-sm">&ndash;&gt;-->
<!--&lt;!&ndash; <span class="text-danger flex items-center">&ndash;&gt;-->
<!--&lt;!&ndash; <i class="fa-solid fa-arrow-up mr-1"></i>12.1%&ndash;&gt;-->
<!--&lt;!&ndash; </span>&ndash;&gt;-->
<!--&lt;!&ndash; <span class="text-gray-400 ml-2">较上月</span>&ndash;&gt;-->
<!--&lt;!&ndash; </div>&ndash;&gt;-->
<!-- </div>-->
<!-- 关联车辆数 -->
<div class="bg-white rounded-lg p-5 card-shadow">
<div class="flex justify-between items-start mb-4">
<div>
<p class="text-gray-500 text-sm">车辆总数</p>
<h2 class="text-3xl font-bold mt-1" id="carTotal"></h2>
</div>
<div class="w-10 h-10 rounded-full bg-success/10 flex items-center justify-center">
<i class="fa-solid fa-truck text-success"></i>
</div>
</div>
<!-- <div class="flex items-center text-sm">-->
<!-- <span class="text-success flex items-center">-->
<!-- <i class="fa-solid fa-arrow-up mr-1"></i>8.5%-->
<!-- </span>-->
<!-- <span class="text-gray-400 ml-2">较上月</span>-->
<!-- </div>-->
</div>
</section>
<!-- 图表区域 -->
<section class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-6">
<!-- 近一个月出入库统计 -->
<div class="bg-white rounded-lg p-5 card-shadow lg:col-span-2">
<div class="flex justify-between items-center mb-4">
<h3 class="font-bold text-lg">近一个月轮胎出入库统计</h3>
<!-- <div class="flex gap-2">-->
<!-- <button class="px-3 py-1 rounded bg-primary text-white text-sm">日</button>-->
<!-- <button class="px-3 py-1 rounded bg-light text-gray-500 text-sm hover:bg-gray-200 transition">周</button>-->
<!-- <button class="px-3 py-1 rounded bg-light text-gray-500 text-sm hover:bg-gray-200 transition">月</button>-->
<!-- </div>-->
</div>
<div class="h-[300px]">
<canvas id="inventoryChart"></canvas>
<!-- 3. 修理厂下拉框 (新增) -->
<li>
<label>修理厂: </label>
<select id="repairShop" name="repairShop" class="form-control" disabled>
<option value="">-- 请先选分公司 --</option>
</select>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i>&nbsp;重置</a>
</li>
</ul>
</div>
</form>
</div>
</div>
<!-- 轮胎类型分布 -->
<div class="bg-white rounded-lg p-5 card-shadow">
<h3 class="font-bold text-lg mb-4">轮胎类型分布</h3>
<div class="h-[300px] flex items-center justify-center">
<canvas id="tireTypeChart"></canvas>
</div>
<div class="row">
<!-- 左边部分 (占 30% -> 近似使用 col-sm-4 即 33%) -->
<div class="col-sm-6" style="margin-top: 20px">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>实时库存统计</h5>
</div>
<div class="ibox-content">
<!-- ================= 第一部分:实时库存 (环形图 + 卡片) ================= -->
<div class="row" style="margin-bottom: 40px;">
<!-- 左侧:环形图 -->
<div class="col-sm-5 text-center" style="border-right: 1px solid #f0f0f0; position: relative; height: 240px;">
<h5 class="no-margins font-bold">实时库存</h5>
<div id="pieChart" style="height: 200px; width: 100%;"></div>
<!-- 中间文字覆盖 -->
<div id="pie-center-text" style="position: absolute; top: 45%; left: 50%; transform: translate(-50%, -50%); pointer-events: none;">
<!-- <div style="font-size: 14px; color: #666;">总数</div>-->
<!-- <div style="font-size: 24px; font-weight: bold; color: #333;">341</div>-->
</div>
</div>
<!-- 右侧:详细数据卡片 -->
<div class="col-sm-7">
<div class="row">
<!-- 新胎卡片 -->
<div class="col-sm-4">
<div class="panel panel-blue" style="border: 1px solid #e7eaec; box-shadow: none; margin-bottom: 15px;">
<div class="panel-body" style="padding: 10px;">
<div style="display: flex; align-items: center;">
<i class="fa fa-circle" style="color: #1ab394; margin-right: 5px;"></i>
<span style="font-weight: bold; font-size: 16px;">全新胎</span>
</div>
<h2 style="margin: 10px 0;" id="newTop">305</h2>
<small id="new">在库: 305</small>
</div>
</div>
</div>
<!-- 旧轮胎片 -->
<div class="col-sm-4">
<div class="panel panel-blue" style="border: 1px solid #e7eaec; box-shadow: none; margin-bottom: 15px;">
<div class="panel-body" style="padding: 10px;">
<div style="display: flex; align-items: center;">
<i class="fa fa-circle" style="color: #ed5565; margin-right: 5px;"></i>
<span style="font-weight: bold; font-size: 16px;">翻新胎</span>
</div>
<h2 style="margin: 10px 0;" id="renovateTop">35</h2>
<small id="renovate">在库: 34 </small>
</div>
</div>
</div>
<!-- 翻新胎卡片 -->
<div class="col-sm-4">
<div class="panel panel-blue" style="border: 1px solid #e7eaec; box-shadow: none; margin-bottom: 15px;">
<div class="panel-body" style="padding: 10px;">
<div style="display: flex; align-items: center;">
<i class="fa fa-circle" style="color: #f8ac59; margin-right: 5px;"></i>
<span style="font-weight: bold; font-size: 16px;">周转胎</span>
</div>
<h2 style="margin: 10px 0;" id="circulatingTop">1</h2>
<small id="circulating">在库: 1 </small>
</div>
</div>
</div>
<!-- 翻新胎卡片 -->
<div class="col-sm-4">
<div class="panel panel-blue" style="border: 1px solid #e7eaec; box-shadow: none; margin-bottom: 15px;">
<div class="panel-body" style="padding: 10px;">
<div style="display: flex; align-items: center;">
<i class="fa fa-circle" style="color: #3c5dbf; margin-right: 5px;"></i>
<span style="font-weight: bold; font-size: 16px;">实验胎</span>
</div>
<h2 style="margin: 10px 0;"id="experimentalTop">1</h2>
<small id="experimental" >在库: 1 </small>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- ================= 第二部分:近一个月出入库统计 (折线图) ================= -->
<div class="row">
<div class="col-sm-12">
<div style="border-top: 1px solid #f0f0f0; padding-top: 20px;">
<h5 class="font-bold"><i class="fa fa-line-chart"></i> 近一个月出入库统计</h5>
<!-- 折线图容器 -->
<div id="lineChart" style="height: 300px; width: 100%; margin-top: 15px;"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-6" style="margin-top: 20px">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>轮胎入库及装车统计</h5>
</div>
<div class="ibox-content">
<div class="card-box" style="height: 100%;">
<!-- 2. 选项卡切换 -->
<ul class="nav nav-tabs" style="margin-bottom: 20px;">
<li class="active"><a href="###" data-toggle="tab">入库统计</a></li>
</ul>
<!-- 3. 数字统计卡片 (4个) -->
<div class="row" style="margin-bottom: 25px;">
<div class="col-sm-3">
<div class="statistic-box" style="background: #f9f9f9; padding: 15px; border-radius: 5px; text-align: center;">
<h5>全新胎 <i class="fa fa-question-circle text-info"></i></h5>
<h2 class="font-bold text-info" id="right_new">93</h2>
</div>
</div>
<div class="col-sm-3">
<div class="statistic-box" style="background: #f9f9f9; padding: 15px; border-radius: 5px; text-align: center;">
<h5>翻新胎 <i class="fa fa-question-circle text-info"></i></h5>
<h2 class="font-bold text-primary" id="right_renovate">0</h2>
</div>
</div>
<div class="col-sm-3">
<div class="statistic-box" style="background: #f9f9f9; padding: 15px; border-radius: 5px; text-align: center;">
<h5>周转胎 <i class="fa fa-question-circle text-info"></i></h5>
<h2 class="font-bold text-warning" id="right_circulating">0</h2>
</div>
</div>
<div class="col-sm-3">
<div class="statistic-box" style="background: #f9f9f9; padding: 15px; border-radius: 5px; text-align: center;">
<h5>试验胎 <i class="fa fa-question-circle text-info"></i></h5>
<h2 class="font-bold text-danger" id="right_experimental">0</h2>
</div>
</div>
</div>
<!-- 4. 图表区域 -->
<div class="row">
<div class="col-sm-12">
<!-- 规格占比 -->
<div style="margin-bottom: 15px; font-weight: bold; font-size: 16px;">
规格占比 <small style="color: #999; font-weight: normal; margin-left: 10px;"></small>
</div>
<div id="specChart" style="height: 200px; width: 100%; margin-bottom: 30px;"></div>
<!-- 来源占比 -->
<div style="margin-bottom: 15px; font-weight: bold; font-size: 16px;">
新胎装车统计 <small style="color: #999; font-weight: normal; margin-left: 10px;"></small>
</div>
<div id="sourceChart" style="height: 200px; width: 100%;"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- 车辆与轮胎状态表格 -->
<!-- <section class="bg-white rounded-lg p-5 card-shadow">-->
<!-- <div class="flex justify-between items-center mb-4">-->
<!-- <h3 class="font-bold text-lg">车辆轮胎状态TOP10</h3>-->
<!--&lt;!&ndash; <button class="text-primary flex items-center hover:text-primary/80 transition">&ndash;&gt;-->
<!--&lt;!&ndash; 查看全部 <i class="fa-solid fa-angle-right ml-1"></i>&ndash;&gt;-->
<!--&lt;!&ndash; </button>&ndash;&gt;-->
<!-- </div>-->
<!-- <div class="overflow-x-auto">-->
<!-- <table class="w-full text-sm">-->
<!-- <thead>-->
<!-- <tr class="border-b border-gray-200">-->
<!-- <th class="text-left py-3 px-4 font-medium text-gray-500">车辆编号</th>-->
<!-- <th class="text-left py-3 px-4 font-medium text-gray-500">车牌号码</th>-->
<!-- <th class="text-left py-3 px-4 font-medium text-gray-500">轮胎数量</th>-->
<!-- <th class="text-left py-3 px-4 font-medium text-gray-500">待保养数</th>-->
<!-- <th class="text-left py-3 px-4 font-medium text-gray-500">胎压异常数</th>-->
<!-- <th class="text-left py-3 px-4 font-medium text-gray-500">最近检查时间</th>-->
<!-- </tr>-->
<!-- </thead>-->
<!-- <tbody>-->
<!-- <tr class="border-b border-gray-100 hover:bg-gray-50 transition">-->
<!-- <td class="py-3 px-4 font-medium">VEH-00128</td>-->
<!-- <td class="py-3 px-4">京A·88990</td>-->
<!-- <td class="py-3 px-4">12</td>-->
<!-- <td class="py-3 px-4"><span class="text-warning">2</span></td>-->
<!-- <td class="py-3 px-4"><span class="text-danger">1</span></td>-->
<!-- <td class="py-3 px-4">2026-02-05</td>-->
<!-- </tr>-->
<!-- <tr class="border-b border-gray-100 hover:bg-gray-50 transition">-->
<!-- <td class="py-3 px-4 font-medium">VEH-00129</td>-->
<!-- <td class="py-3 px-4">沪B·77889</td>-->
<!-- <td class="py-3 px-4">10</td>-->
<!-- <td class="py-3 px-4"><span class="text-warning">1</span></td>-->
<!-- <td class="py-3 px-4"><span class="text-gray-400">0</span></td>-->
<!-- <td class="py-3 px-4">2026-02-07</td>-->
<!-- </tr>-->
<!-- <tr class="border-b border-gray-100 hover:bg-gray-50 transition">-->
<!-- <td class="py-3 px-4 font-medium">VEH-00130</td>-->
<!-- <td class="py-3 px-4">粤C·66778</td>-->
<!-- <td class="py-3 px-4">14</td>-->
<!-- <td class="py-3 px-4"><span class="text-warning">3</span></td>-->
<!-- <td class="py-3 px-4"><span class="text-danger">2</span></td>-->
<!-- <td class="py-3 px-4">2026-02-03</td>-->
<!-- </tr>-->
<!-- <tr class="border-b border-gray-100 hover:bg-gray-50 transition">-->
<!-- <td class="py-3 px-4 font-medium">VEH-00131</td>-->
<!-- <td class="py-3 px-4">苏D·55667</td>-->
<!-- <td class="py-3 px-4">8</td>-->
<!-- <td class="py-3 px-4"><span class="text-gray-400">0</span></td>-->
<!-- <td class="py-3 px-4"><span class="text-gray-400">0</span></td>-->
<!-- <td class="py-3 px-4">2026-02-08</td>-->
<!-- </tr>-->
<!-- <tr class="hover:bg-gray-50 transition">-->
<!-- <td class="py-3 px-4 font-medium">VEH-00132</td>-->
<!-- <td class="py-3 px-4">浙E·44556</td>-->
<!-- <td class="py-3 px-4">10</td>-->
<!-- <td class="py-3 px-4"><span class="text-warning">1</span></td>-->
<!-- <td class="py-3 px-4"><span class="text-gray-400">0</span></td>-->
<!-- <td class="py-3 px-4">2026-02-06</td>-->
<!-- </tr>-->
<!-- </tbody>-->
<!-- </table>-->
<!-- </div>-->
<!-- </section>-->
<!-- 图表初始化脚本 -->
</div>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: datetimepicker-js" />
<th:block th:include="include :: echarts-js" />
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('tyre:tyre:edit')}]];
var removeFlag = [[${@permission.hasPermi('tyre:tyre:remove')}]];
var prefix = ctx + "tyre/tyre";
var datas = [[${@dict.getType('tyre_type')}]];
var shopData = {
'one': [], // 一分公司:空数组
'three': [ // 三分公司:包含两个选项
{ value: 'guangming', name: '光明修理厂' },
{ value: 'shiyan', name: '石岩修理厂' }
]
};
$(function() {
$("input[name='birthday']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
// 实时时间更新
function updateClock() {
const now = new Date();
const weekDays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
const timeStr = now.toTimeString().substr(0, 8); // "11:14:10"
const dateStr = now.toLocaleDateString(); // "2026/4/15"
const weekStr = weekDays[now.getDay()];
// 这里的 HTML 结构完全模拟了你图片中的样式
$('#clock').html(`${timeStr} <small style="color:#999; margin: 0 10px;">|</small> ${dateStr} ${weekStr}`);
}
// ================= 1. 环形图逻辑 (保持原有逻辑) =================
var pieChart = echarts.init(document.getElementById('pieChart'));
function renderPieChart(data) {
var option = {
color: ['#1ab394', '#f8ac59', '#5B7CD9', '#ed5565', '#999'], // 配色方案
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
series: [
{
name: '实时库存',
type: 'pie',
radius: ['60%', '75%'], // 环形
avoidLabelOverlap: false,
label: {
show: false
},
labelLine: {
show: false
},
data: [
{ value: data.new, name: '新胎' },
{ value: data.circulating, name: '周转胎' },
{ value: data.renovate, name: '翻新胎' },
{ value: data.experimental, name: '试验胎' }
// 注意如果后端返回0这里也要传0否则图表会少一块
]
}
]
};
pieChart.setOption(option);
$('#new').text(`在库: ${data.new}`);
$('#circulating').text(`在库: ${data.circulating}`);
$('#renovate').text(`在库: ${data.renovate}`);
$('#experimental').text(`在库: ${data.experimental}`);
$('#newTop').text(`${data.new}`);
$('#circulatingTop').text(`${data.circulating}`);
$('#renovateTop').text(`${data.renovate}`);
$('#experimentalTop').text(`${data.experimental}`);
$('#right_new').text(`${data.new}`);
$('#right_circulating').text(`${data.circulating}`);
$('#right_renovate').text(`${data.renovate}`);
$('#right_experimental').text(`${data.experimental}`);
// 3. 动态更新中间的文字覆盖层
// 获取DOM元素并更新文本
const clockDiv = document.getElementById('pie-center-text');
if (clockDiv) {
// 这里复用你原本的逻辑,或者直接用接口返回的 total
clockDiv.innerHTML = `总数<br><span style="font-size:24px;font-weight:bold">${data.total || 0}</span>`;
}
}
// 4. 发起 AJAX 请求获取数据
$.ajax({
type: "post",
url: ctx + "queryIndexData",
success: function(r) {
if (r.code == web_status.SUCCESS) {
document.getElementById('tireStock').innerText = r.data.InventoryTotal;
document.getElementById('tireInuse').innerText = r.data.TyreInCar;
document.getElementById('carTotal').innerText = r.data.CarTotal;
const mapList = r.data.mapList || [];
const inData = mapList.map(item => Number(item.type_0_count) || 0);
const outData = mapList.map(item => Number(item.type_1_count) || 0);
// 提取每个元素的 date 字段
const dates = mapList.map(item => {
// 若后端返回的 date 是完整日期(如 2026-03-02可格式化可选
// 示例:把 2026-03-02 转成 3/2
if (item.date && item.date.includes('-')) {
const [year, month, day] = item.date.split('-');
return `${month}/${day}`;
}
// 若后端已返回 3/2 格式,直接返回
return item.date || '';
});
// 3. 基于后端返回的 dates 生成图表数据(也可从 mapList 提取真实出入库数据)
// 如果你有真实的入库/出库数据,也可以从 mapList 提取,比如:
// const inData = mapList.map(item => item.inNum || 0);
// const outData = mapList.map(item => item.outNum || 0);
// 暂时保留随机数,仅替换 dates
// 等待DOM加载完成
// 1. 出入库统计图表
const inventoryCtx = document.getElementById('inventoryChart').getContext('2d');
new Chart(inventoryCtx, {
type: 'line',
data: {
labels: dates,
datasets: [
{
label: '入库数量',
data: inData,
borderColor: '#165DFF',
backgroundColor: 'rgba(22, 93, 255, 0.1)',
fill: true,
tension: 0.4
},
{
label: '出库数量',
data: outData,
borderColor: '#F53F3F',
backgroundColor: 'rgba(245, 63, 63, 0.1)',
fill: true,
tension: 0.4
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'top',
},
tooltip: {
mode: 'index',
intersect: false
}
},
scales: {
y: {
beginAtZero: true,
grid: {
color: 'rgba(0, 0, 0, 0.05)'
}
},
x: {
grid: {
display: false
}
}
}
}
});
// 2. 轮胎类型分布图表
const tireTypeCtx = document.getElementById('tireTypeChart').getContext('2d');
new Chart(tireTypeCtx, {
type: 'doughnut',
data: {
labels: ['卡车轮胎', '客车轮胎', '轿车轮胎', '工程车轮胎', '其他'],
datasets: [{
data: [45, 25, 15, 10, 5],
backgroundColor: [
'#165DFF',
'#36CFC9',
'#FF7D00',
'#F53F3F',
'#86909C'
],
borderWidth: 0
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
}
},
cutout: '70%'
}
});
url: ctx+'queryIndexData', // 你的接口地址
type: 'POST',
dataType: 'json',
success: function(res) {
if (res.code === 0) { // 假设 code 0 代表成功
// 调用渲染函数
renderPieChart(res.data.tireTypeTotal);
// --- 新增代码:渲染折线图 ---
// 假设 res.data.mapList 是包含日期和数量的数组
if (res.data.mapList && res.data.mapList.length > 0) {
renderLineChart(res.data.mapList);
} else {
// 处理空数据情况,防止报错
renderLineChart([]);
}
// --- 新增代码:渲染规格占比图 ---
// 假设接口返回的数据结构为 res.data.mapListTyreModel
if (res.data.mapListTyreModel && res.data.mapListTyreModel.length > 0) {
renderSpecChart(res.data.mapListTyreModel);
} else {
renderSpecChart([]); // 传空数组显示暂无数据
}
// --- 新增代码:渲染规格占比图 ---
// 假设接口返回的数据结构为 res.data.mapListTyreModel
if (res.data.mapListInstall && res.data.mapListInstall.length > 0) {
renderSourceChart(res.data.mapListInstall);
} else {
renderSourceChart([]); // 传空数组显示暂无数据
}
} else {
// 错误处理
console.error('数据加载失败:', res.msg);
// 即使失败,也渲染一个默认的空数据或者错误提示
renderPieChart({total: 0, new: 0, circulating: 0, renovate: 0, experimental: 0});
renderLineChart([]);
renderSpecChart([]); // 错误时也传空
renderSourceChart([]); // 错误时也传空
}
// $.modal.closeLoading();
},
error: function() {
console.error('网络请求出错');
renderPieChart({total: 0, new: 0, circulating: 0, renovate: 0, experimental: 0});
}
});
})
// ================= 2. 折线图逻辑 (新增) =================
var lineChart = echarts.init(document.getElementById('lineChart'));
function renderLineChart(mapList) {
// 1. 数据预处理:从 mapList 中提取 X轴(date) 和 Y轴数据
var dates = [];
var inData = []; // 入库数量 (type_0_count)
var outData = []; // 出库数量 (type_1_count)
mapList.forEach(function(item) {
dates.push(item.date); // X轴日期
inData.push(item.type_0_count); // Y轴入库
outData.push(item.type_1_count); // Y轴出库
});
var lineOption = {
tooltip: {
trigger: 'axis'
},
legend: {
data: ['入库数量', '出库数量'],
right: '10%'
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: dates, // 使用接口返回的日期
axisLine: {
lineStyle: {
color: '#ccc'
}
}
},
yAxis: {
type: 'value',
axisLine: {
show: false
},
splitLine: {
lineStyle: {
type: 'dashed',
color: '#eee'
}
}
},
series: [
{
name: '入库数量',
type: 'line',
smooth: true,
symbol: 'circle',
symbolSize: 6,
itemStyle: {
color: '#1ab394' // 绿色
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(26, 179, 148, 0.5)' },
{ offset: 0.8, color: 'rgba(26, 179, 148, 0.1)' }
])
},
data: inData // 使用接口返回的入库数据
},
{
name: '出库数量',
type: 'line',
smooth: true,
symbol: 'circle',
symbolSize: 6,
itemStyle: {
color: '#ed5565' // 红色
},
data: outData // 使用接口返回的出库数据
}
]
};
lineChart.setOption(lineOption);
}
// 窗口大小改变时重绘图表
window.addEventListener('resize', function() {
pieChart.resize();
lineChart.resize();
});
// ================= 规格占比图表 (修改版:支持异步数据) =================
var specChart = echarts.init(document.getElementById("specChart"));
// 1. 定义一个全局的颜色数组 (放在函数外面,避免 undefined 错误)
var specColors = ['#5B7CD9', '#8CC657', '#F7C763', '#E96966', '#73C0DE', '#45B97C', '#9A60B4', '#EA7E53'];
function renderSpecChart(modelData) {
// 1. 数据预处理
if (!modelData || modelData.length === 0) {
specChart.clear(); // 清空图表
specChart.setOption({
title: { text: '', left: 'center', top: 'center', textStyle: { fontSize: 16 } },
xAxis: { show: false },
yAxis: { show: false },
series: []
});
return;
}
// 2. 动态生成 Series 数据
// 使用 map 遍历后端传来的规格列表
var specSeries = modelData.map(function(item, index) {
// 使用 index % specColors.length 确保颜色循环使用,且不会越界
var color = specColors[index % specColors.length];
return {
name: item.tyreModel,
type: 'bar',
stack: 'total',
barWidth: 20,
label: { show: false },
itemStyle: {
color: color // 使用计算出的颜色
},
data: [item.total]
};
});
// 3. 生成图例数据
var legendData = modelData.map(item => item.tyreModel);
// 4. 设置图表 Option
var specOption = {
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' }
},
legend: {
bottom: 0,
data: legendData,
textStyle: { fontSize: 12 }
},
grid: {
left: '50',
right: '20',
bottom: '60',
top: '10',
containLabel: true
},
xAxis: {
type: 'value',
max: function(value) {
return Math.ceil(value.max * 1.2);
},
splitLine: { show: true, lineStyle: { type: 'dashed' } }
},
yAxis: {
type: 'category',
data: ['规格统计'] // 可以改为动态的,或者保持单维度
},
series: specSeries
};
specChart.setOption(specOption);
}
// 初始化时传空数据
renderSpecChart([]);
// ================= 来源占比图表 (修改版:支持异步数据) =================
var sourceChart = echarts.init(document.getElementById("sourceChart"));
function renderSourceChart(modelData) {
// 1. 数据预处理
if (!modelData || modelData.length === 0) {
sourceChart.clear(); // 清空图表
sourceChart.setOption({
title: { text: '', left: 'center', top: 'center', textStyle: { fontSize: 16 } },
xAxis: { show: false },
yAxis: { show: false },
series: []
});
return;
}
// 2. 动态生成 Series 数据
// 使用 map 遍历后端传来的规格列表
var sourceSeries = modelData.map(function(item, index) {
// 使用 index % specColors.length 确保颜色循环使用,且不会越界
var color = specColors[index % specColors.length];
return {
name: item.tyreModel,
type: 'bar',
stack: 'total',
barWidth: 20,
label: { show: false },
itemStyle: {
color: color // 使用计算出的颜色
},
data: [item.total]
};
});
// 3. 生成图例数据
var legendData = modelData.map(item => item.tyreModel);
// 4. 设置图表 Option
var sourceOption = {
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' }
},
legend: {
bottom: 0,
data: legendData,
textStyle: { fontSize: 12 }
},
grid: {
left: '50',
right: '20',
bottom: '60',
top: '10',
containLabel: true
},
xAxis: {
type: 'value',
max: function(value) {
return Math.ceil(value.max * 1.2);
},
splitLine: { show: true, lineStyle: { type: 'dashed' } }
},
yAxis: {
type: 'category',
data: ['装车统计'] // 可以改为动态的,或者保持单维度
},
series: sourceSeries
};
sourceChart.setOption(sourceOption);
}
renderSourceChart([])
// 窗口大小改变时自适应
window.addEventListener('resize', function() {
specChart.resize();
sourceChart.resize();
});
updateClock(); // 初始化
setInterval(updateClock, 1000); // 每秒刷新
});
// 分公司下拉框改变时触发的函数
function handleCompanyChange() {
var companyVal = $("#branchCompany").val(); // 获取选中的分公司值
var $shopSelect = $("#repairShop"); // 获取修理厂下拉框对象
// 1. 清空修理厂下拉框现有的选项
$shopSelect.empty();
if (!companyVal) {
// 如果没选分公司
$shopSelect.append('<option value="">-- 请先选分公司 --</option>');
$shopSelect.prop('disabled', true); // 禁用下拉框
} else {
// 获取对应的修理厂数据
var shops = shopData[companyVal];
if (shops && shops.length > 0) {
// 如果有数据,遍历添加
shops.forEach(function(item) {
$shopSelect.append('<option value="' + item.value + '">' + item.name + '</option>');
});
$shopSelect.prop('disabled', false); // 启用下拉框
} else {
// 如果是空数组(如一分公司)
$shopSelect.append('<option value="">-- 暂无数据 --</option>');
$shopSelect.prop('disabled', true); // 禁用下拉框
}
}
}
$.form.reset = function() {
$('form').each(function() {
this.reset();
});
// 手动触发一次 change 事件,确保修理厂下拉框回到初始禁用状态
handleCompanyChange();
};
</script>
</body>
</html>

@ -1,143 +1,209 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('车辆维保记录列表')" />
<th:block th:include="include :: header('维保任务列表')" />
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="formId">
<div class="select-list">
<ul>
<li>
<label>车辆ID</label>
<input type="text" name="vehicleId"/>
</li>
<li>
<label>车牌号:</label>
<input type="text" name="plateNumber"/>
</li>
<li>
<label>维保场站/修理厂:</label>
<input type="text" name="maintStation"/>
</li>
<li>
<label>保养日期:</label>
<input type="text" class="time-input" placeholder="请选择保养日期" name="maintDate"/>
</li>
<li>
维保类型:<select name="mainType" th:with="type=${@dict.getType('main_type')}">
<div class="container-div">
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="formId">
<div class="select-list">
<ul>
<li>
<label>工单编号:</label>
<input type="text" name="orderNo"/>
</li>
<li>
<label>车牌号码:</label>
<input type="text" name="plateNumber"/>
</li>
<li>
<label>维保类型:</label>
<select name="typeCode" th:with="type=${@dict.getType('main_type')}">
<option value="">所有</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</li>
<li>
维保项目:<select name="project" th:with="type=${@dict.getType('maintenance_project')}">
<option value="">所有</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i>&nbsp;重置</a>
</li>
</ul>
</div>
</form>
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="system:maintenance:add">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="system:maintenance:edit">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="system:maintenance:remove">
<i class="fa fa-remove"></i> 删除
</a>
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="system:maintenance:export">
<i class="fa fa-download"></i> 导出
</a>
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</li>
<li>
<label>状态:</label>
<select name="status" th:with="type=${@dict.getType('order_status')}">
<option value="">所有</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i>&nbsp;重置</a>
</li>
</ul>
</div>
</form>
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-success" onclick="$.operate.addTab()" shiro:hasPermission="system:order:submit">
<i class="fa fa-pencil"></i> 提交工单
</a>
<!-- <a class="btn btn-primary single disabled" onclick="$.operate.editTab()" shiro:hasPermission="system:order:edit">-->
<!-- <i class="fa fa-edit"></i> 编辑-->
<!-- </a>-->
<!-- <a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="system:order:remove">-->
<!-- <i class="fa fa-remove"></i> 删除-->
<!-- </a>-->
<!-- <a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="system:order:export">-->
<!-- <i class="fa fa-download"></i> 导出-->
<!-- </a>-->
<!-- <a class="btn btn-info" onclick="$.operate.view()" shiro:hasPermission="system:order:view">-->
<!-- <i class="fa fa-eye"></i> 查看详情-->
<!-- </a>-->
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('system:maintenance:edit')}]];
var removeFlag = [[${@permission.hasPermi('system:maintenance:remove')}]];
var prefix = ctx + "tyre/maintenance";
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('system:order:edit')}]];
var removeFlag = [[${@permission.hasPermi('system:order:remove')}]];
var viewFlag = [[${@permission.hasPermi('system:order:view')}]];
var prefix = ctx + "tyre/order";
$(function() {
var options = {
url: prefix + "/list",
createUrl: prefix + "/add",
updateUrl: prefix + "/edit/{id}",
removeUrl: prefix + "/remove",
exportUrl: prefix + "/export",
modalName: "车辆维保记录",
columns: [{
checkbox: true
},
function showDetail(orderId) {
// 这里使用了若依框架常用的 $.modal.open 方法
// 如果你的框架没有这个方法,可以使用 Bootstrap 的 Modal 手动填充数据
$.modal.open("轮胎详情", prefix + "/detail/" + orderId);
// 或者如果你是弹出一个包含详细信息的 Alert
// $.modal.alertSuccess("你点击的轮胎ID是: " + tyreId);
}
$(function() {
var options = {
url: prefix + "/list",
createUrl: prefix + "/submit",
updateUrl: prefix + "/edit/{id}",
removeUrl: prefix + "/remove",
exportUrl: prefix + "/export",
modalName: "补胎工单",
columns: [{
checkbox: true
},
{
field: 'id',
title: '维保单号',
// visible: false
},
{
field: 'vehicleId',
title: '车辆ID',
field: 'orderId',
title: '工单ID',
visible: false
},
{
field: 'orderNo',
title: '工单编号'
},
{
field: 'plateNumber',
title: '车牌号'
title: '车牌号'
},
{
field: 'maintType',
title: '维保类型'
field: 'typeCode',
title: '维保类型',
formatter: function(value, item, index) {
if (item.typeCode == '1') {
return '二级保养';
}
else if (item.typeCode == '2') {
return '抢碎修';
}
else if (item.typeCode == '3') {
return '拆报废车';
}
else if (item.typeCode == '4') {
return '月检';
}
else if (item.typeCode == '5') {
return '小修';
}
}
},
{
field: 'maintStation',
title: '维保场站/修理厂'
field: 'inputMileage',
title: '录入里程'
},
{
field: 'maintDate',
field: 'lastMileage',
title: '上次里程'
},
{
field: 'maintainDate',
title: '保养日期'
},
{
field: 'mileage',
title: '仪表盘里程'
field: 'description',
title: '补充说明'
},
{
field: 'factoryName',
title: '维修站点'
},
{
field: 'status',
title: '维保状态'
title: '状态',
formatter: function(value, row, index) {
if (value === 'UNSTARTED') return '<span class="label label-warning">未开始</span>';
if (value === 'PROCESSING') return '<span class="label label-primary">执行中</span>';
if (value === 'COMPLETED') return '<span class="label label-success">已完成</span>';
return value;
}
},
{
field: 'project',
title: '维保项目'
field: 'createBy',
title: '创建人'
},
{
field: 'remark',
title: '备注'
field: 'createTime',
title: '提交日期'
},
{
field: 'maintainer',
title: '修补人'
},
{
field: 'maintainerDate',
title: '修补日期'
},
{
title: '操作',
align: 'center',
formatter: function(value, row, index) {
var actions = [];
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.id + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.id + '\')"><i class="fa fa-remove"></i>删除</a>');
if(row.status == 'UNSTARTED'){
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.editTab(\'' + row.orderId + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.orderId + '\')"><i class="fa fa-remove"></i>删除</a>');
}
actions.push('<a class="btn btn-info btn-xs ' + viewFlag + '" href="javascript:void(0)" onclick="showDetail(\'' + row.orderId + '\')"><i class="fa fa-eye"></i>详情</a> ');
return actions.join('');
}
}]
};
$.table.init(options);
};
$.table.init(options);
// 初始化日期插件
$("#formId input[name='maintainDate']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
</script>
// 提交工单新窗口
$.operate.openNewWindow = function(url) {
if (url === 'submit') {
$.modal.open("提交工单", prefix + "/submit", "800", "600");
} else {
$.modal.open("详情查看", url, "900", "700");
}
};
});
</script>
</body>
</html>

@ -0,0 +1,136 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('新增维保工单')" />
<th:block th:include="include :: datetimepicker-css" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-order-add">
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label is-required">工单编号:</label>
<div class="col-sm-8">
<input name="orderNo" class="form-control" type="text" required>
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label is-required">车辆ID/轮胎ID</label>
<div class="col-sm-8">
<input name="vehicleId" class="form-control" type="text" required>
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">车牌号码:</label>
<div class="col-sm-8">
<input name="plateNumber" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label is-required">维保类型:</label>
<div class="col-sm-8">
<select name="typeCode" class="form-control" th:with="type=${@dict.getType('main_type')}" required>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">维修站点/修理厂ID</label>
<div class="col-sm-8">
<input name="factoryId" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">仪表盘录入里程:</label>
<div class="col-sm-8">
<input name="inputMileage" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">上次维保里程:</label>
<div class="col-sm-8">
<input name="lastMileage" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">保养日期:</label>
<div class="col-sm-8">
<div class="input-group date">
<input name="maintainDate" class="form-control" placeholder="yyyy-MM-dd" type="text">
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
</div>
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">补充说明:</label>
<div class="col-sm-8">
<textarea name="description" class="form-control"></textarea>
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">状态:</label>
<div class="col-sm-8">
<select name="status" class="form-control" th:with="type=${@dict.getType('order_status')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">1代表汽车、2代表轮胎</label>
<div class="col-sm-8">
<input name="orderType" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">备注:</label>
<div class="col-sm-8">
<textarea name="remark" class="form-control"></textarea>
</div>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: datetimepicker-js" />
<script th:inline="javascript">
var prefix = ctx + "system/order"
$("#form-order-add").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/add", $('#form-order-add').serialize());
}
}
$("input[name='maintainDate']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
</script>
</body>
</html>

@ -1,225 +0,0 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<th:block th:include="include :: header('补胎工单详情')" />
<style>
.image-gallery {
display: flex;
flex-wrap: wrap;
gap: 15px;
margin-top: 10px;
}
.image-item {
width: 150px;
border: 1px solid #ddd;
border-radius: 4px;
overflow: hidden;
padding: 5px;
background: #f9f9f9;
}
.image-item img {
width: 100%;
height: 120px;
object-fit: cover;
border-radius: 3px;
}
.image-info {
font-size: 12px;
text-align: center;
margin-top: 5px;
color: #666;
word-break: break-all;
}
.field-label {
font-weight: bold;
color: #555;
}
.readonly-field {
background-color: #f8f9fa;
border-color: #dee2e6;
color: #495057;
}
</style>
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<!-- 基本信息 -->
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">基本信息</h3>
</div>
<div class="panel-body">
<form class="form-horizontal m">
<div class="form-group">
<label class="col-sm-3 control-label field-label">工单编号:</label>
<div class="col-sm-8">
<input class="form-control readonly-field" th:value="${bizMaintenanceOrder.orderNo}" readonly>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label field-label">车牌号:</label>
<div class="col-sm-8">
<input class="form-control readonly-field" th:value="${bizMaintenanceOrder.plateNumber}" readonly>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label field-label">维保类型:</label>
<div class="col-sm-8">
<input class="form-control readonly-field" th:value="${bizMaintenanceOrder.typeCode}" readonly>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label field-label">仪表盘录入里程:</label>
<div class="col-sm-8">
<input class="form-control readonly-field" th:value="${bizMaintenanceOrder.inputMileage}" readonly>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label field-label">上次维保里程:</label>
<div class="col-sm-8">
<input class="form-control readonly-field" th:value="${bizMaintenanceOrder.lastMileage}" readonly>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label field-label">保养日期:</label>
<div class="col-sm-8">
<input class="form-control readonly-field" th:value="${#dates.format(bizMaintenanceOrder.maintainDate, 'yyyy-MM-dd')}" readonly>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label field-label">维修站点:</label>
<div class="col-sm-8">
<input class="form-control readonly-field" th:value="${bizMaintenanceOrder.factoryName}" readonly>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label field-label">提交人:</label>
<div class="col-sm-8">
<input class="form-control readonly-field" th:value="${bizMaintenanceOrder.createBy}" readonly>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label field-label">提交日期:</label>
<div class="col-sm-8">
<input class="form-control readonly-field" th:value="${#dates.format(bizMaintenanceOrder.createTime, 'yyyy-MM-dd HH:mm:ss')}" readonly>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label field-label">状态:</label>
<div class="col-sm-8">
<input class="form-control readonly-field" th:value="${bizMaintenanceOrder.status}" readonly>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label field-label">补充说明:</label>
<div class="col-sm-8">
<textarea class="form-control readonly-field" th:text="${bizMaintenanceOrder.description}" readonly rows="3"></textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label field-label">修补人:</label>
<div class="col-sm-8">
<input class="form-control readonly-field" th:value="${bizMaintenanceOrder.maintainer}" readonly>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label field-label">修补日期:</label>
<div class="col-sm-8">
<input class="form-control readonly-field" th:value="${#dates.format(bizMaintenanceOrder.maintainerDate, 'yyyy-MM-dd')}" readonly>
</div>
</div>
</form>
</div>
</div>
<!-- 图片 -->
<!-- <div class="panel panel-default">-->
<!-- <div class="panel-heading">-->
<!-- <h3 class="panel-title">图片</h3>-->
<!-- </div>-->
<!-- <div class="panel-body">-->
<!-- <div th:if="${attachments != null and not attachments.empty}">-->
<!-- <div class="image-gallery">-->
<!-- <div th:each="attachment : ${attachments}" class="image-item preview-item" style="cursor: pointer;" th:data-src="@{${attachment.filePath}}" th:data-name="${attachment.fileName}">-->
<!-- <img th:src="@{${attachment.filePath}}" th:alt="${attachment.fileName}" >-->
<!-- <div class="image-info">-->
<!-- <div th:text="${attachment.fileName}" style="font-weight: bold; font-size: 11px;"></div>-->
<!-- <div th:text="${#dates.format(attachment.uploadTime, 'yyyy-MM-dd HH:mm')}" style="font-size: 10px; color: #888;"></div>-->
<!-- <div th:text="${attachment.uploadBy}" style="font-size: 10px; color: #666;"></div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div th:if="${attachments == null or attachments.empty}" class="text-center text-muted">-->
<!-- <p>暂无上传图片</p>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- 轮胎信息 -->
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">轮胎信息</h3>
</div>
<div class="panel-body">
<div th:if="${tireDetails != null and not tireDetails.empty}">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="width: 60px;">序号</th>
<th>轮胎编号</th>
<th>轮胎位置</th>
<th>品牌</th>
<th>型号</th>
<th>花纹深度(mm)</th>
<th>状态描述</th>
</tr>
</thead>
<tbody>
<tr th:each="tire, iterStat : ${tireDetails}">
<td th:text="${iterStat.count}"></td>
<td th:text="${tire.tireCode}"></td>
<td th:text="${tire.positionDesc}"></td>
<td th:text="${tire.tyreBrand}"></td>
<td th:text="${tire.tyreModel}"></td>
<td th:text="${tire.treadDepth}"></td>
<td th:text="${tire.tireStatus}"></td>
</tr>
</tbody>
</table>
</div>
<div th:if="${tireDetails == null or tireDetails.empty}" class="text-center text-muted">
<p>暂无轮胎信息</p>
</div>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script type="text/javascript">
$(function() {
// 图片点击预览
$(document).on('click', '.preview-item', function() {
var imgSrc = $(this).data('src');
var imgTitle = $(this).data('name') || '工单图片';
previewImage(imgSrc, imgTitle);
});
});
// 图片点击预览
function previewImage(imgSrc, imgTitle) {
layer.open({
type: 1,
title: imgTitle || '工单图片',
shadeClose: true,
shade: 0.8,
area: ['90%', '90%'],
content: '<div style="text-align:center; padding: 20px;"><img src="' + imgSrc + '" style="max-width:100%;max-height:100%;" /></div>'
});
}
</script>
</body>
</html>

@ -1,447 +1,129 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('编辑补胎工单')" />
<th:block th:include="include :: header('修改维保工单')" />
<th:block th:include="include :: datetimepicker-css" />
<th:block th:include="include :: bootstrap-fileinput-css" />
<th:block th:include="include :: bootstrap-select-css" />
<style>
/* 图片预览样式 */
.file-preview-frame {
position: relative;
display: inline-block;
margin: 5px;
}
.file-preview-image {
width: 100px;
height: 100px;
object-fit: cover;
border-radius: 4px;
border: 1px solid #ddd;
}
.file-remove-btn {
position: absolute;
top: -8px;
right: -8px;
background: #dc3545;
color: white;
border: none;
border-radius: 50%;
width: 20px;
height: 20px;
line-height: 18px;
text-align: center;
cursor: pointer;
font-size: 12px;
z-index: 10;
}
.uploaded-images {
margin-top: 15px;
}
.uploaded-image-item {
position: relative;
display: inline-block;
margin: 5px;
}
.uploaded-image-item img {
width: 100px;
height: 100px;
object-fit: cover;
border-radius: 4px;
border: 1px solid #ddd;
}
.uploaded-image-item .remove-btn {
position: absolute;
top: -8px;
right: -8px;
background: #dc3545;
color: white;
border: none;
border-radius: 50%;
width: 20px;
height: 20px;
line-height: 18px;
text-align: center;
cursor: pointer;
font-size: 12px;
}
.existing-images {
margin-top: 15px;
padding: 10px;
background: #f8f9fa;
border-radius: 4px;
}
.existing-images-title {
font-weight: bold;
margin-bottom: 10px;
color: #555;
}
</style>
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-order-edit" th:object="${bizMaintenanceOrder}">
<input type="hidden" name="orderId" th:value="${bizMaintenanceOrder.orderId}"/>
<input name="orderType" type="hidden" value="1"/>
<input type="hidden" id="attachmentUrls" name="attachmentUrls">
<!-- 车辆信息选择 -->
<div class="form-group">
<label class="col-sm-3 control-label is-required">车辆信息:</label>
<div class="col-sm-8">
<select name="vehicleId" class="form-control selectpicker" id="vehicleSelect" data-live-search="true" required>
<option value="">请选择车辆</option>
</select>
</div>
</div>
<!-- 车牌号码(自动填充) -->
<div class="form-group" style="display: none;">
<label class="col-sm-3 control-label is-required">车牌号码:</label>
<div class="col-sm-8">
<input name="plateNumber" class="form-control" type="text" id="plateNumber" placeholder="车牌号码" readonly required th:value="${bizMaintenanceOrder.plateNumber}">
</div>
</div>
<!-- 工单类型 -->
<div class="form-group">
<label class="col-sm-3 control-label is-required">维保类型:</label>
<div class="col-sm-8">
<select name="typeCode" class="form-control" id="typeCode" required th:with="type=${@dict.getType('main_type')}">
<option value=""></option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{typeCode}"></option>
</select>
</div>
</div>
<!-- 执行站点 -->
<div class="form-group">
<label class="col-sm-3 control-label is-required">执行站点:</label>
<div class="col-sm-8">
<select name="factoryId" class="form-control selectpicker" id="factorySelect" data-live-search="true" required>
<option value="">请选择站点</option>
</select>
</div>
</div>
<!-- 仪表盘录入里程 -->
<div class="form-group">
<label class="col-sm-3 control-label">仪表盘录入里程:</label>
<div class="col-sm-8">
<input name="inputMileage" class="form-control" type="number" step="0.01" placeholder="请输入当前里程(km)" th:value="${bizMaintenanceOrder.inputMileage}">
</div>
</div>
<!-- 上次维保里程 -->
<div class="form-group">
<label class="col-sm-3 control-label">上次维保里程:</label>
<div class="col-sm-8">
<input name="lastMileage" class="form-control" type="number" step="0.01" placeholder="请输入上次维保里程(km)" th:value="${bizMaintenanceOrder.lastMileage}">
</div>
</div>
<!-- 保养日期 -->
<div class="form-group">
<label class="col-sm-3 control-label is-required">保养日期:</label>
<div class="col-sm-8">
<div class="input-group date">
<input name="maintainDate" class="form-control" placeholder="yyyy-MM-dd" type="text" required th:value="${#dates.format(bizMaintenanceOrder.maintainDate, 'yyyy-MM-dd')}">
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-order-edit" th:object="${bizMaintenanceOrder}">
<input name="orderId" th:field="*{orderId}" type="hidden">
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label is-required">车辆ID/轮胎ID</label>
<div class="col-sm-8">
<input name="vehicleId" th:field="*{vehicleId}" class="form-control" type="text" required>
</div>
</div>
</div>
</div>
<!-- 补充说明 -->
<div class="form-group">
<label class="col-sm-3 control-label">补充说明:</label>
<div class="col-sm-8">
<textarea name="description" class="form-control" rows="3" placeholder="请输入补充说明" th:text="${bizMaintenanceOrder.description}"></textarea>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">车牌号码:</label>
<div class="col-sm-8">
<input name="plateNumber" th:field="*{plateNumber}" class="form-control" type="text">
</div>
</div>
</div>
</div>
<!-- 上传图片 -->
<!-- <div class="form-group">-->
<!-- <label class="col-sm-3 control-label">上传图片:</label>-->
<!-- <div class="col-sm-8">-->
<!-- &lt;!&ndash; 已存在的图片 &ndash;&gt;-->
<!-- <div class="existing-images" th:if="${attachments != null and not attachments.empty}">-->
<!-- <div class="existing-images-title">已上传图片(点击可预览,点击×删除):</div>-->
<!-- <div class="uploaded-images" id="existingImages">-->
<!-- <div th:each="attachment, iterStat : ${attachments}" class="uploaded-image-item" th:data-url="${attachment.filePath}" th:data-index="${iterStat.index}">-->
<!-- <img th:src="@{${attachment.filePath}}" th:alt="${attachment.fileName}" onerror="this.src=ctx + 'static/img/no-image.png'" style="cursor: pointer;" class="preview-img">-->
<!-- <button type="button" class="remove-btn" th:data-index="${iterStat.index}">×</button>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- &lt;!&ndash; 新图片上传 &ndash;&gt;-->
<!-- <div class="file-loading">-->
<!-- <input id="orderImages" name="files" type="file" multiple>-->
<!-- </div>-->
<!-- <div class="uploaded-images" id="uploadedImages">-->
<!-- &lt;!&ndash; 新上传图片预览区域 &ndash;&gt;-->
<!-- </div>-->
<!-- <span class="help-block">可上传多张图片支持jpg、png格式单张不超过20MB</span>-->
<!-- </div>-->
<!-- </div>-->
<div class="form-group">
<div class="col-sm-8 col-sm-offset-3">
<button type="button" class="btn btn-primary" onclick="submitHandler()">保存</button>
<button type="button" class="btn btn-danger" onclick="$.modal.close()">取消</button>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label is-required">维保类型:</label>
<div class="col-sm-8">
<select name="typeCode" class="form-control" th:with="type=${@dict.getType('main_type')}" required>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{typeCode}"></option>
</select>
</div>
</div>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: datetimepicker-js" />
<th:block th:include="include :: bootstrap-select-js" />
<th:block th:include="include :: bootstrap-fileinput-js" />
<script type="text/javascript">
var prefix = ctx + "tyre/order";
var uploadedFiles = [];
// 从后端获取已存在的图片
var existingFiles = [[${attachments}]] || [];
// 初始化已存在的图片URL数组
$(function() {
if (existingFiles && existingFiles.length > 0) {
$.each(existingFiles, function(index, item) {
if (item.filePath) {
uploadedFiles.push(item.filePath);
}
});
updateAttachmentUrls();
}
});
// 页面加载完成后执行
$(function() {
// 初始化日期插件
$("#form-order-edit input[name='maintainDate']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
// 初始化表单验证
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">维修站点/修理厂ID</label>
<div class="col-sm-8">
<input name="factoryId" th:field="*{factoryId}" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">仪表盘录入里程:</label>
<div class="col-sm-8">
<input name="inputMileage" th:field="*{inputMileage}" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">上次维保里程:</label>
<div class="col-sm-8">
<input name="lastMileage" th:field="*{lastMileage}" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">保养日期:</label>
<div class="col-sm-8">
<div class="input-group date">
<input name="maintainDate" th:value="${#dates.format(bizMaintenanceOrder.maintainDate, 'yyyy-MM-dd')}" class="form-control" placeholder="yyyy-MM-dd" type="text">
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
</div>
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">补充说明:</label>
<div class="col-sm-8">
<textarea name="description" class="form-control">[[*{description}]]</textarea>
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">状态:</label>
<div class="col-sm-8">
<select name="status" class="form-control" th:with="type=${@dict.getType('order_status')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{status}"></option>
</select>
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">1代表汽车、2代表轮胎</label>
<div class="col-sm-8">
<input name="orderType" th:field="*{orderType}" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">备注:</label>
<div class="col-sm-8">
<textarea name="remark" class="form-control">[[*{remark}]]</textarea>
</div>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: datetimepicker-js" />
<script th:inline="javascript">
var prefix = ctx + "system/order";
$("#form-order-edit").validate({
focusCleanup: true
});
// 初始化selectpicker
initSelectPicker();
// 初始化文件上传
initFileInput();
// 加载车辆列表和站点列表
loadVehicleList();
loadFactoryList();
// 绑定已存在图片的预览和删除事件
bindExistingImageEvents();
});
// 绑定已存在图片的事件
function bindExistingImageEvents() {
// 图片预览
$(document).on('click', '.preview-img', function() {
var imgSrc = $(this).attr('src');
var imgTitle = $(this).attr('alt') || '工单图片';
previewImage(imgSrc, imgTitle);
});
// 删除图片
$(document).on('click', '.remove-btn', function() {
var $item = $(this).closest('.uploaded-image-item');
var fileUrl = $item.data('url');
removeExistingImage(fileUrl, $item);
});
}
// 初始化selectpicker
function initSelectPicker() {
try {
$('.selectpicker').selectpicker({
liveSearch: true,
liveSearchPlaceholder: '请输入关键词搜索...',
noneSelectedText: '请选择',
noneResultsText: '没有找到匹配的结果'
});
} catch (e) {
console.error('selectpicker初始化失败:', e);
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/edit", $('#form-order-edit').serialize());
}
}
}
// 初始化bootstrap-fileinput
function initFileInput() {
try {
var $fileInput = $("#orderImages");
if ($fileInput.length === 0) {
console.error('文件输入框不存在');
return;
}
$fileInput.fileinput({
theme: 'fa',
language: 'zh',
uploadUrl: prefix + '/uploadImage',
uploadAsync: true,
maxFileCount: 10,
maxFileSize: 20480,
allowedFileExtensions: ['jpg', 'jpeg', 'png'],
showUpload: true,
showRemove: true,
showPreview: true,
showClose: false,
showCaption: true,
browseOnZoneClick: true,
autoReplace: false,
browseClass: "btn btn-primary",
browseLabel: "选择图片",
browseIcon: "<i class='glyphicon glyphicon-folder-open'></i>&nbsp;",
removeClass: "btn btn-default",
removeLabel: "删除",
removeIcon: "<i class='glyphicon glyphicon-trash'></i>&nbsp;",
uploadClass: "btn btn-info",
uploadLabel: "上传",
uploadIcon: "<i class='glyphicon glyphicon-upload'></i>&nbsp;",
msgPlaceholder: "选择图片...",
msgSizeTooLarge: "文件 \"{name}\" ({size} KB) 超过了最大限制 {maxSize} KB。",
msgInvalidFileExtension: "文件 \"{name}\" 格式不正确。只支持 \"{extensions}\" 格式的文件。",
msgFilesTooMany: "选择的文件数量({n})超过了最大限制{m}。",
dropZoneTitle: "拖拽图片到这里 &hellip;<br>或点击选择按钮",
dropZoneClickTitle: "<br>(或点击选择{files})",
fileActionSettings: {
showUpload: false,
showRemove: true
}
}).on('fileuploaded', function(event, data, previewId, index) {
var response = data.response;
if (response.code == 0) {
var fileUrl = response.url;
uploadedFiles.push(fileUrl);
updateAttachmentUrls();
$.modal.msgSuccess('上传成功');
} else {
$.modal.alertError(response.msg || '上传失败');
}
}).on('fileuploaderror', function(event, data, msg) {
$.modal.alertError('上传失败: ' + msg);
}).on('fileerror', function(event, data, msg) {
$.modal.alertError('文件错误: ' + msg);
});
} catch (e) {
console.error('fileinput初始化失败:', e);
}
}
// 加载车辆列表
function loadVehicleList() {
$.ajax({
url: ctx + "tyre/car/list",
type: "post",
dataType: "json",
success: function(data) {
var select = $("#vehicleSelect");
select.empty();
select.append('<option value="">请选择车辆</option>');
$.each(data.rows || data, function(index, item) {
select.append('<option value="' + item.id + '" data-plate="' + item.carNo + '">' + item.carNo + ' - ' + (item.team || '') + '</option>');
});
// 设置选中的车辆
var selectedVehicleId = [[${bizMaintenanceOrder.vehicleId}]];
if (selectedVehicleId) {
select.val(selectedVehicleId);
}
select.selectpicker('refresh');
},
error: function() {
$.modal.alertError("加载车辆列表失败");
}
$("input[name='maintainDate']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
}
// 加载站点列表
function loadFactoryList() {
$.ajax({
url: prefix + "/getFactoryList",
type: "get",
dataType: "json",
success: function(data) {
var select = $("#factorySelect");
select.empty();
select.append('<option value="">请选择站点</option>');
$.each(data.data, function(index, item) {
select.append('<option value="' + item.deptId + '">' + item.deptName + '</option>');
});
// 设置选中的站点
var selectedFactoryId = [[${bizMaintenanceOrder.factoryId}]];
if (selectedFactoryId) {
select.val(selectedFactoryId);
}
select.selectpicker('refresh');
},
error: function() {
$.modal.alertError("加载站点列表失败");
}
});
}
// 车辆选择事件
$(document).on("changed.bs.select", "#vehicleSelect", function(e, clickedIndex, isSelected, previousValue) {
var selectedOption = $(this).find("option:selected");
var plateNumber = selectedOption.data("plate");
$("#plateNumber").val(plateNumber || "");
});
// 更新隐藏字段的值
function updateAttachmentUrls() {
$('#attachmentUrls').val(uploadedFiles.join(','));
}
// 图片点击预览
function previewImage(imgSrc, imgTitle) {
layer.open({
type: 1,
title: imgTitle || '工单图片',
shadeClose: true,
shade: 0.8,
area: ['90%', '90%'],
content: '<div style="text-align:center; padding: 20px;"><img src="' + imgSrc + '" style="max-width:100%;max-height:100%;" /></div>'
});
}
// 删除已存在的图片
function removeExistingImage(fileUrl, $element) {
$.modal.confirm("确定删除该图片吗?", function() {
// 从数组中移除
uploadedFiles = uploadedFiles.filter(function(url) {
return url !== fileUrl;
});
updateAttachmentUrls();
// 从DOM中移除
$element.remove();
// 如果没有图片了,隐藏整个区域
if ($('#existingImages .uploaded-image-item').length === 0) {
$('.existing-images').hide();
}
$.modal.msgSuccess('删除成功,保存后生效');
});
}
// 表单提交
function submitHandler() {
if ($.validate.form()) {
var data = $("#form-order-edit").serializeArray();
// 添加图片附件URL
var attachmentUrls = uploadedFiles.join(',');
data.push({"name": "attachmentUrls", "value": attachmentUrls});
$.operate.saveTab(prefix + "/edit", data);
}
}
</script>
</script>
</body>
</html>
</html>

@ -1,7 +1,7 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('补胎工单列表')" />
<th:block th:include="include :: header('维保工单列表')" />
</head>
<body class="gray-bg">
<div class="container-div">
@ -10,10 +10,6 @@
<form id="formId">
<div class="select-list">
<ul>
<li>
<label>工单编号:</label>
<input type="text" name="orderNo"/>
</li>
<li>
<label>车牌号码:</label>
<input type="text" name="plateNumber"/>
@ -22,17 +18,23 @@
<label>维保类型:</label>
<select name="typeCode" th:with="type=${@dict.getType('main_type')}">
<option value="">所有</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
<option th:each="dict : ${type}" th:if="${dict.dictValue == '1'} or ${dict.dictValue == '4'}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</li>
<li>
<label>维修站点:</label>
<input type="text" name="factoryId"/>
</li>
<!-- <li>-->
<!-- <label>保养日期:</label>-->
<!-- <input type="text" class="time-input" placeholder="请选择保养日期" name="maintainDate"/>-->
<!-- </li>-->
<li>
<label>状态:</label>
<select name="status" th:with="type=${@dict.getType('order_status')}">
<option value="">所有</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
@ -44,21 +46,18 @@
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-success" onclick="$.operate.addTab()" shiro:hasPermission="system:order:submit">
<i class="fa fa-pencil"></i> 提交工单
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="system:order:add">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="system:order:edit">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="system:order:remove">
<i class="fa fa-remove"></i> 删除
</a>
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="system:order:export">
<i class="fa fa-download"></i> 导出
</a>
<!-- <a class="btn btn-primary single disabled" onclick="$.operate.editTab()" shiro:hasPermission="system:order:edit">-->
<!-- <i class="fa fa-edit"></i> 编辑-->
<!-- </a>-->
<!-- <a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="system:order:remove">-->
<!-- <i class="fa fa-remove"></i> 删除-->
<!-- </a>-->
<!-- <a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="system:order:export">-->
<!-- <i class="fa fa-download"></i> 导出-->
<!-- </a>-->
<!-- <a class="btn btn-info" onclick="$.operate.view()" shiro:hasPermission="system:order:view">-->
<!-- <i class="fa fa-eye"></i> 查看详情-->
<!-- </a>-->
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
@ -69,25 +68,18 @@
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('system:order:edit')}]];
var removeFlag = [[${@permission.hasPermi('system:order:remove')}]];
var viewFlag = [[${@permission.hasPermi('system:order:view')}]];
var typeCodeDatas = [[${@dict.getType('main_type')}]];
var statusDatas = [[${@dict.getType('order_status')}]];
var prefix = ctx + "tyre/order";
function showDetail(orderId) {
// 这里使用了若依框架常用的 $.modal.open 方法
// 如果你的框架没有这个方法,可以使用 Bootstrap 的 Modal 手动填充数据
$.modal.open("轮胎详情", prefix + "/detail/" + orderId);
// 或者如果你是弹出一个包含详细信息的 Alert
// $.modal.alertSuccess("你点击的轮胎ID是: " + tyreId);
}
$(function() {
var options = {
url: prefix + "/list",
createUrl: prefix + "/submit",
url: prefix + "/listMaintenanceOrder",
createUrl: prefix + "/add",
updateUrl: prefix + "/edit/{id}",
removeUrl: prefix + "/remove",
exportUrl: prefix + "/export",
modalName: "补胎工单",
modalName: "维保工单",
columns: [{
checkbox: true
},
@ -100,6 +92,10 @@
field: 'orderNo',
title: '工单编号'
},
{
field: 'vehicleId',
title: '车辆ID/轮胎ID'
},
{
field: 'plateNumber',
title: '车牌号码'
@ -107,31 +103,21 @@
{
field: 'typeCode',
title: '维保类型',
formatter: function(value, item, index) {
if (item.typeCode == '1') {
return '二级保养';
}
else if (item.typeCode == '2') {
return '抢碎修';
}
else if (item.typeCode == '3') {
return '拆报废车';
}
else if (item.typeCode == '4') {
return '月检';
}
else if (item.typeCode == '5') {
return '小修';
}
formatter: function(value, row, index) {
return $.table.selectDictLabel(typeCodeDatas, value);
}
},
{
field: 'factoryId',
title: '维修站点/修理厂ID'
},
{
field: 'inputMileage',
title: '录入里程'
title: '仪表盘录入里程'
},
{
field: 'lastMileage',
title: '上次里程'
title: '上次维保里程'
},
{
field: 'maintainDate',
@ -141,68 +127,33 @@
field: 'description',
title: '补充说明'
},
{
field: 'factoryName',
title: '维修站点'
},
{
field: 'status',
title: '状态',
formatter: function(value, row, index) {
if (value === 'UNSTARTED') return '<span class="label label-warning">未开始</span>';
if (value === 'PROCESSING') return '<span class="label label-primary">执行中</span>';
if (value === 'COMPLETED') return '<span class="label label-success">已完成</span>';
return value;
return $.table.selectDictLabel(statusDatas, value);
}
},
{
field: 'createBy',
title: '创建人'
field: 'orderType',
title: '1代表汽车、2代表轮胎'
},
{
field: 'createTime',
title: '提交日期'
},
{
field: 'maintainer',
title: '修补人'
},
{
field: 'maintainerDate',
title: '修补日期'
field: 'remark',
title: '备注'
},
{
title: '操作',
align: 'center',
formatter: function(value, row, index) {
var actions = [];
if(row.status == 'UNSTARTED'){
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.editTab(\'' + row.orderId + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.orderId + '\')"><i class="fa fa-remove"></i>删除</a>');
}
actions.push('<a class="btn btn-info btn-xs ' + viewFlag + '" href="javascript:void(0)" onclick="showDetail(\'' + row.orderId + '\')"><i class="fa fa-eye"></i>详情</a> ');
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.orderId + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.orderId + '\')"><i class="fa fa-remove"></i>删除</a>');
return actions.join('');
}
}]
};
$.table.init(options);
// 初始化日期插件
$("#formId input[name='maintainDate']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
// 提交工单新窗口
$.operate.openNewWindow = function(url) {
if (url === 'submit') {
$.modal.open("提交工单", prefix + "/submit", "800", "600");
} else {
$.modal.open("详情查看", url, "900", "700");
}
};
});
</script>
</body>

@ -1,193 +0,0 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('报废工单列表')" />
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="formId">
<div class="select-list">
<ul>
<li>
<label>工单编号:</label>
<input type="text" name="orderNo"/>
</li>
<li>
<label>车牌号码:</label>
<input type="text" name="plateNumber"/>
</li>
<li>
<label>状态:</label>
<select name="status" th:with="type=${@dict.getType('order_status')}">
<option value="">所有</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i>&nbsp;重置</a>
</li>
</ul>
</div>
</form>
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<!-- <a class="btn btn-success" onclick="$.operate.addTab()" shiro:hasPermission="system:order:submit">-->
<!-- <i class="fa fa-pencil"></i> 提交工单-->
<!-- </a>-->
<!-- <a class="btn btn-primary single disabled" onclick="$.operate.editTab()" shiro:hasPermission="system:order:edit">-->
<!-- <i class="fa fa-edit"></i> 编辑-->
<!-- </a>-->
<!-- <a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="system:order:remove">-->
<!-- <i class="fa fa-remove"></i> 删除-->
<!-- </a>-->
<!-- <a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="system:order:export">-->
<!-- <i class="fa fa-download"></i> 导出-->
<!-- </a>-->
<!-- <a class="btn btn-info" onclick="$.operate.view()" shiro:hasPermission="system:order:view">-->
<!-- <i class="fa fa-eye"></i> 查看详情-->
<!-- </a>-->
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('system:order:edit')}]];
var removeFlag = [[${@permission.hasPermi('system:order:remove')}]];
var viewFlag = [[${@permission.hasPermi('system:order:view')}]];
var prefix = ctx + "tyre/order";
function showDetail(orderId) {
// 这里使用了若依框架常用的 $.modal.open 方法
// 如果你的框架没有这个方法,可以使用 Bootstrap 的 Modal 手动填充数据
$.modal.open("轮胎详情", prefix + "/detail/" + orderId);
// 或者如果你是弹出一个包含详细信息的 Alert
// $.modal.alertSuccess("你点击的轮胎ID是: " + tyreId);
}
$(function() {
var options = {
url: prefix + "/listScrap",
modalName: "补胎工单",
columns: [{
checkbox: true
},
{
field: 'orderId',
title: '工单ID',
visible: false
},
{
field: 'orderNo',
title: '工单编号'
},
{
field: 'plateNumber',
title: '车牌号码'
},
{
field: 'typeCode',
title: '维保类型',
formatter: function(value, item, index) {
if (item.typeCode == '1') {
return '二级保养';
}
else if (item.typeCode == '2') {
return '抢碎修';
}
else if (item.typeCode == '3') {
return '拆报废车';
}
else if (item.typeCode == '4') {
return '月检';
}
else if (item.typeCode == '5') {
return '小修';
}
}
},
{
field: 'inputMileage',
title: '录入里程'
},
{
field: 'lastMileage',
title: '上次里程'
},
{
field: 'maintainDate',
title: '保养日期'
},
{
field: 'description',
title: '补充说明'
},
{
field: 'factoryName',
title: '维修站点'
},
{
field: 'status',
title: '状态',
formatter: function(value, row, index) {
if (value === 'UNSTARTED') return '<span class="label label-warning">未开始</span>';
if (value === 'PROCESSING') return '<span class="label label-primary">执行中</span>';
if (value === 'COMPLETED') return '<span class="label label-success">已完成</span>';
return value;
}
},
{
field: 'createBy',
title: '创建人'
},
{
field: 'createTime',
title: '提交日期'
},
{
field: 'maintainer',
title: '修补人'
},
{
field: 'maintainerDate',
title: '修补日期'
},
{
title: '操作',
align: 'center',
formatter: function(value, row, index) {
var actions = [];
actions.push('<a class="btn btn-info btn-xs ' + viewFlag + '" href="javascript:void(0)" onclick="showDetail(\'' + row.orderId + '\')"><i class="fa fa-eye"></i>详情</a> ');
return actions.join('');
}
}]
};
$.table.init(options);
// 初始化日期插件
$("#formId input[name='maintainDate']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
// 提交工单新窗口
$.operate.openNewWindow = function(url) {
if (url === 'submit') {
$.modal.open("提交工单", prefix + "/submit", "800", "600");
} else {
$.modal.open("详情查看", url, "900", "700");
}
};
});
</script>
</body>
</html>

@ -1,373 +0,0 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<th:block th:include="include :: header('提交补胎工单')" />
<th:block th:include="include :: datetimepicker-css" />
<th:block th:include="include :: bootstrap-fileinput-css" />
<th:block th:include="include :: bootstrap-select-css" />
<style>
/* 图片预览样式 */
.file-preview-frame {
position: relative;
display: inline-block;
margin: 5px;
}
.file-preview-image {
width: 100px;
height: 100px;
object-fit: cover;
border-radius: 4px;
border: 1px solid #ddd;
}
.file-remove-btn {
position: absolute;
top: -8px;
right: -8px;
background: #dc3545;
color: white;
border: none;
border-radius: 50%;
width: 20px;
height: 20px;
line-height: 18px;
text-align: center;
cursor: pointer;
font-size: 12px;
z-index: 10;
}
.uploaded-images {
margin-top: 15px;
}
.uploaded-image-item {
position: relative;
display: inline-block;
margin: 5px;
}
.uploaded-image-item img {
width: 100px;
height: 100px;
object-fit: cover;
border-radius: 4px;
border: 1px solid #ddd;
}
.uploaded-image-item .remove-btn {
position: absolute;
top: -8px;
right: -8px;
background: #dc3545;
color: white;
border: none;
border-radius: 50%;
width: 20px;
height: 20px;
line-height: 18px;
text-align: center;
cursor: pointer;
font-size: 12px;
}
</style>
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-order-submit">
<input name="orderType" type="hidden" value="1"/>
<input name="status" type="hidden" value="UNSTARTED"/>
<input type="hidden" id="attachmentUrls" name="attachmentUrls">
<!-- 车辆信息选择 -->
<div class="form-group">
<label class="col-sm-3 control-label is-required">车辆信息:</label>
<div class="col-sm-8">
<select name="vehicleId" class="form-control selectpicker" id="vehicleSelect" data-live-search="true" required>
<option value="">请选择车辆</option>
</select>
</div>
</div>
<!-- 车牌号码(自动填充) -->
<div class="form-group" style="display: none">
<label class="col-sm-3 control-label is-required">车牌号码:</label>
<div class="col-sm-8">
<input name="plateNumber" class="form-control" type="text" id="plateNumber" placeholder="车牌号码" readonly required>
</div>
</div>
<!-- 工单类型 -->
<div class="form-group">
<label class="col-sm-3 control-label is-required">维保类型:</label>
<div class="col-sm-8">
<select name="typeCode" class="form-control" id="typeCode" required th:with="type=${@dict.getType('main_type')}">
<option value=""></option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</div>
</div>
<!-- 执行站点 -->
<div class="form-group">
<label class="col-sm-3 control-label is-required">执行站点:</label>
<div class="col-sm-8">
<select name="factoryId" class="form-control selectpicker" id="factorySelect" data-live-search="true" required>
<option value="">请选择站点</option>
</select>
</div>
</div>
<!-- 仪表盘录入里程 -->
<div class="form-group">
<label class="col-sm-3 control-label">仪表盘录入里程:</label>
<div class="col-sm-8">
<input name="inputMileage" class="form-control" type="number" step="0.01" placeholder="请输入当前里程(km)">
</div>
</div>
<!-- 上次维保里程 -->
<div class="form-group">
<label class="col-sm-3 control-label">上次维保里程:</label>
<div class="col-sm-8">
<input name="lastMileage" class="form-control" type="number" step="0.01" placeholder="请输入上次维保里程(km)">
</div>
</div>
<!-- 保养日期 -->
<div class="form-group">
<label class="col-sm-3 control-label is-required">保养日期:</label>
<div class="col-sm-8">
<div class="input-group date">
<input name="maintainDate" class="form-control" placeholder="yyyy-MM-dd" type="text">
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
</div>
</div>
</div>
<!-- 补充说明 -->
<div class="form-group">
<label class="col-sm-3 control-label">补充说明:</label>
<div class="col-sm-8">
<textarea name="description" class="form-control" rows="3" placeholder="请输入补充说明"></textarea>
</div>
</div>
<!-- 上传图片 -->
<!-- <div class="form-group">-->
<!-- <label class="col-sm-3 control-label">上传图片:</label>-->
<!-- <div class="col-sm-8">-->
<!-- <div class="file-loading">-->
<!-- <input id="orderImages" name="files" type="file" multiple>-->
<!-- </div>-->
<!-- <div class="uploaded-images" id="uploadedImages">-->
<!-- &lt;!&ndash; 已上传图片预览区域 &ndash;&gt;-->
<!-- </div>-->
<!-- <span class="help-block">可上传多张图片支持jpg、png格式单张不超过20MB</span>-->
<!-- </div>-->
<!-- </div>-->
<div class="form-group">
<div class="col-sm-8 col-sm-offset-3">
<button type="button" class="btn btn-primary" onclick="submitHandler()">提交</button>
<button type="button" class="btn btn-danger" onclick="$.modal.close()">取消</button>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: datetimepicker-js" />
<th:block th:include="include :: bootstrap-select-js" />
<th:block th:include="include :: bootstrap-fileinput-js" />
<script type="text/javascript">
var prefix = ctx + "tyre/order";
var uploadedFiles = [];
// 页面加载完成后执行
$(function() {
// 初始化日期插件
$("#form-order-submit input[name='maintainDate']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
// 初始化表单验证
$("#form-order-submit").validate({
focusCleanup: true
});
// 初始化selectpicker
initSelectPicker();
// 初始化文件上传
initFileInput();
// 加载车辆列表和站点列表
loadVehicleList();
loadFactoryList();
});
// 初始化selectpicker
function initSelectPicker() {
try {
$('.selectpicker').selectpicker({
liveSearch: true,
liveSearchPlaceholder: '请输入关键词搜索...',
noneSelectedText: '请选择',
noneResultsText: '没有找到匹配的结果'
});
} catch (e) {
console.error('selectpicker初始化失败:', e);
}
}
// 初始化bootstrap-fileinput
function initFileInput() {
try {
var $fileInput = $("#orderImages");
if ($fileInput.length === 0) {
console.error('文件输入框不存在');
return;
}
$fileInput.fileinput({
theme: 'fa',
language: 'zh',
uploadUrl: prefix + '/uploadImage',
uploadAsync: true,
maxFileCount: 10,
maxFileSize: 20480,
allowedFileExtensions: ['jpg', 'jpeg', 'png'],
showUpload: true,
showRemove: true,
showPreview: true,
showClose: false,
showCaption: true,
browseOnZoneClick: true,
autoReplace: false,
browseClass: "btn btn-primary",
browseLabel: "选择图片",
browseIcon: "<i class='glyphicon glyphicon-folder-open'></i>&nbsp;",
removeClass: "btn btn-default",
removeLabel: "删除",
removeIcon: "<i class='glyphicon glyphicon-trash'></i>&nbsp;",
uploadClass: "btn btn-info",
uploadLabel: "上传",
uploadIcon: "<i class='glyphicon glyphicon-upload'></i>&nbsp;",
msgPlaceholder: "选择图片...",
msgSizeTooLarge: "文件 \"{name}\" ({size} KB) 超过了最大限制 {maxSize} KB。",
msgInvalidFileExtension: "文件 \"{name}\" 格式不正确。只支持 \"{extensions}\" 格式的文件。",
msgFilesTooMany: "选择的文件数量({n})超过了最大限制{m}。",
dropZoneTitle: "拖拽图片到这里 &hellip;<br>或点击选择按钮",
dropZoneClickTitle: "<br>(或点击选择{files})",
fileActionSettings: {
showUpload: false,
showRemove: true
}
}).on('fileuploaded', function(event, data, previewId, index) {
var response = data.response;
if (response.code == 0) {
var fileUrl = response.url;
uploadedFiles.push(fileUrl);
updateAttachmentUrls();
$.modal.msgSuccess('上传成功');
} else {
$.modal.alertError(response.msg || '上传失败');
}
}).on('fileuploaderror', function(event, data, msg) {
$.modal.alertError('上传失败: ' + msg);
}).on('fileerror', function(event, data, msg) {
$.modal.alertError('文件错误: ' + msg);
});
} catch (e) {
console.error('fileinput初始化失败:', e);
}
}
// 加载车辆列表
function loadVehicleList() {
$.ajax({
url: prefix + "/getCarList",
type: "get",
dataType: "json",
success: function(data) {
var select = $("#vehicleSelect");
select.empty();
select.append('<option value="">请选择车辆</option>');
$.each(data.data || data, function(index, item) {
select.append('<option value="' + item.id + '" data-plate="' + item.carNo + '">' + item.carNo + ' - ' + (item.team || '') + '</option>');
});
select.selectpicker('refresh');
},
error: function() {
$.modal.alertError("加载车辆列表失败");
}
});
}
// 加载站点列表
function loadFactoryList() {
$.ajax({
url: prefix + "/getFactoryList",
type: "get",
dataType: "json",
success: function(data) {
var select = $("#factorySelect");
select.empty();
select.append('<option value="">请选择站点</option>');
$.each(data.data, function(index, item) {
select.append('<option value="' + item.deptId + '">' + item.deptName + '</option>');
});
select.selectpicker('refresh');
},
error: function() {
$.modal.alertError("加载站点列表失败");
}
});
}
// 车辆选择事件
$(document).on("changed.bs.select", "#vehicleSelect", function(e, clickedIndex, isSelected, previousValue) {
var selectedOption = $(this).find("option:selected");
var plateNumber = selectedOption.data("plate");
$("#plateNumber").val(plateNumber || "");
});
// 更新隐藏字段的值
function updateAttachmentUrls() {
$('#attachmentUrls').val(uploadedFiles.join(','));
}
// 删除已上传的文件
function removeUploadedFile(fileUrl) {
$.ajax({
url: prefix + '/deleteImage',
type: 'post',
data: { filePath: fileUrl },
success: function(response) {
if (response.code == 0) {
uploadedFiles = uploadedFiles.filter(function(url) {
return url !== fileUrl;
});
updateAttachmentUrls();
$('.uploaded-image-item[data-url="' + fileUrl + '"]').remove();
$.modal.msgSuccess('删除成功');
} else {
$.modal.alertError(response.msg || '删除失败');
}
}
});
}
// 表单提交
function submitHandler() {
if ($.validate.form()) {
var data = $("#form-order-submit").serializeArray();
// 添加图片附件URL
var attachmentUrls = uploadedFiles.join(',');
data.push({"name": "attachmentUrls", "value": attachmentUrls});
$.operate.saveTab(prefix + "/submit", data);
}
}
</script>
</body>
</html>

@ -344,6 +344,7 @@ public class ShiroConfig
filterChainDefinitionMap.put("/tyre/car/queryCarByRfid", "anon,captchaValidate");
filterChainDefinitionMap.put("/system/package/checkUpdate", "anon,captchaValidate");
filterChainDefinitionMap.put("/common/downloadApk", "anon,captchaValidate");
filterChainDefinitionMap.put("/tyre/order/PDAGetMaintenanceOrder", "anon,captchaValidate");
// 系统权限列表
// filterChainDefinitionMap.putAll(SpringUtils.getBean(IMenuService.class).selectPermsAll());

@ -5,7 +5,10 @@ import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import javax.validation.constraints.NotBlank;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
/**
* base_car

@ -5,7 +5,10 @@ import com.ruoyi.common.core.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import javax.validation.constraints.NotBlank;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
/**
* base_tyre

@ -2,8 +2,6 @@ package com.ruoyi.system.domain;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
@ -11,10 +9,10 @@ import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* biz_maintenance_order
* biz_maintenance_order
*
* @author xins
* @date 2026-04-15
* @author yangwl
* @date 2026-04-16
*/
public class BizMaintenanceOrder extends BaseEntity
{
@ -32,7 +30,7 @@ public class BizMaintenanceOrder extends BaseEntity
private Long vehicleId;
/** 车牌号码(冗余字段,便于查询) */
@Excel(name = "车牌号码", readConverterExp = "冗余字段,便于查询")
@Excel(name = "车牌号码", readConverterExp = "冗=余字段,便于查询")
private String plateNumber;
/** 维保类型(如:二级保养) */
@ -44,15 +42,15 @@ public class BizMaintenanceOrder extends BaseEntity
private Long factoryId;
/** 仪表盘录入里程(截图中的必填项) */
@Excel(name = "仪表盘录入里程", readConverterExp = "截图中的必填项")
@Excel(name = "仪表盘录入里程", readConverterExp = "截=图中的必填项")
private BigDecimal inputMileage;
/** 上次维保里程(快照) */
@Excel(name = "上次维保里程", readConverterExp = "快照")
@Excel(name = "上次维保里程", readConverterExp = "快=照")
private BigDecimal lastMileage;
/** 保养日期 */
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "保养日期", width = 30, dateFormat = "yyyy-MM-dd")
private Date maintainDate;
@ -61,29 +59,13 @@ public class BizMaintenanceOrder extends BaseEntity
private String description;
/** 状态UNSTARTED未开始, PROCESSING执行中, COMPLETED已完成 */
@Excel(name = "状态", readConverterExp = "UNSTARTED未开始, PROCESSING执行中, COMPLETED已完成")
@Excel(name = "状态", readConverterExp = "U=NSTARTED未开始,,P=ROCESSING执行中,,C=OMPLETED已完成")
private String status;
/** 1代表汽车、2代表轮胎 */
@Excel(name = "1代表汽车、2代表轮胎")
private String orderType;
/** 维修站点名称(扩展字段,用于显示) */
@Excel(name = "维修站点")
private String factoryName;
/** 维修人 */
@Excel(name = "维修人")
private String maintainer;
/** 维修日期 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "维修日期", width = 30, dateFormat = "yyyy-MM-dd")
private Date maintainerDate;
/** 轮胎明细列表 */
private List<BizOrderTireDetail> tireDetails;
public void setOrderId(Long orderId)
{
this.orderId = orderId;
@ -93,6 +75,7 @@ public class BizMaintenanceOrder extends BaseEntity
{
return orderId;
}
public void setOrderNo(String orderNo)
{
this.orderNo = orderNo;
@ -102,6 +85,7 @@ public class BizMaintenanceOrder extends BaseEntity
{
return orderNo;
}
public void setVehicleId(Long vehicleId)
{
this.vehicleId = vehicleId;
@ -111,6 +95,7 @@ public class BizMaintenanceOrder extends BaseEntity
{
return vehicleId;
}
public void setPlateNumber(String plateNumber)
{
this.plateNumber = plateNumber;
@ -120,6 +105,7 @@ public class BizMaintenanceOrder extends BaseEntity
{
return plateNumber;
}
public void setTypeCode(String typeCode)
{
this.typeCode = typeCode;
@ -129,6 +115,7 @@ public class BizMaintenanceOrder extends BaseEntity
{
return typeCode;
}
public void setFactoryId(Long factoryId)
{
this.factoryId = factoryId;
@ -138,6 +125,7 @@ public class BizMaintenanceOrder extends BaseEntity
{
return factoryId;
}
public void setInputMileage(BigDecimal inputMileage)
{
this.inputMileage = inputMileage;
@ -147,6 +135,7 @@ public class BizMaintenanceOrder extends BaseEntity
{
return inputMileage;
}
public void setLastMileage(BigDecimal lastMileage)
{
this.lastMileage = lastMileage;
@ -156,6 +145,7 @@ public class BizMaintenanceOrder extends BaseEntity
{
return lastMileage;
}
public void setMaintainDate(Date maintainDate)
{
this.maintainDate = maintainDate;
@ -165,6 +155,7 @@ public class BizMaintenanceOrder extends BaseEntity
{
return maintainDate;
}
public void setDescription(String description)
{
this.description = description;
@ -174,6 +165,7 @@ public class BizMaintenanceOrder extends BaseEntity
{
return description;
}
public void setStatus(String status)
{
this.status = status;
@ -183,6 +175,7 @@ public class BizMaintenanceOrder extends BaseEntity
{
return status;
}
public void setOrderType(String orderType)
{
this.orderType = orderType;
@ -193,38 +186,6 @@ public class BizMaintenanceOrder extends BaseEntity
return orderType;
}
public String getFactoryName() {
return factoryName;
}
public void setFactoryName(String factoryName) {
this.factoryName = factoryName;
}
public String getMaintainer() {
return maintainer;
}
public void setMaintainer(String maintainer) {
this.maintainer = maintainer;
}
public Date getMaintainerDate() {
return maintainerDate;
}
public void setMaintainerDate(Date maintainerDate) {
this.maintainerDate = maintainerDate;
}
public List<BizOrderTireDetail> getTireDetails() {
return tireDetails;
}
public void setTireDetails(List<BizOrderTireDetail> tireDetails) {
this.tireDetails = tireDetails;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
@ -245,9 +206,6 @@ public class BizMaintenanceOrder extends BaseEntity
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.append("factoryName", getFactoryName())
.append("maintainer", getMaintainer())
.append("maintainerDate", getMaintainerDate())
.toString();
}
}
}

@ -2,7 +2,10 @@ package com.ruoyi.system.domain.vo;
import com.ruoyi.common.annotation.Excel;
import javax.validation.constraints.NotBlank;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
public class BaseTyreVo {
private static final long serialVersionUID = 1L;

@ -4,7 +4,7 @@ import java.util.List;
public class InStoreSpinnerVo {
private List<String> tyreBrandList;
private List<String> tyreSizeList;
private List<tyreSizeVo> tyreSizeList;
private List<String> levelList;
private List<String> patternList;
private List<String> kindList;
@ -26,11 +26,11 @@ public class InStoreSpinnerVo {
this.tyreBrandList = tyreBrandList;
}
public List<String> getTyreSizeList() {
public List<tyreSizeVo> getTyreSizeList() {
return tyreSizeList;
}
public void setTyreSizeList(List<String> tyreSizeList) {
public void setTyreSizeList(List<tyreSizeVo> tyreSizeList) {
this.tyreSizeList = tyreSizeList;
}
@ -57,4 +57,5 @@ public class InStoreSpinnerVo {
public void setKindList(List<String> kindList) {
this.kindList = kindList;
}
}

@ -0,0 +1,22 @@
package com.ruoyi.system.domain.vo;
public class tyreSizeVo {
private String label;
private String value;
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}

@ -5,6 +5,7 @@ package com.ruoyi.system.mapper;
import com.ruoyi.system.domain.BaseInventory;
import java.util.List;
import java.util.Map;
/**
* Mapper
@ -66,7 +67,7 @@ public interface BaseInventoryMapper
int updateBaseInventoryByEpc(BaseInventory baseInventory);
int querytotal();
Map querytotal();
int queryInCar();

@ -4,109 +4,61 @@ import java.util.List;
import com.ruoyi.system.domain.BizMaintenanceOrder;
/**
* Mapper
* Mapper
*
* @author yangwanli
* @date 2026-04-15
* @author yangwl
* @date 2026-04-16
*/
public interface BizMaintenanceOrderMapper
{
/**
*
*
*
* @param orderId
* @return
* @param orderId
* @return
*/
public BizMaintenanceOrder selectBizMaintenanceOrderById(Long orderId);
public BizMaintenanceOrder selectBizMaintenanceOrderByOrderId(Long orderId);
/**
*
*
*
* @param bizMaintenanceOrder
* @return
* @param bizMaintenanceOrder
* @return
*/
public List<BizMaintenanceOrder> selectBizMaintenanceOrderList(BizMaintenanceOrder bizMaintenanceOrder);
public List<BizMaintenanceOrder> selectBizMaintenanceOrderListTwo(BizMaintenanceOrder bizMaintenanceOrder);
/**
*
*
*
* @param bizMaintenanceOrder
* @param bizMaintenanceOrder
* @return
*/
public int insertBizMaintenanceOrder(BizMaintenanceOrder bizMaintenanceOrder);
/**
*
*
*
* @param bizMaintenanceOrder
* @param bizMaintenanceOrder
* @return
*/
public int updateBizMaintenanceOrder(BizMaintenanceOrder bizMaintenanceOrder);
/**
*
*
*
* @param orderId
* @param orderId
* @return
*/
public int deleteBizMaintenanceOrderById(Long orderId);
public int deleteBizMaintenanceOrderByOrderId(Long orderId);
/**
*
*
*
* @param orderIds
* @return
*/
public int deleteBizMaintenanceOrderByIds(String[] orderIds);
/**
*
*
* @param status
* @return
*/
public int selectOrderCountByStatus(String status);
/**
*
*
* @param plateNumber
* @return
*/
public List<BizMaintenanceOrder> selectOrderByPlateNumber(String plateNumber);
/**
*
*
* @param tireCode
* @return
*/
public List<BizMaintenanceOrder> selectOrderByTireCode(String tireCode);
/**
*
*
* @param orderId ID
* @param status
* @return
*/
public int updateOrderStatus(Long orderId, String status);
/**
*
*
* @param bizMaintenanceOrder
* @return
*/
public List<BizMaintenanceOrder> selectBizRepairOrderList(BizMaintenanceOrder bizMaintenanceOrder);
/**
*
*
* @param bizMaintenanceOrder
* @return
*/
public List<BizMaintenanceOrder> selectBizScrapOrderList(BizMaintenanceOrder bizMaintenanceOrder);
}
public int deleteBizMaintenanceOrderByOrderIds(String[] orderIds);
}

@ -64,4 +64,8 @@ public interface RecordWarehousingMapper
public int deleteRecordWarehousingByIds(String[] ids);
List<Map> selectRecord();
List<Map> selectTyreModel();
List<Map> selectTyreInstall();
}

@ -6,6 +6,7 @@ import com.ruoyi.system.domain.BaseTyre;
import java.util.List;
import java.util.Map;
/**
* Service
@ -67,7 +68,7 @@ public interface IBaseInventoryService
AjaxResult OutInventoryByPda(BaseInventory baseInventory, BaseTyre baseTyre);
int querytotal();
Map querytotal();
int queryInCar();

@ -1,123 +1,63 @@
package com.ruoyi.system.service;
import java.util.List;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.system.domain.BizMaintenanceOrder;
import com.ruoyi.system.domain.BizOrderTireDetail;
/**
* Service
* Service
*
* @author yangwanli
* @date 2026-04-15
* @author yangwl
* @date 2026-04-16
*/
public interface IBizMaintenanceOrderService
{
/**
*
*
*
* @param orderId
* @return
* @param orderId
* @return
*/
public BizMaintenanceOrder selectBizMaintenanceOrderById(Long orderId);
public BizMaintenanceOrder selectBizMaintenanceOrderByOrderId(Long orderId);
/**
*
*
*
* @param bizMaintenanceOrder
* @return
* @param bizMaintenanceOrder
* @return
*/
public List<BizMaintenanceOrder> selectBizMaintenanceOrderList(BizMaintenanceOrder bizMaintenanceOrder);
/**
*
*
*
* @param bizMaintenanceOrder
* @param bizMaintenanceOrder
* @return
*/
public int insertBizMaintenanceOrder(BizMaintenanceOrder bizMaintenanceOrder);
/**
*
*
*
* @param bizMaintenanceOrder
* @param bizMaintenanceOrder
* @return
*/
public int updateBizMaintenanceOrder(BizMaintenanceOrder bizMaintenanceOrder);
/**
*
*
*
* @param orderIds
* @param orderIds
* @return
*/
public int deleteBizMaintenanceOrderByIds(String orderIds);
public int deleteBizMaintenanceOrderByOrderIds(String orderIds);
/**
*
*
*
* @param orderId
* @param orderId
* @return
*/
public int deleteBizMaintenanceOrderById(Long orderId);
public int deleteBizMaintenanceOrderByOrderId(Long orderId);
/**
*
*
* @param plateNumber
* @return
*/
public List<BizMaintenanceOrder> selectOrderByPlateNumber(String plateNumber);
/**
*
*
* @param tireCode
* @return
*/
public List<BizMaintenanceOrder> selectOrderByTireCode(String tireCode);
/**
*
*
* @param orderId ID
* @param status
* @return
*/
public int updateOrderStatus(Long orderId, String status);
/**
*
*
* @param status
* @return
*/
public int selectOrderCountByStatus(String status);
/**
*
*
* @param bizMaintenanceOrder
* @param tireDetails
* @return
*/
public int saveOrderWithDetails(BizMaintenanceOrder bizMaintenanceOrder, List<BizOrderTireDetail> tireDetails);
/**
*
*
* @param bizMaintenanceOrder
* @return
*/
public List<BizMaintenanceOrder> selectBizRepairOrderList(BizMaintenanceOrder bizMaintenanceOrder);
/**
*
*
* @param bizMaintenanceOrder
* @return
*/
public List<BizMaintenanceOrder> selectBizScrapOrderList(BizMaintenanceOrder bizMaintenanceOrder);
}
List<BizMaintenanceOrder> selectBizMaintenanceOrderListTwo(BizMaintenanceOrder bizMaintenanceOrder);
}

@ -63,4 +63,8 @@ public interface IRecordWarehousingService
public int deleteRecordWarehousingById(Long id);
List<Map> selectRecord();
List<Map> selectTyreModel();
List<Map> selectTyreInstall();
}

@ -14,10 +14,13 @@ import com.ruoyi.system.mapper.BaseTyreMapper;
import com.ruoyi.system.mapper.RecordWarehousingMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.IBaseInventoryService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
* Service
@ -38,6 +41,8 @@ public class BaseInventoryServiceImpl implements IBaseInventoryService
@Autowired
private SysUserMapper sysUserMapper;
private static final Logger log = LoggerFactory.getLogger(BaseInventoryServiceImpl.class);
/**
*
*
@ -120,63 +125,45 @@ public class BaseInventoryServiceImpl implements IBaseInventoryService
//查询登录人的部门信息
SysUser sysUser = sysUserMapper.selectUserByLoginName(baseInventory.getCreateBy());
int m=0,t=0;
if (isbaseInventory!=null){
return AjaxResult.error("该轮胎已在仓库!");
}else {
//插入库存表以及基础信息表
baseInventory.setStatus("0");
baseInventory.setNumber(1L);
baseInventory.setCreateTime(DateUtils.getNowDate());
baseInventory.setUpdateTime(DateUtils.getNowDate());
m = baseInventoryMapper.insertBaseInventory(baseInventory);
//添加入库记录
RecordWarehousing recordWarehousing = new RecordWarehousing();
recordWarehousing.setTyreRfid(baseInventory.getTyreRfid());
recordWarehousing.setType("0");
recordWarehousing.setCreateTime(DateUtils.getNowDate());
recordWarehousing.setCreateBy(baseInventory.getCreateBy());
t= recordWarehousingMapper.insertRecordWarehousing(recordWarehousing);
//查询此轮胎是否在基础信息表里面
BaseTyre baseTyres = baseTyreMapper.selectBaseTyreByEpc(baseTyre);
//查找用户所在的车队
String team = baseTyreMapper.getTeamByUser(baseInventory.getCreateBy());
String patternDepth = null;
switch (baseTyre.getTyreModel().toString().trim()){
case "215/75R17.5 16PR LFL866":
patternDepth = "20";
break;
case "265/70R19.5-18 F820":
patternDepth = "17";
break;
case "11R22.5 16PR LAU802":
patternDepth = "16";
break;
case "245/70R19.5 18PR LAU609":
patternDepth = "20";
break;
case "255/70R22.5 16PR LAU609":
patternDepth = "14";
break;
case "275/70R22.5 18PR LAU802":
patternDepth = "15";
break;
}
if (baseTyres==null){
baseTyre.setTyreNo(baseInventory.getTyreOutsideId());
baseTyre.setCreateTime(DateUtils.getNowDate());
baseTyre.setTeam(team);
baseTyre.setCreateBy(baseInventory.getCreateBy());
baseTyre.setDeptId(sysUser.getDeptId());
baseTyre.setPatternDepth(patternDepth);
baseTyreMapper.insertBaseTyre(baseTyre);
try {
if (isbaseInventory!=null){
return AjaxResult.error("该轮胎已在仓库!");
}else {
baseTyre.setTyreId(baseTyres.getTyreId());
baseTyre.setUpdateTime(DateUtils.getNowDate());
baseTyre.setTeam(team);
baseTyre.setUpdateBy(baseInventory.getCreateBy());
baseTyre.setDeptId(sysUser.getDeptId());
baseTyreMapper.updateBaseTyre(baseTyre);
//插入库存表以及基础信息表
baseInventory.setStatus("0");
baseInventory.setNumber(1L);
baseInventory.setCreateTime(DateUtils.getNowDate());
baseInventory.setUpdateTime(DateUtils.getNowDate());
m = baseInventoryMapper.insertBaseInventory(baseInventory);
//添加入库记录
RecordWarehousing recordWarehousing = new RecordWarehousing();
recordWarehousing.setTyreRfid(baseInventory.getTyreRfid());
recordWarehousing.setType("0");
recordWarehousing.setCreateTime(DateUtils.getNowDate());
recordWarehousing.setCreateBy(baseInventory.getCreateBy());
t= recordWarehousingMapper.insertRecordWarehousing(recordWarehousing);
//查询此轮胎是否在基础信息表里面
BaseTyre baseTyres = baseTyreMapper.selectBaseTyreByEpc(baseTyre);
//查找用户所在的车队
String team = baseTyreMapper.getTeamByUser(baseInventory.getCreateBy());
if (baseTyres==null){
baseTyre.setTyreNo(baseInventory.getTyreOutsideId());
baseTyre.setCreateTime(DateUtils.getNowDate());
baseTyre.setTeam(team);
baseTyre.setCreateBy(baseInventory.getCreateBy());
baseTyre.setDeptId(sysUser.getDeptId());
baseTyreMapper.insertBaseTyre(baseTyre);
}else {
baseTyre.setTyreId(baseTyres.getTyreId());
baseTyre.setUpdateTime(DateUtils.getNowDate());
baseTyre.setTeam(team);
baseTyre.setUpdateBy(baseInventory.getCreateBy());
baseTyre.setDeptId(sysUser.getDeptId());
baseTyreMapper.updateBaseTyre(baseTyre);
}
}
}catch (Exception e){
log.error(e.getMessage());
}
if (m>0&&t>0){
return AjaxResult.success("入库成功");
@ -221,7 +208,7 @@ public class BaseInventoryServiceImpl implements IBaseInventoryService
}
@Override
public int querytotal() {
public Map querytotal() {
return baseInventoryMapper.querytotal();
}

@ -1,26 +1,19 @@
package com.ruoyi.system.service.impl;
import java.util.List;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.system.mapper.BizMaintenanceOrderMapper;
import com.ruoyi.system.domain.BizMaintenanceOrder;
import com.ruoyi.system.service.IBizMaintenanceOrderService;
import com.ruoyi.system.service.IBizOrderTireDetailService;
import com.ruoyi.system.domain.BizOrderTireDetail;
import com.ruoyi.common.core.text.Convert;
/**
* Service
* Service
*
* @author yangwanli
* @date 2026-04-15
* @author yangwl
* @date 2026-04-16
*/
@Service
public class BizMaintenanceOrderServiceImpl implements IBizMaintenanceOrderService
@ -28,208 +21,82 @@ public class BizMaintenanceOrderServiceImpl implements IBizMaintenanceOrderServi
@Autowired
private BizMaintenanceOrderMapper bizMaintenanceOrderMapper;
@Autowired
private IBizOrderTireDetailService bizOrderTireDetailService;
/**
*
*
*
* @param orderId
* @return
* @param orderId
* @return
*/
@Override
public BizMaintenanceOrder selectBizMaintenanceOrderById(Long orderId)
public BizMaintenanceOrder selectBizMaintenanceOrderByOrderId(Long orderId)
{
BizMaintenanceOrder order = bizMaintenanceOrderMapper.selectBizMaintenanceOrderById(orderId);
if (order != null) {
// 查询轮胎明细
List<BizOrderTireDetail> tireDetails = bizOrderTireDetailService.selectTireDetailByOrderId(orderId);
order.setTireDetails(tireDetails);
}
return order;
return bizMaintenanceOrderMapper.selectBizMaintenanceOrderByOrderId(orderId);
}
/**
*
*
*
* @param bizMaintenanceOrder
* @return
* @param bizMaintenanceOrder
* @return
*/
@Override
@DataScope(deptAlias = "d", userAlias = "u")
public List<BizMaintenanceOrder> selectBizMaintenanceOrderList(BizMaintenanceOrder bizMaintenanceOrder)
{
return bizMaintenanceOrderMapper.selectBizMaintenanceOrderList(bizMaintenanceOrder);
}
/**
*
*
*
* @param bizMaintenanceOrder
* @param bizMaintenanceOrder
* @return
*/
@Override
public int insertBizMaintenanceOrder(BizMaintenanceOrder bizMaintenanceOrder)
{
bizMaintenanceOrder.setCreateTime(DateUtils.getNowDate());
bizMaintenanceOrder.setCreateBy(ShiroUtils.getLoginName());
bizMaintenanceOrder.setOrderType("1"); // 默认设置为汽车类型
return bizMaintenanceOrderMapper.insertBizMaintenanceOrder(bizMaintenanceOrder);
}
/**
*
*
*
* @param bizMaintenanceOrder
* @param bizMaintenanceOrder
* @return
*/
@Override
@Transactional
public int updateBizMaintenanceOrder(BizMaintenanceOrder bizMaintenanceOrder)
{
bizMaintenanceOrder.setUpdateTime(DateUtils.getNowDate());
bizMaintenanceOrder.setUpdateBy(ShiroUtils.getLoginName());
return bizMaintenanceOrderMapper.updateBizMaintenanceOrder(bizMaintenanceOrder);
}
/**
*
*
*
* @param orderIds
* @param orderIds
* @return
*/
@Override
@Transactional
public int deleteBizMaintenanceOrderByIds(String orderIds)
public int deleteBizMaintenanceOrderByOrderIds(String orderIds)
{
String[] ids = Convert.toStrArray(orderIds);
for (String id : ids) {
Long orderId = Long.parseLong(id);
// 先删除轮胎明细
bizOrderTireDetailService.deleteTireDetailByOrderId(orderId);
}
return bizMaintenanceOrderMapper.deleteBizMaintenanceOrderByIds(ids);
return bizMaintenanceOrderMapper.deleteBizMaintenanceOrderByOrderIds(Convert.toStrArray(orderIds));
}
/**
*
*
*
* @param orderId
* @param orderId
* @return
*/
@Override
@Transactional
public int deleteBizMaintenanceOrderById(Long orderId)
public int deleteBizMaintenanceOrderByOrderId(Long orderId)
{
// 先删除轮胎明细
bizOrderTireDetailService.deleteTireDetailByOrderId(orderId);
return bizMaintenanceOrderMapper.deleteBizMaintenanceOrderById(orderId);
return bizMaintenanceOrderMapper.deleteBizMaintenanceOrderByOrderId(orderId);
}
/**
*
*
* @param plateNumber
* @return
*/
@Override
public List<BizMaintenanceOrder> selectOrderByPlateNumber(String plateNumber)
{
return bizMaintenanceOrderMapper.selectOrderByPlateNumber(plateNumber);
public List<BizMaintenanceOrder> selectBizMaintenanceOrderListTwo(BizMaintenanceOrder bizMaintenanceOrder) {
return bizMaintenanceOrderMapper.selectBizMaintenanceOrderListTwo(bizMaintenanceOrder);
}
/**
*
*
* @param tireCode
* @return
*/
@Override
public List<BizMaintenanceOrder> selectOrderByTireCode(String tireCode)
{
return bizMaintenanceOrderMapper.selectOrderByTireCode(tireCode);
}
/**
*
*
* @param orderId ID
* @param status
* @return
*/
@Override
public int updateOrderStatus(Long orderId, String status)
{
return bizMaintenanceOrderMapper.updateOrderStatus(orderId, status);
}
/**
*
*
* @param status
* @return
*/
@Override
public int selectOrderCountByStatus(String status)
{
return bizMaintenanceOrderMapper.selectOrderCountByStatus(status);
}
/**
*
*
* @param bizMaintenanceOrder
* @param tireDetails
* @return
*/
@Override
@Transactional
public int saveOrderWithDetails(BizMaintenanceOrder bizMaintenanceOrder, List<BizOrderTireDetail> tireDetails)
{
// 保存工单
bizMaintenanceOrder.setCreateTime(DateUtils.getNowDate());
bizMaintenanceOrder.setCreateBy(ShiroUtils.getLoginName());
bizMaintenanceOrder.setOrderType("1"); // 默认设置为汽车类型
int result = bizMaintenanceOrderMapper.insertBizMaintenanceOrder(bizMaintenanceOrder);
if (result > 0 && tireDetails != null && tireDetails.size() > 0) {
// 保存轮胎明细
for (BizOrderTireDetail detail : tireDetails) {
detail.setOrderId(bizMaintenanceOrder.getOrderId());
detail.setCreateTime(DateUtils.getNowDate());
detail.setCreateBy(ShiroUtils.getLoginName());
}
bizOrderTireDetailService.batchInsertTireDetail(tireDetails);
}
return result;
}
/**
*
*
* @param bizMaintenanceOrder
* @return
*/
@Override
@DataScope(deptAlias = "d", userAlias = "u")
public List<BizMaintenanceOrder> selectBizRepairOrderList(BizMaintenanceOrder bizMaintenanceOrder)
{
return bizMaintenanceOrderMapper.selectBizRepairOrderList(bizMaintenanceOrder);
}
/**
*
*
* @param bizMaintenanceOrder
* @return
*/
@Override
@DataScope(deptAlias = "d", userAlias = "u")
public List<BizMaintenanceOrder> selectBizScrapOrderList(BizMaintenanceOrder bizMaintenanceOrder)
{
return bizMaintenanceOrderMapper.selectBizScrapOrderList(bizMaintenanceOrder);
}
}
}

@ -123,6 +123,7 @@ public class RecordTyreInstallServiceImpl implements IRecordTyreInstallService
baseTyre.setCarNo(recordTyreInstall.getCarNo());
baseTyre.setWheelPostion(recordTyreInstall.getWheelPostion());
baseTyre.setSelfNo(recordTyreInstall.getSelfNo());
baseTyre.setTyreNo(recordTyreInstall.getTyreNo());
int m = baseTyreMapper.updateBaseTyre(baseTyre);
if (n>0&&m>0){
return AjaxResult.success("安装成功!");

@ -104,4 +104,14 @@ public class RecordWarehousingServiceImpl implements IRecordWarehousingService
public List<Map> selectRecord() {
return recordWarehousingMapper.selectRecord();
}
@Override
public List<Map> selectTyreModel() {
return recordWarehousingMapper.selectTyreModel();
}
@Override
public List<Map> selectTyreInstall() {
return recordWarehousingMapper.selectTyreInstall();
}
}

@ -5,6 +5,7 @@ import java.util.List;
import com.ruoyi.system.domain.vo.CheckInfoSpinnerVo;
import com.ruoyi.system.domain.vo.InStoreSpinnerVo;
import com.ruoyi.system.domain.vo.tyreSizeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.core.domain.entity.SysDictData;
@ -133,7 +134,7 @@ public class SysDictDataServiceImpl implements ISysDictDataService
List<String> strings = new ArrayList<>();
List<String> string_pattern = new ArrayList<>();
List<String> string_level = new ArrayList<>();
List<String> string_size = new ArrayList<>();
List<tyreSizeVo> string_size = new ArrayList<>();
List<String> string_brand = new ArrayList<>();
List<String> string_grooves = new ArrayList<>();
InStoreSpinnerVo inStoreSpinnerVo =new InStoreSpinnerVo();
@ -154,11 +155,15 @@ public class SysDictDataServiceImpl implements ISysDictDataService
}
if (sizeList!=null){
for (SysDictData s: sizeList){
string_size.add(s.getDictLabel());
tyreSizeVo tyreSizeVo = new tyreSizeVo();
tyreSizeVo.setLabel(s.getDictLabel());
tyreSizeVo.setValue(s.getRemark());
string_size.add(tyreSizeVo);
}
}
if (brandList!=null){
for (SysDictData s:brandList){
string_brand.add(s.getDictLabel());
}
}

@ -54,15 +54,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="number != null "> and number = #{number}</if>
</where>
</select>
<select id="querytotal" resultType="java.lang.Integer">
SELECT COUNT(*) FROM `base_inventory` WHERE `status` = '0'
</select>
<select id="queryInCar" resultType="java.lang.Integer">
SELECT COUNT(*) FROM `base_tyre` WHERE `car_no` is not null
</select>
<select id="queryCarTotal" resultType="java.lang.Integer">
SELECT COUNT(*) FROM `base_car`
</select>
<select id="querytotal" resultType="java.util.Map">
SELECT
COUNT(bi.id) AS total,
COUNT(CASE WHEN bt.tyre_type IN ('全新胎', 'new') THEN 1 END) AS new,
COUNT(CASE WHEN bt.tyre_type IN ('circulating') THEN 1 END) AS circulating,
COUNT(CASE WHEN bt.tyre_type IN ('renovate') THEN 1 END) AS renovate,
COUNT(CASE WHEN bt.tyre_type IN ('experimental') THEN 1 END) AS experimental
FROM base_inventory bi
INNER JOIN base_tyre bt ON bi.tyre_rfid = bt.tyre_epc
WHERE bi.status = '0';
</select>
<insert id="insertBaseInventory" parameterType="BaseInventory">
insert into base_inventory

@ -22,9 +22,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
<result property="factoryName" column="factory_name" />
<result property="maintainer" column="maintainer" />
<result property="maintainerDate" column="maintainer_date" />
</resultMap>
<sql id="selectBizMaintenanceOrderVo">
@ -32,89 +29,53 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</sql>
<select id="selectBizMaintenanceOrderList" parameterType="BizMaintenanceOrder" resultMap="BizMaintenanceOrderResult">
select o.order_id, o.order_no, o.vehicle_id, o.plate_number, o.type_code, o.factory_id, o.input_mileage, o.last_mileage, o.maintain_date, o.description, o.status, o.order_type, o.create_by, o.create_time, o.update_by, o.update_time, o.remark, d.dept_name as factory_name
from biz_maintenance_order o
left join sys_dept d on d.dept_id = o.factory_id
<include refid="selectBizMaintenanceOrderVo"/>
<where>
<if test="orderNo != null and orderNo != ''"> and o.order_no like concat('%', #{orderNo}, '%')</if>
<if test="plateNumber != null and plateNumber != ''"> and o.plate_number like concat('%', #{plateNumber}, '%')</if>
<if test="typeCode != null and typeCode != ''"> and o.type_code = #{typeCode}</if>
<if test="factoryId != null "> and o.factory_id = #{factoryId}</if>
<if test="inputMileage != null "> and o.input_mileage = #{inputMileage}</if>
<if test="lastMileage != null "> and o.last_mileage = #{lastMileage}</if>
<if test="maintainDate != null "> and o.maintain_date = #{maintainDate}</if>
<if test="description != null and description != ''"> and o.description like concat('%', #{description}, '%')</if>
<if test="status != null and status != ''"> and o.status = #{status}</if>
<if test="orderType != null and orderType != ''"> and o.order_type = #{orderType}</if>
<!-- 按照补胎工单查询 -->
<if test="orderType == null or orderType == ''"> and o.order_type = '1'</if>
${params.dataScope}
<if test="orderNo != null and orderNo != ''"> and order_no = #{orderNo}</if>
<if test="vehicleId != null "> and vehicle_id = #{vehicleId}</if>
<if test="plateNumber != null and plateNumber != ''"> and plate_number = #{plateNumber}</if>
<if test="typeCode != null and typeCode != ''"> and type_code = #{typeCode}</if>
<if test="factoryId != null "> and factory_id = #{factoryId}</if>
<if test="inputMileage != null "> and input_mileage = #{inputMileage}</if>
<if test="lastMileage != null "> and last_mileage = #{lastMileage}</if>
<if test="maintainDate != null "> and maintain_date = #{maintainDate}</if>
<if test="description != null and description != ''"> and description = #{description}</if>
<if test="status != null and status != ''"> and status = #{status}</if>
<if test="orderType != null and orderType != ''"> and order_type = #{orderType}</if>
</where>
order by o.create_time desc
</select>
<select id="selectBizRepairOrderList" parameterType="BizMaintenanceOrder" resultMap="BizMaintenanceOrderResult">
select o.order_id, o.order_no, o.vehicle_id, o.plate_number, o.type_code, o.factory_id, o.input_mileage, o.last_mileage, o.maintain_date, o.description, o.status, o.order_type, o.create_by, o.create_time, o.update_by, o.update_time, o.remark, d.dept_name as factory_name
from biz_maintenance_order o
left join sys_dept d on d.dept_id = o.factory_id
<select id="selectBizMaintenanceOrderListTwo" parameterType="BizMaintenanceOrder" resultMap="BizMaintenanceOrderResult">
<include refid="selectBizMaintenanceOrderVo"/>
<where>
and o.type_code in ('1','2','4','5')
<if test="orderNo != null and orderNo != ''"> and o.order_no like concat('%', #{orderNo}, '%')</if>
<if test="plateNumber != null and plateNumber != ''"> and o.plate_number like concat('%', #{plateNumber}, '%')</if>
<if test="typeCode != null and typeCode != ''"> and o.type_code = #{typeCode}</if>
<if test="factoryId != null "> and o.factory_id = #{factoryId}</if>
<if test="inputMileage != null "> and o.input_mileage = #{inputMileage}</if>
<if test="lastMileage != null "> and o.last_mileage = #{lastMileage}</if>
<if test="maintainDate != null "> and o.maintain_date = #{maintainDate}</if>
<if test="description != null and description != ''"> and o.description like concat('%', #{description}, '%')</if>
<if test="status != null and status != ''"> and o.status = #{status}</if>
<if test="orderType != null and orderType != ''"> and o.order_type = #{orderType}</if>
<!-- 按照补胎工单查询 -->
<if test="orderType == null or orderType == ''"> and o.order_type = '1'</if>
${params.dataScope}
<if test="orderNo != null and orderNo != ''"> and order_no = #{orderNo}</if>
<if test="vehicleId != null "> and vehicle_id = #{vehicleId}</if>
<if test="plateNumber != null and plateNumber != ''"> and plate_number = #{plateNumber}</if>
<if test="typeCode == null or typeCode == ''"> and type_code in ('1','4')</if>
<if test="typeCode != null and typeCode != ''"> and type_code = #{typeCode}</if>
<if test="factoryId != null "> and factory_id = #{factoryId}</if>
<if test="inputMileage != null "> and input_mileage = #{inputMileage}</if>
<if test="lastMileage != null "> and last_mileage = #{lastMileage}</if>
<if test="maintainDate != null "> and maintain_date = #{maintainDate}</if>
<if test="description != null and description != ''"> and description = #{description}</if>
<if test="status != null and status != ''"> and status = #{status}</if>
<if test="orderType != null and orderType != ''"> and order_type = #{orderType}</if>
</where>
order by o.create_time desc
</select>
<select id="selectBizScrapOrderList" parameterType="BizMaintenanceOrder" resultMap="BizMaintenanceOrderResult">
select o.order_id, o.order_no, o.vehicle_id, o.plate_number, o.type_code, o.factory_id, o.input_mileage, o.last_mileage, o.maintain_date, o.description, o.status, o.order_type, o.create_by, o.create_time, o.update_by, o.update_time, o.remark, d.dept_name as factory_name
from biz_maintenance_order o
left join sys_dept d on d.dept_id = o.factory_id
<where>
and o.type_code = '3'
<if test="orderNo != null and orderNo != ''"> and o.order_no like concat('%', #{orderNo}, '%')</if>
<if test="plateNumber != null and plateNumber != ''"> and o.plate_number like concat('%', #{plateNumber}, '%')</if>
<if test="typeCode != null and typeCode != ''"> and o.type_code = #{typeCode}</if>
<if test="factoryId != null "> and o.factory_id = #{factoryId}</if>
<if test="inputMileage != null "> and o.input_mileage = #{inputMileage}</if>
<if test="lastMileage != null "> and o.last_mileage = #{lastMileage}</if>
<if test="maintainDate != null "> and o.maintain_date = #{maintainDate}</if>
<if test="description != null and description != ''"> and o.description like concat('%', #{description}, '%')</if>
<if test="status != null and status != ''"> and o.status = #{status}</if>
<if test="orderType != null and orderType != ''"> and o.order_type = #{orderType}</if>
<!-- 按照补胎工单查询 -->
<if test="orderType == null or orderType == ''"> and o.order_type = '1'</if>
${params.dataScope}
</where>
order by o.create_time desc
</select>
<select id="selectBizMaintenanceOrderById" parameterType="Long" resultMap="BizMaintenanceOrderResult">
select o.order_id, o.order_no, o.vehicle_id, o.plate_number, o.type_code, o.factory_id, o.input_mileage, o.last_mileage, o.maintain_date, o.description, o.status, o.order_type, o.create_by, o.create_time, o.update_by, o.update_time, o.remark, d.dept_name as factory_name
from biz_maintenance_order o
left join sys_dept d on d.dept_id = o.factory_id
where o.order_id = #{orderId}
<select id="selectBizMaintenanceOrderByOrderId" parameterType="Long" resultMap="BizMaintenanceOrderResult">
<include refid="selectBizMaintenanceOrderVo"/>
where order_id = #{orderId}
</select>
<insert id="insertBizMaintenanceOrder" parameterType="BizMaintenanceOrder" useGeneratedKeys="true" keyProperty="orderId">
insert into biz_maintenance_order
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="orderNo != null">order_no,</if>
<if test="orderNo != null and orderNo != ''">order_no,</if>
<if test="vehicleId != null">vehicle_id,</if>
<if test="plateNumber != null">plate_number,</if>
<if test="typeCode != null">type_code,</if>
<if test="typeCode != null and typeCode != ''">type_code,</if>
<if test="factoryId != null">factory_id,</if>
<if test="inputMileage != null">input_mileage,</if>
<if test="lastMileage != null">last_mileage,</if>
@ -127,14 +88,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if>
<if test="maintainer != null">maintainer,</if>
<if test="maintainerDate != null">maintainer_date,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="orderNo != null">#{orderNo},</if>
<if test="orderNo != null and orderNo != ''">#{orderNo},</if>
<if test="vehicleId != null">#{vehicleId},</if>
<if test="plateNumber != null">#{plateNumber},</if>
<if test="typeCode != null">#{typeCode},</if>
<if test="typeCode != null and typeCode != ''">#{typeCode},</if>
<if test="factoryId != null">#{factoryId},</if>
<if test="inputMileage != null">#{inputMileage},</if>
<if test="lastMileage != null">#{lastMileage},</if>
@ -147,18 +106,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
<if test="maintainer != null">#{maintainer},</if>
<if test="maintainerDate != null">#{maintainerDate},</if>
</trim>
</insert>
<update id="updateBizMaintenanceOrder" parameterType="BizMaintenanceOrder">
update biz_maintenance_order
<trim prefix="SET" suffixOverrides=",">
<if test="orderNo != null">order_no = #{orderNo},</if>
<if test="orderNo != null and orderNo != ''">order_no = #{orderNo},</if>
<if test="vehicleId != null">vehicle_id = #{vehicleId},</if>
<if test="plateNumber != null">plate_number = #{plateNumber},</if>
<if test="typeCode != null">type_code = #{typeCode},</if>
<if test="typeCode != null and typeCode != ''">type_code = #{typeCode},</if>
<if test="factoryId != null">factory_id = #{factoryId},</if>
<if test="inputMileage != null">input_mileage = #{inputMileage},</if>
<if test="lastMileage != null">last_mileage = #{lastMileage},</if>
@ -166,47 +123,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="description != null">description = #{description},</if>
<if test="status != null">status = #{status},</if>
<if test="orderType != null">order_type = #{orderType},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="maintainer != null">maintainer = #{maintainer},</if>
<if test="maintainerDate != null">maintainer_date = #{maintainerDate},</if>
</trim>
where order_id = #{orderId}
</update>
<delete id="deleteBizMaintenanceOrderById" parameterType="Long">
<delete id="deleteBizMaintenanceOrderByOrderId" parameterType="Long">
delete from biz_maintenance_order where order_id = #{orderId}
</delete>
<delete id="deleteBizMaintenanceOrderByIds" parameterType="String">
<delete id="deleteBizMaintenanceOrderByOrderIds" parameterType="String">
delete from biz_maintenance_order where order_id in
<foreach item="orderId" collection="array" open="(" separator="," close=")">
#{orderId}
</foreach>
</delete>
<select id="selectOrderCountByStatus" parameterType="String" resultType="int">
select count(*) from biz_maintenance_order where status = #{status} and order_type = '1'
</select>
<select id="selectOrderByPlateNumber" parameterType="String" resultMap="BizMaintenanceOrderResult">
<include refid="selectBizMaintenanceOrderVo"/>
where plate_number like concat('%', #{plateNumber}, '%') and order_type = '1'
order by create_time desc
</select>
<select id="selectOrderByTireCode" parameterType="String" resultMap="BizMaintenanceOrderResult">
select distinct o.order_id, o.order_no, o.vehicle_id, o.plate_number, o.type_code, o.factory_id, o.input_mileage, o.last_mileage, o.maintain_date, o.description, o.status, o.order_type, o.create_by, o.create_time, o.update_by, o.update_time, o.remark
from biz_maintenance_order o
inner join biz_order_tire_detail d on o.order_id = d.order_id
where d.tire_code like concat('%', #{tireCode}, '%') and o.order_type = '1'
order by o.create_time desc
</select>
<update id="updateOrderStatus" parameterType="map">
update biz_maintenance_order
set status = #{status}, update_time = now()
where order_id = #{orderId}
</update>
</mapper>

@ -54,6 +54,33 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
GROUP BY DATE(create_time)
ORDER BY date;
</select>
<select id="selectTyreModel" resultType="java.util.Map">
SELECT
bt.tyre_model AS tyreModel, -- 规格名称
COUNT(bi.id) AS total -- 该规格的库存总数
FROM
base_inventory bi
INNER JOIN base_tyre bt ON bi.tyre_rfid = bt.tyre_epc
WHERE
bi.status = '0' -- 仅统计在库状态
GROUP BY
bt.tyre_model -- 按规格分组统计
ORDER BY
total DESC; -- 按数量降序排列(可选)
</select>
<select id="selectTyreInstall" resultType="java.util.Map">
SELECT
bt.tyre_model AS tyreModel, -- 规格名称
COUNT(bt.tyre_id) AS total -- 该规格的库存总数
FROM
base_tyre bt
WHERE
bt.car_no is not null -- 仅统计在库状态
GROUP BY
bt.tyre_model -- 按规格分组统计
ORDER BY
total DESC; -- 按数量降序排列(可选)
</select>
<insert id="insertRecordWarehousing" parameterType="RecordWarehousing">
insert into record_warehousing

Loading…
Cancel
Save