Просмотр исходного кода

Merge remote-tracking branch 'origin/master' into master

zxf 16 часов назад
Родитель
Сommit
e7b5832d42
36 измененных файлов с 1443 добавлено и 507 удалено
  1. 3 0
      jd-logistics-api/jd-logistics-api-system/src/main/java/com/ruoyi/system/api/domain/SysDept.java
  2. 32 2
      jd-logistics-modules/jd-logistics-system/src/main/java/com/ruoyi/system/controller/SysDeptController.java
  3. 17 9
      jd-logistics-modules/jd-logistics-system/src/main/java/com/ruoyi/system/controller/SysUserController.java
  4. 63 0
      jd-logistics-modules/jd-logistics-system/src/main/java/com/ruoyi/system/domain/dto/DeptImportDTO.java
  5. 41 0
      jd-logistics-modules/jd-logistics-system/src/main/java/com/ruoyi/system/domain/dto/UserImportDTO.java
  6. 10 1
      jd-logistics-modules/jd-logistics-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java
  7. 12 1
      jd-logistics-modules/jd-logistics-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java
  8. 12 3
      jd-logistics-modules/jd-logistics-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
  9. 81 0
      jd-logistics-modules/jd-logistics-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java
  10. 98 0
      jd-logistics-modules/jd-logistics-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
  11. 12 0
      jd-logistics-modules/jd-logistics-system/src/main/resources/mapper/system/SysDeptMapper.xml
  12. BIN
      jd-logistics-ui-v3/src/assets/images/profile.jpg
  13. 1 1
      jd-logistics-ui-v3/src/views/logistics/banner/index.vue
  14. 1 1
      jd-logistics-ui-v3/src/views/logistics/order/components/PickupTimeCascader.vue
  15. 29 29
      jd-logistics-ui-v3/src/views/logistics/order/createOrder.vue
  16. 300 175
      jd-logistics-ui-v3/src/views/system/dept/index.vue
  17. 17 8
      jd-logistics-ui-v3/src/views/system/user/index.vue
  18. 6 0
      jd_logistics-app/api/address.js
  19. 3 3
      jd_logistics-app/config/env.js
  20. 23 27
      jd_logistics-app/pages.json
  21. 90 2
      jd_logistics-app/pages/address/address_list.vue
  22. 242 45
      jd_logistics-app/pages/address/edit.vue
  23. 12 12
      jd_logistics-app/pages/index/components/PersonalExpressDialog.vue
  24. 115 17
      jd_logistics-app/pages/index/index.vue
  25. 1 1
      jd_logistics-app/pages/mine/login.vue
  26. 18 3
      jd_logistics-app/pages/mine/mine.vue
  27. 1 1
      jd_logistics-app/pages/order/components/OrderItem.vue
  28. 29 19
      jd_logistics-app/pages/order/components/TimePopup.vue
  29. 151 140
      jd_logistics-app/pages/order/create_order.vue
  30. 11 3
      jd_logistics-app/pages/order/index.vue
  31. 1 0
      jd_logistics-app/pages/search/search.vue
  32. BIN
      jd_logistics-app/static/img/default-avatar.png
  33. BIN
      jd_logistics-app/static/img/tabs/order.png
  34. BIN
      jd_logistics-app/static/img/tabs/order_active.png
  35. 1 0
      jd_logistics-app/stores/app.js
  36. 10 4
      jd_logistics-app/utils/request.js

+ 3 - 0
jd-logistics-api/jd-logistics-api-system/src/main/java/com/ruoyi/system/api/domain/SysDept.java

@@ -76,6 +76,9 @@ public class SysDept extends BaseEntity
     /** 公司地址 */
     private String companyAddress;
 
+    /** 部门编码 */
+    private String deptCode;
+
     public Long getDeptId()
     {
         return deptId;

+ 32 - 2
jd-logistics-modules/jd-logistics-system/src/main/java/com/ruoyi/system/controller/SysDeptController.java

@@ -1,6 +1,10 @@
 package com.ruoyi.system.controller;
 
+import java.io.IOException;
 import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+
+import com.ruoyi.common.core.utils.poi.ExcelUtil;
 import org.apache.commons.lang3.ArrayUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
@@ -11,7 +15,9 @@ import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.PutMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
 import com.ruoyi.common.core.constant.UserConstants;
 import com.ruoyi.common.core.utils.StringUtils;
 import com.ruoyi.common.core.web.controller.BaseController;
@@ -21,6 +27,7 @@ import com.ruoyi.common.log.enums.BusinessType;
 import com.ruoyi.common.security.annotation.RequiresPermissions;
 import com.ruoyi.common.security.utils.SecurityUtils;
 import com.ruoyi.system.api.domain.SysDept;
+import com.ruoyi.system.domain.dto.DeptImportDTO;
 import com.ruoyi.system.service.ISysDeptService;
 
 /**
@@ -121,13 +128,36 @@ public class SysDeptController extends BaseController
     {
         if (deptService.hasChildByDeptId(deptId))
         {
-            return warn("存在下级部门,不允许删除");
+            return warn("存在下级部门不允许删除");
         }
         if (deptService.checkDeptExistUser(deptId))
         {
-            return warn("部门存在用户,不允许删除");
+            return warn("部门存在用户不允许删除");
         }
         deptService.checkDeptDataScope(deptId);
         return toAjax(deptService.deleteDeptById(deptId));
     }
+
+    /**
+     * 导入部门数据
+     */
+    @RequiresPermissions("system:dept:add")
+    @Log(title = "部门管理", businessType = BusinessType.IMPORT)
+    @PostMapping("/importData")
+    public AjaxResult importData(MultipartFile file) throws Exception {
+        ExcelUtil<DeptImportDTO> util = new ExcelUtil<DeptImportDTO>(DeptImportDTO.class);
+        List<DeptImportDTO> deptList = util.importExcel(file.getInputStream());
+        String message = deptService.importDept(deptList);
+        return success(message);
+    }
+
+    /**
+     * 下载部门导入模板
+     */
+    @RequiresPermissions("system:dept:add")
+    @PostMapping("/importTemplate")
+    public void importTemplate(HttpServletResponse response) throws IOException {
+        ExcelUtil<DeptImportDTO> util = new ExcelUtil<DeptImportDTO>(DeptImportDTO.class);
+        util.importTemplateExcel(response, "部门数据");
+    }
 }

+ 17 - 9
jd-logistics-modules/jd-logistics-system/src/main/java/com/ruoyi/system/controller/SysUserController.java

@@ -41,6 +41,7 @@ import com.ruoyi.system.api.domain.SysDept;
 import com.ruoyi.system.api.domain.SysRole;
 import com.ruoyi.system.api.domain.SysUser;
 import com.ruoyi.system.api.model.LoginUser;
+import com.ruoyi.system.domain.dto.UserImportDTO;
 import com.ruoyi.system.service.ISysConfigService;
 import com.ruoyi.system.service.ISysDeptService;
 import com.ruoyi.system.service.ISysPermissionService;
@@ -100,22 +101,29 @@ public class SysUserController extends BaseController
         util.exportExcel(response, list, "用户数据");
     }
 
+
+    /**
+     * 导入用户数据
+     */
     @Log(title = "用户管理", businessType = BusinessType.IMPORT)
-    @RequiresPermissions("system:user:import")
+    @RequiresPermissions("system:user:add")
     @PostMapping("/importData")
-    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
-    {
-        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
-        List<SysUser> userList = util.importExcel(file.getInputStream());
+    public AjaxResult importData(MultipartFile file) throws Exception {
+        ExcelUtil<UserImportDTO> util = new ExcelUtil<UserImportDTO>(UserImportDTO.class);
+        List<UserImportDTO> userImportList = util.importExcel(file.getInputStream());
         String operName = SecurityUtils.getUsername();
-        String message = userService.importUser(userList, updateSupport, operName);
+        String message = userService.importUserFromDTO(userImportList, operName);
         return success(message);
     }
 
+
+    /**
+     * 下载用户导入模板
+     */
+    @RequiresPermissions("system:user:add")
     @PostMapping("/importTemplate")
-    public void importTemplate(HttpServletResponse response) throws IOException
-    {
-        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
+    public void importTemplate(HttpServletResponse response) throws IOException {
+        ExcelUtil<UserImportDTO> util = new ExcelUtil<UserImportDTO>(UserImportDTO.class);
         util.importTemplateExcel(response, "用户数据");
     }
 

+ 63 - 0
jd-logistics-modules/jd-logistics-system/src/main/java/com/ruoyi/system/domain/dto/DeptImportDTO.java

@@ -0,0 +1,63 @@
+package com.ruoyi.system.domain.dto;
+
+import java.math.BigDecimal;
+import java.util.List;
+import com.ruoyi.common.core.annotation.Excel;
+import lombok.Data;
+
+/**
+ * 部门 Excel 导入对象
+ * 
+ * @author lydgt
+ */
+@Data
+public class DeptImportDTO {
+
+    /** 组织名称 */
+    @Excel(name = "组织名称")
+    private String deptName;
+
+    /** 组织编码 */
+    @Excel(name = "组织编码")
+    private String deptCode;
+
+    /** 父组织名称 */
+    @Excel(name = "父组织名称")
+    private String parentDeptName;
+
+    /** 父组织编码 */
+    @Excel(name = "父组织编码")
+    private String parentDeptCode;
+
+    /** 负责人手机号 */
+    @Excel(name = "负责人手机号")
+    private String phone;
+
+    /** 负责人姓名 */
+    @Excel(name = "负责人姓名")
+    private String leader;
+
+    /** 费率 */
+    @Excel(name = "费率")
+    private String rateValue;
+
+    /** 发票抬头 */
+    @Excel(name = "发票抬头")
+    private String invoiceName;
+
+    /** 纳税人识别号 */
+    @Excel(name = "纳税人识别号")
+    private String invoiceNum;
+
+    /** 地址 */
+    @Excel(name = "地址")
+    private String companyAddress;
+
+    /** 开户银行 */
+    @Excel(name = "开户银行")
+    private String openBank;
+
+    /** 银行账号 */
+    @Excel(name = "银行账号")
+    private String bankAccount;
+}

+ 41 - 0
jd-logistics-modules/jd-logistics-system/src/main/java/com/ruoyi/system/domain/dto/UserImportDTO.java

@@ -0,0 +1,41 @@
+package com.ruoyi.system.domain.dto;
+
+import com.ruoyi.common.core.annotation.Excel;
+import lombok.Data;
+
+/**
+ * 用户 Excel 导入对象
+ * 
+ * @author lydgt
+ */
+@Data
+public class UserImportDTO {
+
+    /** 手机号 */
+    @Excel(name = "手机号")
+    private String phonenumber;
+
+    /** 姓名 */
+    @Excel(name = "姓名")
+    private String nickName;
+
+    /** 工号 */
+    @Excel(name = "工号")
+    private String employeeCode;
+
+    /** 用户角色名称 */
+    @Excel(name = "用户角色")
+    private String roleName;
+
+    /** 组织名称 */
+    @Excel(name = "组织名称")
+    private String deptName;
+
+    /** 组织编码 */
+    @Excel(name = "组织编码")
+    private String deptCode;
+
+    /** 邮箱 */
+    @Excel(name = "邮箱")
+    private String email;
+}

+ 10 - 1
jd-logistics-modules/jd-logistics-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java

@@ -111,8 +111,17 @@ public interface SysDeptMapper
     /**
      * 删除部门管理信息
      * 
-     * @param deptId 部门ID
+     * @param deptId 部门 ID
      * @return 结果
      */
     public int deleteDeptById(Long deptId);
+
+    /**
+     * 根据部门编码和名称查询部门
+     *
+     * @param deptCode 部门编码
+     * @param deptName 部门名称
+     * @return 部门信息
+     */
+    public SysDept selectDeptByInfo(@Param("deptCode") String deptCode, @Param("deptName") String deptName);
 }

+ 12 - 1
jd-logistics-modules/jd-logistics-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java

@@ -2,6 +2,7 @@ package com.ruoyi.system.service;
 
 import java.util.List;
 import com.ruoyi.system.api.domain.SysDept;
+import com.ruoyi.system.domain.dto.DeptImportDTO;
 import com.ruoyi.system.domain.vo.TreeSelect;
 
 /**
@@ -117,8 +118,18 @@ public interface ISysDeptService
     /**
      * 删除部门管理信息
      * 
-     * @param deptId 部门ID
+     * @param deptId 部门 ID
      * @return 结果
      */
     public int deleteDeptById(Long deptId);
+
+    /**
+     * 导入部门数据
+     * 
+     * @param deptList 部门数据列表
+     * @param isUpdateSupport 是否更新已存在的数据
+     * @param operName 操作用户名
+     * @return 导入结果
+     */
+    public String importDept(List<DeptImportDTO> deptList);
 }

+ 12 - 3
jd-logistics-modules/jd-logistics-system/src/main/java/com/ruoyi/system/service/ISysUserService.java

@@ -2,6 +2,7 @@ package com.ruoyi.system.service;
 
 import java.util.List;
 import com.ruoyi.system.api.domain.SysUser;
+import com.ruoyi.system.domain.dto.UserImportDTO;
 
 /**
  * 用户 业务层
@@ -204,12 +205,20 @@ public interface ISysUserService
      */
     public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName);
 
+    /**
+     * 导入用户数据(使用导入对象)
+     * 
+     * @param userImportList 用户导入数据列表
+     * @param operName 操作用户
+     * @return 结果
+     */
+    public String importUserFromDTO(List<UserImportDTO> userImportList, String operName);
+
 
     /**
-     * 通过用户名和OpenId查询用户
+     * 通过用户名和 OpenId 查询用户
      *
-     * @param userName 用户名
-     * @param openId 用户名
+     * @param sysUser 用户对象
      * @return 用户对象信息
      */
     public SysUser selectUserByOpenId( SysUser sysUser);

+ 81 - 0
jd-logistics-modules/jd-logistics-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java

@@ -4,6 +4,8 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.stream.Collectors;
+
+import com.ruoyi.common.core.utils.DateUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.ruoyi.common.core.constant.UserConstants;
@@ -16,6 +18,7 @@ import com.ruoyi.common.security.utils.SecurityUtils;
 import com.ruoyi.system.api.domain.SysDept;
 import com.ruoyi.system.api.domain.SysRole;
 import com.ruoyi.system.api.domain.SysUser;
+import com.ruoyi.system.domain.dto.DeptImportDTO;
 import com.ruoyi.system.domain.vo.TreeSelect;
 import com.ruoyi.system.mapper.SysDeptMapper;
 import com.ruoyi.system.mapper.SysRoleMapper;
@@ -335,4 +338,82 @@ public class SysDeptServiceImpl implements ISysDeptService
     {
         return getChildList(list, t).size() > 0 ? true : false;
     }
+
+    /**
+     * 导入部门数据
+     * 
+     * @param deptList 部门数据列表
+     * @return 导入结果
+     */
+    @Override
+    public String importDept(List<DeptImportDTO> deptList) {
+        if (StringUtils.isNull(deptList) || deptList.size() == 0) {
+            throw new ServiceException("导入部门数据不能为空!");
+        }
+
+        int successNum = 0;
+        int failureNum = 0;
+        StringBuilder successMsg = new StringBuilder();
+        StringBuilder failureMsg = new StringBuilder();
+
+        for (DeptImportDTO importDTO : deptList) {
+            try {
+                // 将导入对象转换为 SysDept 实体对象
+                SysDept dept = convertToSysDept(importDTO);
+
+                // 根据父组织编码和名称查询父部门 ID
+                SysDept parentId = deptMapper.selectDeptByInfo(importDTO.getParentDeptCode(), importDTO.getParentDeptName());
+
+                // 设置父部门 ID,如果为 null 则默认为顶级部门(0)
+                dept.setParentId(parentId == null ? 0L : parentId.getDeptId());
+
+                // 检查部门名称是否唯一
+                if (null != deptMapper.checkDeptNameUnique(dept.getDeptName(), dept.getParentId())) {
+                    failureNum++;
+                    failureMsg.append(String.format("%1$s、部门已存在;", dept.getDeptName()));
+                } else {
+                    // 新增部门
+                    this.insertDept(dept);
+                    successNum++;
+                    successMsg.append(String.format("%1$s、导入成功;", dept.getDeptName()));
+                }
+            } catch (Exception e) {
+                failureNum++;
+                String msg = String.format("%1$s、导入失败:%2$s", importDTO.getDeptName(), e.getMessage());
+                failureMsg.append(msg);
+            }
+        }
+
+        if (failureNum > 0) {
+            failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据,格式如下:");
+            successMsg.insert(0, "恭喜您,导入成功!共 " + successNum + " 条数据,格式如下:");
+            return failureMsg.toString();
+        } else {
+            successMsg.insert(0, "恭喜您,全部导入成功!共 " + successNum + " 条数据,格式如下:");
+            return successMsg.toString();
+        }
+    }
+
+    /**
+     * 将 DeptImportDTO 转换为 SysDept 实体
+     * 
+     * @param importDTO 导入对象
+     * @return SysDept 实体
+     */
+    private SysDept convertToSysDept(DeptImportDTO importDTO) {
+        SysDept dept = new SysDept();
+        dept.setDeptName(importDTO.getDeptName());
+        dept.setDeptCode(importDTO.getDeptCode());
+        dept.setLeader(importDTO.getLeader());
+        dept.setPhone(importDTO.getPhone());
+        dept.setInvoiceName(importDTO.getInvoiceName());
+        dept.setInvoiceNum(importDTO.getInvoiceNum());
+        dept.setCompanyAddress(importDTO.getCompanyAddress());
+        dept.setOpenBank(importDTO.getOpenBank());
+        dept.setBankAccount(importDTO.getBankAccount());
+        dept.setCreateBy(SecurityUtils.getUsername());
+        dept.setCreateTime(DateUtils.getNowDate());
+        dept.setRateValue(importDTO.getRateValue());
+        return dept;
+    }
 }

+ 98 - 0
jd-logistics-modules/jd-logistics-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java

@@ -8,6 +8,8 @@ import javax.validation.Validator;
 import com.ruoyi.logistics.config.GemaiyunSmsConfig;
 import com.ruoyi.logistics.util.GemaiyunSmsUtil;
 import com.ruoyi.logistics.util.PasswordUtils;
+
+import com.ruoyi.common.core.utils.DateUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -21,11 +23,14 @@ import com.ruoyi.common.core.utils.StringUtils;
 import com.ruoyi.common.core.utils.bean.BeanValidators;
 import com.ruoyi.common.datascope.annotation.DataScope;
 import com.ruoyi.common.security.utils.SecurityUtils;
+import com.ruoyi.system.api.domain.SysDept;
 import com.ruoyi.system.api.domain.SysRole;
 import com.ruoyi.system.api.domain.SysUser;
 import com.ruoyi.system.domain.SysPost;
 import com.ruoyi.system.domain.SysUserPost;
 import com.ruoyi.system.domain.SysUserRole;
+import com.ruoyi.system.domain.dto.UserImportDTO;
+import com.ruoyi.system.mapper.SysDeptMapper;
 import com.ruoyi.system.mapper.SysPostMapper;
 import com.ruoyi.system.mapper.SysRoleMapper;
 import com.ruoyi.system.mapper.SysUserMapper;
@@ -66,6 +71,9 @@ public class SysUserServiceImpl implements ISysUserService
     @Autowired
     private ISysDeptService deptService;
 
+    @Autowired
+    private SysDeptMapper deptMapper;
+
     @Autowired
     protected Validator validator;
 
@@ -594,4 +602,94 @@ public class SysUserServiceImpl implements ISysUserService
     public SysUser selectUserByOpenId(SysUser sysUser) {
         return userMapper.selectUserByOpenId(sysUser.getUserName(), sysUser.getOpenId());
     }
+
+    /**
+     * 导入用户数据(使用导入对象)
+     *
+     * @param userImportList 用户导入数据列表
+     * @param operName 操作用户
+     * @return 结果
+     */
+    @Override
+    public String importUserFromDTO(List<UserImportDTO> userImportList, String operName) {
+        if (StringUtils.isNull(userImportList) || userImportList.size() == 0) {
+            throw new ServiceException("导入用户数据不能为空!");
+        }
+
+        int successNum = 0;
+        int failureNum = 0;
+        StringBuilder successMsg = new StringBuilder();
+        StringBuilder failureMsg = new StringBuilder();
+
+        for (UserImportDTO importDTO : userImportList) {
+            try {
+                // 将导入对象转换为 SysUser 实体对象
+                SysUser user = convertToSysUser(importDTO, operName);
+
+                // 根据组织编码和名称查询部门 ID
+                SysDept deptId = deptMapper.selectDeptByInfo(importDTO.getDeptCode(), importDTO.getDeptName());
+                if (StringUtils.isNull(deptId)) {
+                    throw new ServiceException("部门不存在:" + importDTO.getDeptName());
+                }
+                user.setDeptId(deptId.getDeptId());
+
+                // 验证是否存在这个用户
+                SysUser u = userMapper.selectUserByUserName(user.getUserName());
+                if (StringUtils.isNull(u)) {
+                    BeanValidators.validateWithException(validator, user);
+                    deptService.checkDeptDataScope(user.getDeptId());
+                    user.setCreateBy(operName);
+
+                    // 处理角色关联
+                    if (StringUtils.isNotEmpty(importDTO.getRoleName())) {
+                        SysRole roleId = roleMapper.checkRoleNameUnique(importDTO.getRoleName());
+                        if (StringUtils.isNotNull(roleId)) {
+                            user.setRoleIds(new Long[]{roleId.getRoleId()});
+                        }
+                    }
+
+                    this.insertUser(user);
+
+
+                    successNum++;
+                    successMsg.append("<br/>" + successNum + "、账号 " + user.getUserName() + " 导入成功");
+                } else {
+                    failureNum++;
+                    failureMsg.append("<br/>" + failureNum + "、账号 " + user.getUserName() + " 已存在");
+                }
+            } catch (Exception e) {
+                failureNum++;
+                String msg = "<br/>" + failureNum + "、账号 " + importDTO.getPhonenumber() + " 导入失败:";
+                failureMsg.append(msg + e.getMessage());
+                log.error(msg, e);
+            }
+        }
+
+        if (failureNum > 0) {
+            failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
+            throw new ServiceException(failureMsg.toString());
+        } else {
+            successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
+        }
+        return successMsg.toString();
+    }
+
+    /**
+     * 将 UserImportDTO 转换为 SysUser 实体
+     *
+     * @param importDTO 导入对象
+     * @param operName 操作用户名
+     * @return SysUser 实体
+     */
+    private SysUser convertToSysUser(UserImportDTO importDTO, String operName)
+    {
+        SysUser user = new SysUser();
+        user.setUserName(importDTO.getEmployeeCode());
+        user.setNickName(importDTO.getNickName());
+        user.setPhonenumber(importDTO.getPhonenumber());
+        user.setEmail(importDTO.getEmail());
+        user.setCreateBy(operName);
+        user.setCreateTime(DateUtils.getNowDate());
+        return user;
+    }
 }

+ 12 - 0
jd-logistics-modules/jd-logistics-system/src/main/resources/mapper/system/SysDeptMapper.xml

@@ -179,4 +179,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		update sys_dept set del_flag = '2' where dept_id = #{deptId}
 	</delete>
 
+	<select id="selectDeptByInfo" resultMap="SysDeptResult">
+		<include refid="selectDeptVo"/>
+		where del_flag = '0'
+		<if test="deptCode != null and deptCode != ''">
+			and dept_code = #{deptCode}
+		</if>
+		<if test="deptName != null and deptName != ''">
+			and dept_name = #{deptName}
+		</if>
+		limit 1
+	</select>
+
 </mapper> 

BIN
jd-logistics-ui-v3/src/assets/images/profile.jpg


+ 1 - 1
jd-logistics-ui-v3/src/views/logistics/banner/index.vue

@@ -177,7 +177,7 @@
           </el-radio-group>
         </el-form-item>
 
-        <el-form-item label="跳转链接">
+        <el-form-item label="跳转链接" v-if="form.sysType == 0">
           <el-input v-model="form.linkUrl" placeholder="请输入跳转链接" />
         </el-form-item>
         <!--        <el-form-item label="备注" prop="remark">

+ 1 - 1
jd-logistics-ui-v3/src/views/logistics/order/components/PickupTimeCascader.vue

@@ -77,7 +77,7 @@ const props = defineProps({
   // 开始时间
   startTime: {
     type: Number,
-    default: 8
+    default: 9
   },
   // 结束时间
   endTime: {

+ 29 - 29
jd-logistics-ui-v3/src/views/logistics/order/createOrder.vue

@@ -74,26 +74,26 @@
             </el-form-item>
 
             <div class="default-address-footer">
-              <div class="default-address-wrapper">
-                <label class="checkbox-label">
-                  <el-checkbox
-                      v-model="sender.defaultFlag"
-                      :true-label="'1'"
-                      :false-label="'0'"
-                      size="large"
-                      class="default-address-radio"
-                  />
-                  <span class="checkbox-text">设为默认寄件地址</span>
-                </label>
-              </div>
-
-              <el-button
-                  type="primary"
-                  @click="addToAddressBook('sender')"
-                  class="add-address-btn"
-              >
-                加入地址簿
-              </el-button>
+<!--              <div class="default-address-wrapper">-->
+<!--                <label class="checkbox-label">-->
+<!--                  <el-checkbox-->
+<!--                      v-model="sender.defaultFlag"-->
+<!--                      :true-label="'1'"-->
+<!--                      :false-label="'0'"-->
+<!--                      size="large"-->
+<!--                      class="default-address-radio"-->
+<!--                  />-->
+<!--                  <span class="checkbox-text">设为默认寄件地址</span>-->
+<!--                </label>-->
+<!--              </div>-->
+
+<!--              <el-button-->
+<!--                  type="primary"-->
+<!--                  @click="addToAddressBook('sender')"-->
+<!--                  class="add-address-btn"-->
+<!--              >-->
+<!--                加入地址簿-->
+<!--              </el-button>-->
             </div>
           </el-form>
         </div>
@@ -170,15 +170,15 @@
               />
             </el-form-item>
 
-            <div class="form-footer">
-              <el-button
-                  type="primary"
-                  @click="addToAddressBook('receiver')"
-                  class="add-address-btn"
-              >
-                加入地址簿
-              </el-button>
-            </div>
+<!--            <div class="form-footer">-->
+<!--              <el-button-->
+<!--                  type="primary"-->
+<!--                  @click="addToAddressBook('receiver')"-->
+<!--                  class="add-address-btn"-->
+<!--              >-->
+<!--                加入地址簿-->
+<!--              </el-button>-->
+<!--            </div>-->
           </el-form>
         </div>
       </div>

+ 300 - 175
jd-logistics-ui-v3/src/views/system/dept/index.vue

@@ -1,184 +1,248 @@
 <template>
-   <div class="app-container">
-      <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch">
-         <el-form-item label="供应商名称" prop="deptName">
-            <el-input
-               v-model="queryParams.deptName"
-               placeholder="请输入供应商名称"
-               clearable
-               style="width: 200px"
-               @keyup.enter="handleQuery"
-            />
-         </el-form-item>
-         <el-form-item label="状态" prop="status">
-            <el-select v-model="queryParams.status" placeholder="供应商状态" clearable style="width: 200px">
-               <el-option
-                  v-for="dict in sys_normal_disable"
-                  :key="dict.value"
-                  :label="dict.label"
-                  :value="dict.value"
-               />
-            </el-select>
-         </el-form-item>
-         <el-form-item>
-            <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
-            <el-button icon="Refresh" @click="resetQuery">重置</el-button>
-         </el-form-item>
-      </el-form>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch">
+      <el-form-item label="供应商名称" prop="deptName">
+        <el-input
+            v-model="queryParams.deptName"
+            placeholder="请输入供应商名称"
+            clearable
+            style="width: 200px"
+            @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="供应商状态" clearable style="width: 200px">
+          <el-option
+              v-for="dict in sys_normal_disable"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
 
-      <el-row :gutter="10" class="mb8">
-         <el-col :span="1.5">
-            <el-button
-               type="primary"
-               plain
-               icon="Plus"
-               @click="handleAdd"
-               v-hasPermi="['system:dept:add']"
-            >新增</el-button>
-         </el-col>
-         <el-col :span="1.5">
-            <el-button
-               type="info"
-               plain
-               icon="Sort"
-               @click="toggleExpandAll"
-            >展开/折叠</el-button>
-         </el-col>
-         <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-      </el-row>
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+            type="primary"
+            plain
+            icon="Plus"
+            @click="handleAdd"
+            v-hasPermi="['system:dept:add']"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+            type="info"
+            plain
+            icon="Sort"
+            @click="toggleExpandAll"
+        >展开/折叠
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+            type="success"
+            plain
+            icon="Download"
+            @click="handleDownloadTemplate"
+            v-hasPermi="['system:dept:add']">
+          模板下载
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+            type="success"
+            plain
+            icon="Upload"
+            @click="handleImport"
+            v-hasPermi="['system:dept:add']">
+          导入
+        </el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
 
-      <el-table
-         v-if="refreshTable"
-         v-loading="loading"
-         :data="deptList"
-         row-key="deptId"
-         :default-expand-all="isExpandAll"
-         :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
-      >
-         <el-table-column prop="deptName" label="供应商名称" width="230" :show-overflow-tooltip="true"></el-table-column>
-<!--         <el-table-column prop="orderNum" label="排序" width="200"></el-table-column>-->
-        <el-table-column prop="rateValue" label="费率" width="50"></el-table-column>
-        <el-table-column prop="status" label="状态" width="100">
-           <template #default="scope">
-              <dict-tag :options="sys_normal_disable" :value="scope.row.status" />
-            </template>
-         </el-table-column>
-        <el-table-column prop="invoiceName" label="开票名称(抬头)" width="120" :show-overflow-tooltip="true"></el-table-column>
-        <el-table-column prop="invoiceNum" label="税号" width="100" :show-overflow-tooltip="true"></el-table-column>
-        <el-table-column prop="bankAccount" label="银行账号" width="100" :show-overflow-tooltip="true"></el-table-column>
-        <el-table-column prop="openBank" label="开户银行" width="100" :show-overflow-tooltip="true"></el-table-column>
-         <el-table-column prop="companyAddress" label="公司地址" width="150" :show-overflow-tooltip="true"></el-table-column>
-         <el-table-column label="创建时间" align="center" prop="createTime" width="180">
-            <template #default="scope">
-               <span>{{ parseTime(scope.row.createTime) }}</span>
-            </template>
-         </el-table-column>
-         <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
-            <template #default="scope">
-               <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dept:edit']">修改</el-button>
-               <el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['system:dept:add']">新增</el-button>
-               <el-button v-if="scope.row.parentId != 0" link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:dept:remove']">删除</el-button>
-            </template>
-         </el-table-column>
-      </el-table>
+    <el-table
+        v-if="refreshTable"
+        v-loading="loading"
+        :data="deptList"
+        row-key="deptId"
+        :default-expand-all="isExpandAll"
+        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
+    >
+      <el-table-column prop="deptName" label="供应商名称" width="230" :show-overflow-tooltip="true"></el-table-column>
+      <el-table-column prop="deptCode" label="供应商编码" width="200" :show-overflow-tooltip="true"></el-table-column>
+      <el-table-column prop="rateValue" label="费率" width="50"></el-table-column>
+      <el-table-column prop="status" label="状态" width="100">
+        <template #default="scope">
+          <dict-tag :options="sys_normal_disable" :value="scope.row.status"/>
+        </template>
+      </el-table-column>
+      <el-table-column prop="invoiceName" label="开票名称(抬头)" width="120"
+                       :show-overflow-tooltip="true"></el-table-column>
+      <el-table-column prop="invoiceNum" label="税号" width="100" :show-overflow-tooltip="true"></el-table-column>
+      <el-table-column prop="bankAccount" label="银行账号" width="100" :show-overflow-tooltip="true"></el-table-column>
+      <el-table-column prop="openBank" label="开户银行" width="100" :show-overflow-tooltip="true"></el-table-column>
+      <el-table-column prop="companyAddress" label="公司地址" width="150"
+                       :show-overflow-tooltip="true"></el-table-column>
+      <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+        <template #default="scope">
+          <span>{{ parseTime(scope.row.createTime) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template #default="scope">
+          <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dept:edit']">
+            修改
+          </el-button>
+          <el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['system:dept:add']">
+            新增
+          </el-button>
+          <el-button v-if="scope.row.parentId != 0" link type="primary" icon="Delete" @click="handleDelete(scope.row)"
+                     v-hasPermi="['system:dept:remove']">删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
 
-      <!-- 添加或修改供应商对话框 -->
-      <el-dialog :title="title" v-model="open" width="700px" append-to-body>
-         <el-form ref="deptRef" :model="form" :rules="rules" label-width="110px">
-            <el-row>
-               <el-col :span="24" v-if="form.parentId !== 0">
-                  <el-form-item label="上级组织" prop="parentId">
-                     <el-tree-select
-                        v-model="form.parentId"
-                        :data="deptOptions"
-                        :props="{ value: 'deptId', label: 'deptName', children: 'children' }"
-                        value-key="deptId"
-                        placeholder="选择上级组织"
-                        check-strictly
-                     />
-                  </el-form-item>
-               </el-col>
-               <el-col :span="12">
-                  <el-form-item label="供应商名称" prop="deptName">
-                     <el-input v-model="form.deptName" placeholder="请输入供应商名称" />
-                  </el-form-item>
-               </el-col>
-<!--               <el-col :span="12">
-                  <el-form-item label="显示排序" prop="orderNum">
-                     <el-input-number v-model="form.orderNum" controls-position="right" :min="0" />
-                  </el-form-item>
-               </el-col>-->
-               <el-col :span="12">
-                  <el-form-item label="负责人" prop="leader">
-                     <el-input v-model="form.leader" placeholder="请输入负责人" maxlength="20" />
-                  </el-form-item>
-               </el-col>
-               <el-col :span="12">
-                  <el-form-item label="联系电话" prop="phone">
-                     <el-input v-model="form.phone" placeholder="请输入联系电话" maxlength="11" />
-                  </el-form-item>
-               </el-col>
-               <el-col :span="12">
-                  <el-form-item label="邮箱" prop="email">
-                     <el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />
-                  </el-form-item>
-               </el-col>
-              <el-col :span="12">
-                <el-form-item label="费率" prop="rateValue">
-                  <el-input-number v-model="form.rateValue" controls-position="right" :min="0" :max="100" :precision="2" placeholder="请输入费率(%)" />
-                </el-form-item>
-              </el-col>
-               <el-col :span="12">
-                  <el-form-item label="供应商状态">
-                     <el-radio-group v-model="form.status">
-                        <el-radio
-                           v-for="dict in sys_normal_disable"
-                           :key="dict.value"
-                           :value="dict.value"
-                        >{{ dict.label }}</el-radio>
-                     </el-radio-group>
-                  </el-form-item>
-               </el-col>
-               <el-col :span="24">
-                  <el-form-item label="开票名称(抬头)" prop="invoiceName">
-                     <el-input v-model="form.invoiceName" placeholder="请输入开票名称" />
-                  </el-form-item>
-               </el-col>
-               <el-col :span="24">
-                  <el-form-item label="税号" prop="invoiceNum">
-                     <el-input v-model="form.invoiceNum" placeholder="请输入税号" />
-                  </el-form-item>
-               </el-col>
+    <!-- 添加或修改供应商对话框 -->
+    <el-dialog :title="title" v-model="open" width="700px" append-to-body>
+      <el-form ref="deptRef" :model="form" :rules="rules" label-width="110px">
+        <el-row>
+          <el-col :span="24" v-if="form.parentId !== 0">
+            <el-form-item label="上级组织" prop="parentId">
+              <el-tree-select
+                  v-model="form.parentId"
+                  :data="deptOptions"
+                  :props="{ value: 'deptId', label: 'deptName', children: 'children' }"
+                  value-key="deptId"
+                  placeholder="选择上级组织"
+                  check-strictly
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="供应商名称" prop="deptName">
+              <el-input v-model="form.deptName" placeholder="请输入供应商名称"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="负责人" prop="leader">
+              <el-input v-model="form.leader" placeholder="请输入负责人" maxlength="20"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="联系电话" prop="phone">
+              <el-input v-model="form.phone" placeholder="请输入联系电话" maxlength="11"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="邮箱" prop="email">
+              <el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="费率" prop="rateValue">
+              <el-input-number v-model="form.rateValue" controls-position="right" :min="0" :max="100" :precision="2"
+                               placeholder="请输入费率(%)"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="供应商状态">
+              <el-radio-group v-model="form.status">
+                <el-radio
+                    v-for="dict in sys_normal_disable"
+                    :key="dict.value"
+                    :value="dict.value"
+                >{{ dict.label }}
+                </el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="开票名称(抬头)" prop="invoiceName">
+              <el-input v-model="form.invoiceName" placeholder="请输入开票名称"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="税号" prop="invoiceNum">
+              <el-input v-model="form.invoiceNum" placeholder="请输入税号"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="开户银行" prop="openBank">
+              <el-input v-model="form.openBank" placeholder="请输入开户银行"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="银行账号" prop="bankAccount">
+              <el-input v-model="form.bankAccount" placeholder="请输入银行账号"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="公司地址" prop="companyAddress">
+              <el-input v-model="form.companyAddress" placeholder="请输入公司地址" type="textarea" :rows="2"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">确 定</el-button>
+          <el-button @click="cancel">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
 
-               <el-col :span="24">
-                  <el-form-item label="开户银行" prop="openBank">
-                     <el-input v-model="form.openBank" placeholder="请输入开户银行" />
-                  </el-form-item>
-               </el-col>
-               <el-col :span="24">
-                  <el-form-item label="银行账号" prop="bankAccount">
-                     <el-input v-model="form.bankAccount" placeholder="请输入银行账号" />
-                  </el-form-item>
-               </el-col>
-               <el-col :span="24">
-                  <el-form-item label="公司地址" prop="companyAddress">
-                     <el-input v-model="form.companyAddress" placeholder="请输入公司地址" type="textarea" :rows="2" />
-                  </el-form-item>
-               </el-col>
-            </el-row>
-         </el-form>
-         <template #footer>
-            <div class="dialog-footer">
-               <el-button type="primary" @click="submitForm">确 定</el-button>
-               <el-button @click="cancel">取 消</el-button>
-            </div>
-         </template>
-      </el-dialog>
-   </div>
+    <!-- 供应商导入对话框 -->
+    <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
+      <el-upload
+          ref="uploadRef"
+          :limit="1"
+          accept=".xlsx, .xls"
+          :headers="upload.headers"
+          :action="upload.url"
+          :disabled="upload.isUploading"
+          :on-progress="handleFileUploadProgress"
+          :on-success="handleFileSuccess"
+          :on-change="handleFileChange"
+          :on-remove="handleFileRemove"
+          :auto-upload="false"
+          drag
+      >
+        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
+        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
+        <template #tip>
+          <div class="el-upload__tip text-center">
+            <span>仅允许导入xls、xlsx格式文件。</span>
+            <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="handleDownloadTemplate">
+              下载模板
+            </el-link>
+          </div>
+        </template>
+      </el-upload>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitFileForm">确 定</el-button>
+          <el-button @click="upload.open = false">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
 </template>
 
 <script setup name="Dept">
 import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild } from "@/api/system/dept"
+import { getToken } from "@/utils/auth"
+import { download } from '@/utils/request'
+import { UploadFilled } from '@element-plus/icons-vue'
 
 const { proxy } = getCurrentInstance()
 const { sys_normal_disable } = proxy.useDict("sys_normal_disable")
@@ -192,6 +256,22 @@ const deptOptions = ref([])
 const isExpandAll = ref(true)
 const refreshTable = ref(true)
 
+/*** 供应商导入参数 */
+const upload = reactive({
+  // 是否显示弹出层(导入)
+  open: false,
+  // 弹出层标题
+  title: "",
+  // 是否禁用上传
+  isUploading: false,
+  // 设置上传的请求头部
+  headers: { Authorization: "Bearer " + getToken() },
+  // 上传的地址
+  url: import.meta.env.VITE_APP_BASE_API + "/system/dept/importData",
+  // 当前选中的文件
+  selectedFile: null
+})
+
 const data = reactive({
   form: {},
   queryParams: {
@@ -201,18 +281,63 @@ const data = reactive({
   rules: {
     parentId: [{ required: true, message: "上级组织不能为空", trigger: "blur" }],
     deptName: [{ required: true, message: "供应商名称不能为空", trigger: "blur" }],
-    orderNum: [{ required: true, message: "显示排序不能为空", trigger: "blur" }],
     email: [{ type: "email", message: "请输入正确的邮箱地址", trigger: ["blur", "change"] }],
     phone: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请输入正确的手机号码", trigger: "blur" }],
     rateValue: [
       { required: true, message: "费率不能为空", trigger: "blur" },
       { pattern: /^\d+(\.\d{1,2})?$/, message: "请输入正确的费率格式,最多两位小数", trigger: "blur" }
     ]
-  },
+  }
 })
 
 const { queryParams, form, rules } = toRefs(data)
 
+/** 下载模板 */
+const handleDownloadTemplate = () => {
+  download('/system/dept/importTemplate', {}, '供应商模板.xlsx')
+}
+
+/** 导入按钮操作 */
+function handleImport() {
+  upload.title = "供应商导入"
+  upload.open = true
+  upload.selectedFile = null
+}
+
+/** 文件上传中处理 */
+const handleFileUploadProgress = (event, file, fileList) => {
+  upload.isUploading = true
+}
+
+/** 文件选择处理 */
+const handleFileChange = (file, fileList) => {
+  upload.selectedFile = file
+}
+
+/** 文件删除处理 */
+const handleFileRemove = (file, fileList) => {
+  upload.selectedFile = null
+}
+
+/** 文件上传成功处理 */
+const handleFileSuccess = (response, file, fileList) => {
+  upload.open = false
+  upload.isUploading = false
+  proxy.$refs["uploadRef"].handleRemove(file)
+  proxy.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果", { dangerouslyUseHTMLString: true })
+  getList()
+}
+
+/** 提交上传文件 */
+function submitFileForm() {
+  const file = upload.selectedFile
+  if (!file || file.length === 0 || !file.name.toLowerCase().endsWith('.xls') && !file.name.toLowerCase().endsWith('.xlsx')) {
+    proxy.$modal.msgError("请选择后缀为 “xls”或“xlsx”的文件。")
+    return
+  }
+  proxy.$refs["uploadRef"].submit()
+}
+
 /** 查询部门列表 */
 function getList() {
   loading.value = true
@@ -318,7 +443,7 @@ function submitForm() {
 
 /** 删除按钮操作 */
 function handleDelete(row) {
-  proxy.$modal.confirm('是否确认删除名称为"' + row.deptName + '"的数据项?').then(function() {
+  proxy.$modal.confirm('是否确认删除名称为"' + row.deptName + '"的数据项?').then(function () {
     return delDept(row.deptId)
   }).then(() => {
     getList()

+ 17 - 8
jd-logistics-ui-v3/src/views/system/user/index.vue

@@ -47,12 +47,13 @@
               <el-col :span="1.5">
                 <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['system:user:remove']">删除</el-button>
               </el-col>
-<!--              <el-col :span="1.5">
-                <el-button type="info" plain icon="Upload" @click="handleImport" v-hasPermi="['system:user:import']">导入</el-button>
-              </el-col>
+
               <el-col :span="1.5">
-                <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:user:export']">导出</el-button>
-              </el-col>-->
+                <el-button type="info" plain icon="Upload" @click="handleImport" v-hasPermi="['system:user:add']">导入</el-button>
+              </el-col>
+<!--              <el-col :span="1.5">-->
+<!--                <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:user:export']">导出</el-button>-->
+<!--              </el-col>-->
               <right-toolbar v-model:showSearch="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
             </el-row>
 
@@ -195,9 +196,9 @@
         <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
         <template #tip>
           <div class="el-upload__tip text-center">
-            <div class="el-upload__tip">
-              <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据
-            </div>
+<!--            <div class="el-upload__tip">-->
+<!--              <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据-->
+<!--            </div>-->
             <span>仅允许导入xls、xlsx格式文件。</span>
             <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="importTemplate">下载模板</el-link>
           </div>
@@ -219,6 +220,7 @@ import useAppStore from '@/store/modules/app'
 import { changeUserStatus, listUser, resetUserPwd, delUser, getUser, updateUser, addUser, deptTreeSelect } from "@/api/system/user"
 import { Splitpanes, Pane } from "splitpanes"
 import "splitpanes/dist/splitpanes.css"
+import {download} from "@/utils/request.js";
 
 const router = useRouter()
 const appStore = useAppStore()
@@ -427,6 +429,13 @@ function handleSelectionChange(selection) {
   multiple.value = !selection.length
 }
 
+
+// 下载模板
+const handleDownloadTemplate = () => {
+  // 直接调用 download 方法,传入 URL 和文件名(可选)
+  download('/system/user/importTemplate', {}, '用户模板.xlsx')
+}
+
 /** 导入按钮操作 */
 function handleImport() {
   upload.title = "用户导入"

+ 6 - 0
jd_logistics-app/api/address.js

@@ -42,3 +42,9 @@ export function getLastAddress() {
   return request.get('system/front/book/getRecentAddresses')
 }
 
+/**
+ * 获取地址信息你
+ */
+export function getAddressInfo(data) {
+  return request.post('system/kd100/wxmini/queryIcrExpres',data)
+}

+ 3 - 3
jd_logistics-app/config/env.js

@@ -3,10 +3,10 @@
 // let domain = 'http://192.168.100.199:8081' // 晋守桦IP
 // let domain = 'http://192.168.100.14:8081' // 赵乔功IP
 // let domain = 'http://192.168.100.146:8079' // 马二勇
- // let domain = 'http://192.168.100.92:8080' // 朝龙
+    //let domain = 'http://192.168.100.92:8080' // 朝龙
   //let domain = 'http://192.168.101.213:8080' // 小明
- 
- let domain = 'https://rjsd.mychery.com/prod-api' //线上环境
+ let domain = 'http://192.168.101.39:8080' // 学富
+ //let domain = 'https://rjsd.mychery.com/prod-api' //线上环境
 
 const getBaseUrl = () => {
   // 获取小程序账户信息(包含环境版本)

+ 23 - 27
jd_logistics-app/pages.json

@@ -7,6 +7,13 @@
 				"navigationStyle": "custom"
 			}
 		},
+		{
+			"path": "pages/order/index",
+			"style": {
+				"navigationBarTitleText": "",
+				"navigationStyle": "custom"
+			}
+		},
 		{
 			"path": "pages/mine/mine",
 			"style": {
@@ -46,6 +53,18 @@
 			"style": {
 				"navigationBarTitleText": "关于我们"
 			}
+		},
+		{
+			"path": "pages/order/create_order",
+			"style": {
+				"navigationBarTitleText": "创建订单"
+			}
+		},
+		{
+			"path": "pages/order/order_detail",
+			"style": {
+				"navigationBarTitleText": "订单详情"
+			}
 		}
 	],
 	"subPackages": [
@@ -59,29 +78,6 @@
 				}
 			}]
 		},
-		{
-			"root": "pages/order",
-			"name": "order",
-			"pages": [{
-					"path": "index",
-					"style": {
-						"navigationBarTitleText": "订单列表"
-					}
-				},
-				{
-					"path": "order_detail",
-					"style": {
-						"navigationBarTitleText": "订单详情"
-					}
-				},
-				{
-					"path": "create_order",
-					"style": {
-						"navigationBarTitleText": "创建订单"
-					}
-				}
-			]
-		},
 		{
 			"root": "pages/address",
 			"name": "address",
@@ -118,10 +114,10 @@
 			"iconPath": "static/img/tabs/home.png",
 			"text": "首页"
 		}, {
-			"pagePath": "pages/search/search",
-			"selectedIconPath": "static/img/tabs/search_active.png",
-			"iconPath": "static/img/tabs/search.png",
-			"text": "查快递"
+			"pagePath": "pages/order/index",
+			"selectedIconPath": "/static/img/tabs/order_active.png",
+			"iconPath": "/static/img/tabs/order.png",
+			"text": "订单"
 		}, {
 			"pagePath": "pages/mine/mine",
 			"selectedIconPath": "static/img/tabs/user_active.png",

+ 90 - 2
jd_logistics-app/pages/address/address_list.vue

@@ -1,5 +1,30 @@
 <template>
 	<view class="address-page">
+		
+		<!-- 搜索框(原生 input 实现,兼容微信小程序) -->
+		<view class="search-section">
+			<view class="search-box">
+				<!-- 搜索图标 -->
+				<view class="search-icon">
+					<u-icon name="search" size="22" color="#999"></u-icon>
+				</view>
+				<!-- 输入框 -->
+				<input 
+					class="search-input" 
+					type="text" 
+					v-model="searchKeyword" 
+					placeholder="请输入姓名/手机号/地址"
+					placeholder-class="placeholder-style"
+					confirm-type="search"
+					@confirm="handleSearch"
+				/>
+				<!-- 自定义清除按钮 -->
+				<view v-if="searchKeyword" class="search-clear" @click.stop="handleClear">
+					<u-icon name="close-circle" size="22" color="#999"></u-icon>
+				</view>
+			</view>
+		</view>
+		
 		<!-- 地址列表 -->
 		<view class="address-list">
 			<!-- 地址项组件 -->
@@ -49,6 +74,7 @@
 		updateBook
 	} from '../../api/address'
 
+	const searchKeyword = ref('')
 	const pageNum = ref(1)
 	const pageSize = ref(10)
 	const recordTotal = ref(0)
@@ -211,6 +237,18 @@
 		})
 	}
 
+	// 搜索(点击键盘搜索或清除后调用)
+	const handleSearch = () => {
+		pageNum.value = 1
+		getAddressList()
+	}
+
+	// 清除按钮点击
+	const handleClear = () => {
+		searchKeyword.value = ''
+		handleSearch()
+	}
+
 	const loadMore = () => {
 		pageNum.value++
 		getAddressList(true)
@@ -220,7 +258,8 @@
 	const getAddressList = () => {
 		const params = {
 			pageNum: pageNum.value,
-			pageSize: pageSize.value
+			pageSize: pageSize.value,
+			searchKeyword:searchKeyword.value
 		}
 
 		uni.showLoading({
@@ -246,7 +285,7 @@
 	}
 </script>
 
-<style scoped>
+<style scoped lang="less">
 	.address-page {
 		display: flex;
 		flex-direction: column;
@@ -254,6 +293,55 @@
 		background-color: #F5F7FA;
 	}
 
+	.search-section {
+		background-color: #fff;
+		padding: 16rpx;
+		margin-left: 14rpx;
+	}
+
+	.search-box {
+		display: flex;
+		align-items: center;
+		background-color: #F5F7FA;
+		border-radius: 36rpx;
+		padding: 0 20rpx;
+		height: 72rpx; /* 与 u-search 高度一致 */
+	}
+
+	.search-icon {
+		margin-right: 16rpx;
+		display: flex;
+		align-items: center;
+	}
+
+	.search-input {
+		flex: 1;
+		height: 100%;
+		font-size: 28rpx;
+		color: #333;
+		background-color: transparent;
+		border: none;
+		outline: none;
+	}
+
+	.placeholder-style {
+		color: #999;
+		font-size: 28rpx;
+	}
+
+	.search-clear {
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		margin-left: 16rpx;
+		padding: 8rpx;
+		
+		&:active {
+			opacity: 0.6;
+		}
+	}
+
+
 	.address-list {
 		padding: 20rpx 30rpx 152rpx;
 		box-sizing: border-box;

+ 242 - 45
jd_logistics-app/pages/address/edit.vue

@@ -1,9 +1,20 @@
 <template>
 	<view class="container">
+		<view class="form-card-textarea">
+			<view class="form-item">
+				<textarea class="input-field-textarea flex-item" placeholder="请输入文本,自动识别姓名、电话和地址"
+					placeholder-class="placeholder" v-model="textArea" maxlength="250" />
+			</view>
 
-		<!-- 物品信息 -->
-		<view class="form-card">
+			<view class="form-item">
+				<view class="search-btn" @click="handleSearch">
+					粘贴并识别
+				</view>
+			</view>
+		</view>
 
+		<!-- 物品信息 -->
+		<view class="form-card" style="margin-top: 20rpx;">
 			<!-- 姓名 + 电话 并排 -->
 			<view class="form-item row">
 				<input class="input-field flex-item" placeholder="姓名" placeholder-class="placeholder" maxlength="20"
@@ -40,18 +51,20 @@
 			</view>
 		</view>
 
-		<view class="section-title"  v-if="addressList.length > 0">最近使用地址</view>
+		<view class="section-title" v-if="addressList.length > 0">最近使用地址</view>
 
 		<!-- 最近使用地址 -->
-		<view class="recent-address"  v-if="addressList.length > 0">
+		<view class="recent-address" v-if="addressList.length > 0">
 			<view class="address-item" v-for="(item, index) in addressList" :key="item.id"
-			 @click="onSelectAddress(item)">
+				@click="onSelectAddress(item)">
 				<AddressInfo :address="item" />
 			</view>
 		</view>
 
 		<!-- 确定按钮 -->
-		<view class="submit-btn" @click="onConfirm">确定</view>
+		<view class="add-btn-container">
+			<view class="submit-btn" @click="onConfirm">确定</view>
+		</view>
 
 		<!-- 安全区域占位 -->
 		<view class="safe-area"></view>
@@ -70,22 +83,25 @@
 	import {
 		addBook,
 		updateBook,
-		getBook,getLastAddress
+		getBook,
+		getLastAddress,
+		getAddressInfo
 	} from '@/api/address.js'
 
 	const addType = ref('') // 'sender' 或 'receiver',表示从下单页面哪个字段进入
-	
+
 	const addressList = ref([])
 
+	const textArea = ref('')
+
 	// 表单数据
 	const formData = reactive({
-		addressId:undefined,
+		addressId: undefined,
 		contactName: '',
 		contactPhone: '',
 		provinceName: '',
 		cityName: '',
 		countyName: '',
-		addressId: null,
 		detailedAddress: '',
 		defaultFlag: 0
 	})
@@ -102,6 +118,102 @@
 		getAddressList()
 	});
 
+	// 粘贴并识别功能
+	const handleSearch = async () => {
+		try {
+			// 1. 读取剪贴板内容
+			const clipboardText = await new Promise((resolve, reject) => {
+				uni.getClipboardData({
+					success: res => resolve(res.data),
+					fail: err => reject(err)
+				});
+			});
+
+			if (!clipboardText) {
+				uni.showToast({
+					title: '剪贴板内容为空',
+					icon: 'none'
+				});
+				return;
+			}
+
+			// 可选:将剪贴板内容显示到文本域中,方便用户查看
+			textArea.value = clipboardText;
+
+			uni.showLoading({
+				title: '识别中...',
+				mask: true
+			});
+
+			// 2. 调用接口解析地址
+			const params = {
+				param: clipboardText
+			}; // 根据后端接口要求调整参数格式
+			const res = await getAddressInfo(params);
+			uni.hideLoading();
+
+			if (res.code === 200 && res.data?.result?.length > 0) {
+				const result = res.data.result[0];
+
+				// 填充姓名
+				if (result.name) {
+					formData.contactName = result.name;
+				}
+
+				// 填充电话(取第一个手机号)
+				if (result.mobile && result.mobile.length > 0) {
+					formData.contactPhone = result.mobile[0];
+				}
+
+				// 填充省市区
+				if (result.xzq) {
+					// 从 fullName 中拆分省市区
+					if (result.xzq.fullName) {
+						const parts = result.xzq.fullName.split(',').map(s => s.trim());
+						formData.provinceName = parts[0] || '';
+						formData.cityName = parts[1] || '';
+						formData.countyName = parts[2] || '';
+					} else {
+						// 兼容旧的字段
+						formData.provinceName = result.xzq.province || '';
+						formData.cityName = result.xzq.city || '';
+						formData.countyName = result.xzq.district || '';
+					}
+
+					// 填充详细地址:优先使用 subArea,否则尝试从完整地址中去除省市区前缀
+					if (result.xzq.subArea) {
+						formData.detailedAddress = result.xzq.subArea;
+					} else if (result.address) {
+						const fullAddr = result.address;
+						const prefix = `${formData.provinceName}${formData.cityName}${formData.countyName}`;
+						if (fullAddr.startsWith(prefix)) {
+							formData.detailedAddress = fullAddr.substring(prefix.length);
+						} else {
+							formData.detailedAddress = fullAddr; // 保底
+						}
+					}
+				}
+
+				uni.showToast({
+					title: '识别成功',
+					icon: 'success'
+				});
+			} else {
+				uni.showToast({
+					title: res.message || '识别失败,请重试',
+					icon: 'none'
+				});
+			}
+		} catch (error) {
+			uni.hideLoading();
+			uni.showToast({
+				title: '操作失败',
+				icon: 'none'
+			});
+			console.error('粘贴识别错误:', error);
+		}
+	};
+
 	// 获取地址详情
 	const getAddress = async () => {
 		let res = await getBook(formData.addressId);
@@ -158,34 +270,55 @@
 	const onConfirm = async () => {
 		// 姓名校验
 		if (!formData.contactName || formData.contactName.trim() === '') {
-			return uni.showToast({ title: '请输入姓名', icon: 'none' });
+			return uni.showToast({
+				title: '请输入姓名',
+				icon: 'none'
+			});
 		}
 		if (formData.contactName.length > 20) {
-			return uni.showToast({ title: '姓名不能超过20个字符', icon: 'none' });
+			return uni.showToast({
+				title: '姓名不能超过20个字符',
+				icon: 'none'
+			});
 		}
 
 		// 电话校验
 		if (!formData.contactPhone) {
-			return uni.showToast({ title: '请输入联系电话', icon: 'none' });
+			return uni.showToast({
+				title: '请输入联系电话',
+				icon: 'none'
+			});
 		}
 		if (!isValidPhone(formData.contactPhone)) {
-			return uni.showToast({ title: '请输入正确的手机号码', icon: 'none' });
+			return uni.showToast({
+				title: '请输入正确的手机号码',
+				icon: 'none'
+			});
 		}
 
 		// 省市区校验
 		if (!formData.provinceName) {
-			return uni.showToast({ title: '请选择省市区', icon: 'none' });
+			return uni.showToast({
+				title: '请选择省市区',
+				icon: 'none'
+			});
 		}
 
 		// 详细地址校验
 		if (!formData.detailedAddress || formData.detailedAddress.trim() === '') {
-			return uni.showToast({ title: '请输入详细地址', icon: 'none' });
+			return uni.showToast({
+				title: '请输入详细地址',
+				icon: 'none'
+			});
 		}
 		if (formData.detailedAddress.length > 100) {
-			return uni.showToast({ title: '详细地址不能超过100个字符', icon: 'none' });
+			return uni.showToast({
+				title: '详细地址不能超过100个字符',
+				icon: 'none'
+			});
 		}
 		uni.showLoading({
-			title:'正在保存',
+			title: '正在保存',
 			mask: true
 		})
 
@@ -194,18 +327,27 @@
 		let res = await api;
 
 		if (res.code === 200) {
-			uni.showToast({ title: '保存成功', icon: 'success' });
-			debugger
+			uni.showToast({
+				title: '保存成功',
+				icon: 'success'
+			});
+
 			// 如果接口返回了新地址数据,更新到formData(特别是新增时的ID)
 			if (!formData.addressId) {
 				formData.addressId = res.data
 			}
-			debugger
+			if (addType.value !== 'sender' && addType.value !== 'receiver') {
+				uni.navigateBack() // 返回上一页
+				return;
+			}
 			onSelectAddress(formData);
 			uni.hideLoading()
 		} else {
 			uni.hideLoading()
-			uni.showToast({ title: res.msg || '保存失败', icon: 'none' });
+			uni.showToast({
+				title: res.msg || '保存失败',
+				icon: 'none'
+			});
 		}
 	};
 
@@ -218,33 +360,55 @@
 			type: addType.value,
 			address
 		});
-		
+
 		uni.navigateBack() // 返回上一页
 	};
-	
+
 	// 获取地址列表
 	const getAddressList = () => {
 		getLastAddress().then(res => {
 			addressList.value = res.data
-		}, err => {
-		})
+		}, err => {})
 	}
-	
 </script>
 
 <style scoped lang="less">
 	.container {
 		background-color: #F5F7FA;
 		min-height: 100vh;
-		padding: 20rpx 20rpx 30rpx 20rpx;
+		padding: 20rpx 0rpx 30rpx 0rpx;
 	}
 
 	.form-card {
+		margin: 0rpx 20rpx;
 		background-color: #fff;
 		border-radius: 32rpx;
 		padding: 0 20rpx;
 	}
 
+	.form-card-textarea {
+		margin: 0rpx 20rpx;
+		background-color: #fff;
+		border-radius: 32rpx;
+		padding: 20rpx 20rpx;
+
+		.search-btn {
+			width: 204rpx;
+			height: 72rpx;
+			background: #1B64F0;
+			border-radius: 38rpx;
+			font-weight: 400;
+			font-size: 32rpx;
+			color: #FFFFFF;
+			line-height: 72rpx;
+			text-align: center;
+			font-style: normal;
+			position: absolute;
+			right: 40rpx;
+
+		}
+	}
+
 	.form-item {
 		display: flex;
 		align-items: center;
@@ -256,11 +420,38 @@
 			gap: 20rpx;
 		}
 
+		&.column {
+			flex-direction: column;
+		}
+
 		&:last-child {
 			border-bottom: none;
 		}
 	}
 
+	.input-field-textarea {
+		height: 200rpx;
+		line-height: 48rpx;
+		font-size: 28rpx;
+		color: #333;
+		background: transparent;
+		padding: 20rxp 0rpx;
+
+		&.flex-item {
+			flex: 1;
+			width: auto;
+			min-width: 0; // 防止溢出
+		}
+
+		&.full-width {
+			width: 100%;
+		}
+
+		.placeholder {
+			color: #999;
+		}
+	}
+
 	/* 输入框通用样式 */
 	.input-field {
 		height: 100rpx;
@@ -332,11 +523,12 @@
 		font-size: 32rpx;
 		color: #333333;
 		line-height: 48rpx;
-		margin: 20rpx 0;
+		margin: 20rpx;
 		font-weight: bold;
 	}
 
 	.recent-address {
+		margin: 0rpx 20rpx;
 		background-color: #fff;
 		padding: 0 30rpx;
 	}
@@ -346,23 +538,28 @@
 		border-bottom: 1rpx solid #eee;
 	}
 
-	/* 确定按钮 */
-	.submit-btn {
+	.add-btn-container {
+		width: 100%;
 		position: fixed;
-		bottom: 40rpx;
-		left: 30rpx;
-		right: 30rpx;
-		width: 686rpx;
-		height: 88rpx;
-		background: #1B64F0;
-		border-radius: 44rpx;
-		display: flex;
-		justify-content: center;
-		align-items: center;
-		font-size: 32rpx;
-		color: #FFFFFF;
-		line-height: 88rpx;
-		z-index: 10;
+		bottom: 0rpx;
+		padding: 32rpx;
+		background-color: #fff;
+		border-top: 1rpx solid #eee;
+		box-sizing: border-box;
+
+		/* 确定按钮 */
+		.submit-btn {
+			height: 88rpx;
+			background: #1B64F0;
+			border-radius: 44rpx;
+			color: #fff;
+			font-size: 32rpx;
+			font-weight: 500;
+			height: 88rpx;
+			line-height: 88rpx;
+			text-align: center
+		}
+
 	}
 
 	.safe-area {

+ 12 - 12
jd_logistics-app/pages/index/components/PersonalExpressDialog.vue

@@ -10,20 +10,20 @@
 
 			<!-- 物流选项 -->
 			<view class="express-options">
+				<!-- 京东选项 -->
+				<view class="express-option jd-option" :class="{ 'selected': selectedExpress === '京东' }"
+					@click="selectExpress('京东')">
+					<image class="option-icon" src="/static/img/icon-logo-jd.png" mode="aspectFit" />
+					<text class="option-text">京东物流</text>
+				</view>
+				
 				<!-- 顺丰选项 -->
 				<view class="express-option sf-option" :class="{ 'selected': selectedExpress === '顺丰' }"
 					@click="selectExpress('顺丰')">
 					<image class="option-icon" src="/static/img/icon-logo-sf.png" mode="aspectFit" />
 					<text class="option-text">顺丰物流</text>
-
 				</view>
 
-				<!-- 京东选项 -->
-				<view class="express-option jd-option" :class="{ 'selected': selectedExpress === '京东' }"
-					@click="selectExpress('京东')">
-					<image class="option-icon" src="/static/img/icon-logo-jd.png" mode="aspectFit" />
-					<text class="option-text">京东物流</text>
-				</view>
 			</view>
 
 			<!-- 取消按钮 -->
@@ -84,12 +84,12 @@
 		// 延时关闭并传递选择结果
 		setTimeout(() => {
 			// const url = encodeURIComponent(company == '京东' ? "https://rjsd.mychery.com/jd.html" : "https://rjsd.mychery.com/sf.html")
-			const url = encodeURIComponent(company == '京东' ? "https://rjsd.mychery.com/jd" : "https://rjsd.mychery.com/sf")
-			uni.navigateTo({
-				url: '/pages/webView/webView?title=个人寄件&url=' + url
-			})
+			// const url = encodeURIComponent(company == '京东' ? "https://rjsd.mychery.com/jd/" : "https://rjsd.mychery.com/sf/")
+			// uni.navigateTo({
+			// 	url: '/pages/webView/webView?title=个人寄件&url=' + url
+			// })
 			
-			return
+			// return
 
 			const appId = company == '京东' ? "wx73247c7819d61796" : "wxd4185d00bf7e08ac"
 			wx.navigateToMiniProgram({

+ 115 - 17
jd_logistics-app/pages/index/index.vue

@@ -13,8 +13,20 @@
 			</swiper>
 		</view>
 
+		<view class="search-section">
+			<view class="search-input-wrapper">
+				<image class="search-icon" src="@/static/img/search.png" />
+				<input class="search-input" placeholder="请输入要查询的运单号" placeholder-class="placeholder-style"
+					@focus="onInputFocus" @blur="onInputBlur" v-model="trackingNumber" />
+				<view class="search-btn" @click="handleSearch">
+					搜索
+				</view>
+			</view>
+
+		</view>
+
 		<view class="btn-container">
-			
+
 			<view class="btn-item" @click="handleExpress('1')">
 				<image class="button-icon" src="/static/img/index-un-time.png" />
 				<view class="button-right">
@@ -22,8 +34,8 @@
 					<view class="button-desc">下单当日取件</view>
 				</view>
 			</view>
-			
-	<!-- 		<view class="btn-item" @click="handleExpress('2')">
+
+			<!-- 		<view class="btn-item" @click="handleExpress('2')">
 				<image class="button-icon" src="/static/img/index-time.png" />
 				<view class="button-right">
 					<view class="button-title">瑞鲸速达(顺丰)</view>
@@ -31,7 +43,7 @@
 				</view>
 
 			</view> -->
-			
+
 			<view class="btn-item" @click="showExpressDialog">
 				<image class="button-icon" src="/static/img/index-personal.png" />
 				<view class="button-right">
@@ -71,6 +83,10 @@
 
 	// 轮播图数据
 	const swiperList = ref([])
+	
+	
+	const trackingNumber = ref('')
+	const isInputFocused = ref(false)
 
 	onShow(() => {
 		getBannerList()
@@ -103,20 +119,45 @@
 			url: `/pages/order/create_order?product=${company}`
 		})
 	}
-	
+
 	const handleBannerClick = (item) => {
-	  if (!item.linkUrl) {
-	    // uni.showToast({ title: '暂无跳转链接', icon: 'none' });
-	    return;
-	  }
-	 if (item.linkUrl.startsWith('http://') || item.linkUrl.startsWith('https://')) {
+		//  if (!item.linkUrl) {
+		//    // uni.showToast({ title: '暂无跳转链接', icon: 'none' });
+		//    return;
+		//  }
+		// if (item.linkUrl.startsWith('http://') || item.linkUrl.startsWith('https://')) {
+		// uni.navigateTo({
+		//   url: `/pages/webView/webView?url=${encodeURIComponent(item.linkUrl)}`
+		// })
+		//  } else {
+		// uni.showToast({ title: '链接格式不支持', icon: 'none' })
+		//  }
+	};
+	
+	
+	const onInputFocus = () => {
+		isInputFocused.value = true
+	}
+	
+	const onInputBlur = () => {
+		isInputFocused.value = false
+	}
+	
+	const handleSearch = async () => {
+		if (!await checkLoginShowModal()) return;
+		if (!trackingNumber.value.trim()) {
+			uni.showToast({
+				title: '请输入运单号',
+				icon: 'none'
+			})
+			return
+		}
 		uni.navigateTo({
-		  url: `/pages/webView/webView?url=${encodeURIComponent(item.linkUrl)}`
+			url:'/pages/logistics/index?orderNo=' + trackingNumber.value.trim()
 		})
-	  } else {
-		uni.showToast({ title: '链接格式不支持', icon: 'none' })
-	  }
-	};
+		return
+	}
+	
 </script>
 
 <style lang="scss" scoped>
@@ -216,12 +257,69 @@
 		border-radius: 4rpx;
 	}
 
+
+	/* 搜索区域 */
+	.search-section {
+		position: relative;
+		top: -40rpx;
+		width: 100%;
+		padding: 0 20rpx;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+
+		.search-input-wrapper {
+			width: 100%;
+			height: 88rpx;
+			background: #FFFFFF;
+			border-radius: 44rpx;
+			font-size: 28rpx;
+			color: #333;
+			border: 4rpx solid #1B64F0;
+			padding: 6rpx;
+			display: flex;
+			justify-content: center;
+			justify-items: center;
+			align-items: center;
+
+			.search-icon {
+				width: 40rpx;
+				height: 40rpx;
+				margin-left: 18rpx;
+			}
+
+			.search-input {
+				flex: 1;
+				margin-left: 8rpx;
+				margin-right: 8rpx;
+			}
+
+
+			.placeholder-style {
+				color: #999999;
+			}
+
+			.search-btn {
+				width: 160rpx;
+				height: 76rpx;
+				background: #1B64F0;
+				border-radius: 38rpx;
+				font-weight: 400;
+				font-size: 32rpx;
+				color: #FFFFFF;
+				line-height: 76rpx;
+				text-align: center;
+				font-style: normal;
+			}
+
+		}
+
+	}
+
 	.btn-container {
 		display: flex;
 		flex-wrap: wrap;
 		justify-content: space-between;
-		position: relative;
-		top: -40rpx;
 		padding: 0rpx 20rpx;
 
 		.btn-item {

+ 1 - 1
jd_logistics-app/pages/mine/login.vue

@@ -10,7 +10,7 @@
 		<template v-if="loginMode === 'password'">
 			<!-- 手机号输入框 -->
 			<view class="input-wrapper">
-				<input v-model="phone" type="number" maxlength="11" class="input-field" placeholder="请输入帐号"
+				<input v-model="phone" maxlength="11" class="input-field" placeholder="请输入帐号"
 					placeholder-style="color: #999;" confirm-type="done" />
 			</view>
 

+ 18 - 3
jd_logistics-app/pages/mine/mine.vue

@@ -13,7 +13,15 @@
 						:src="userAvatar"
 						mode="aspectFill"
 						:show-level="false"
-					></u-avatar>
+						default-url="/static/img/default-avatar.png"
+						></u-avatar>
+					
+					<!-- <image
+						@click="toUser"
+						:src="userAvatar"
+						mode="aspectFill"
+						class="avatar"
+					></image> -->
 					<view class="user-text-info">
 						<view class="user-name-section">
 							<view v-if="isLoggedIn">
@@ -47,13 +55,13 @@
 		<view class="menu-section">
 			<view class="menu-card">
 				<!-- 订单列表 -->
-				<view class="menu-item" @click="toOrderList">
+	<!-- 			<view class="menu-item" @click="toOrderList">
 					<view class="menu-item-left">
 						<image src="/static/img/mine/icon-mine-order.png" class="menu-icon"></image>
 						<text class="menu-text">订单列表</text>
 					</view>
 					<image src="/static/img/arrow-right.png" class="arrow-icon"></image>
-				</view>
+				</view> -->
 
 				<!-- 地址簿 -->
 				<view class="menu-item" @click="toAddressBook">
@@ -148,6 +156,7 @@ const userAvatar = computed(() => {
 	return appStore.userInfo?.avatar || '/static/img/default-avatar.png';
 });
 
+
 const displayName = computed(() => {
 	return appStore.userInfo?.nickName || appStore.userInfo?.userName;
 });
@@ -290,6 +299,12 @@ function userLogoutFn() {
 				display: flex;
 				align-items: center;
 				min-height: 144rpx;
+				
+				.avatar {
+					width: 144rpx;
+					height: 144rpx;
+					border-radius: 50%;
+				}
 
 				.user-text-info {
 					flex: 1;

+ 1 - 1
jd_logistics-app/pages/order/components/OrderItem.vue

@@ -16,7 +16,7 @@
 				<view class="status">{{ getStatusText(orderDetail.orderStatus) }}</view>
 
 				<image v-if="orderDetail.orderStatus == 5" src="/static/img/translte-1.png"></image>
-				<image v-if="orderDetail.orderStatus == 6" src="/static/img/translte-3.png"></image>
+				<image v-else-if="orderDetail.orderStatus == 6" src="/static/img/translte-3.png"></image>
 				<image v-else src="/static/img/translte-2.png"></image>
 			</view>
 

+ 29 - 19
jd_logistics-app/pages/order/components/TimePopup.vue

@@ -20,14 +20,14 @@
         <!-- 左侧日期选择 -->
         <scroll-view class="date-sidebar" scroll-y>
           <view 
-            v-for="date in dateList" 
+            v-for="(date,index) in dateList" 
             :key="date.value"
             class="date-item"
             :class="{ 
               active: selectedDate === date.value,
               today: date.isToday
             }"
-            @tap="selectDate(date.value)"
+            @tap="selectDate(date.value,index)"
           >
             <view class="date-content">
               <text class="date-name" 
@@ -50,7 +50,7 @@
             </view>
             <view 
               class="recommend-time"
-              :class="{ active: selectedTime === withinOneHourSlot.value }"
+              :class="{ active: selectedTime === withinOneHourSlot.value && selectedDay ===  selectedCurrentDay}"
               @tap="selectTime(withinOneHourSlot.value, true)"
             >
               <text class="time-value">{{ withinOneHourSlot.label }}</text>
@@ -67,7 +67,7 @@
                 :key="timeSlot.value"
                 class="time-item"
                 :class="{ 
-                  active: selectedTime === timeSlot.value,
+                  active: selectedTime === timeSlot.value && selectedDay ===  selectedCurrentDay,
                   disabled: timeSlot.disabled,
                   night: timeSlot.night
                 }"
@@ -89,7 +89,7 @@
       </view>
       
       <!-- 操作按钮 -->
-      <view class="action-bar">
+ <!--     <view class="action-bar">
         <button 
           class="confirm-btn" 
           :class="{ active: selectedTime }"
@@ -97,7 +97,7 @@
         >
           {{ buttonText }}
         </button>
-      </view>
+      </view> -->
     </view>
   </u-popup>
 </template>
@@ -108,7 +108,7 @@ import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
 const props = defineProps({
   visible: { type: Boolean, default: false },
   days: { type: Number, default: 3 },
-  startTime: { type: Number, default: 8 },
+  startTime: { type: Number, default: 9 },
   endTime: { type: Number, default: 20 },
   autoSelect: { type: Boolean, default: true }
 })
@@ -119,6 +119,9 @@ const emit = defineEmits(['update:visible', 'close', 'confirm'])
 const currentTime = ref(new Date())
 const selectedDate = ref('')
 const selectedTime = ref('')
+const selectedDay = ref('')
+const selectedCurrentDayPosition = ref(0)
+const selectedCurrentDay = ref('')
 const loading = ref(false)
 const isWithinOneHour = ref(false)
 
@@ -162,7 +165,7 @@ const withinOneHourSlot = computed(() => {
   return {
     start: startHour + startMinute / 60,
     end: endHour + endMinute / 60,
-    label: `(${startStr}-${endStr})`,
+    label: `${startStr}-${endStr}`,
     value: `immediate:${startStr}-${endStr}`, // ✅ 唯一标识
     startHour, startMinute, endHour, endMinute
   }
@@ -242,24 +245,28 @@ const timeSlots = computed(() => {
 const buttonText = computed(() => selectedTime.value ? '确定' : '请选择上门时间')
 
 // ----- 核心:切换日期(自动根据 autoSelect 选中第一个可用时段)-----
-const selectDate = (date) => {
+const selectDate = (date,index) => {
   selectedDate.value = date
-  selectedTime.value = ''
-  isWithinOneHour.value = false
+  selectedCurrentDayPosition.value = index
+  selectedCurrentDay.value = dateList.value[index].label
+  
+  // selectedTime.value = ''
+  // isWithinOneHour.value = false
 
   // 若开启自动选择,立即为该日期选择一个合适的时间
   if (props.autoSelect) {
     // 1. 如果是今天且有推荐时段,优先选中推荐
-    if (date === todayDate.value && withinOneHourSlot.value) {
+    if (selectedTime.value == '' && !isWithinOneHour.value) {
       selectedTime.value = withinOneHourSlot.value.value
       isWithinOneHour.value = true
     } else {
-      // 2. 否则选中该日期下第一个可用普通时段
-      const firstSlot = timeSlots.value[0]
-      if (firstSlot) {
-        selectedTime.value = firstSlot.value
-        isWithinOneHour.value = false
-      }
+	  isWithinOneHour.value = false
+      // // 2. 否则选中该日期下第一个可用普通时段
+      // const firstSlot = timeSlots.value[0]
+      // if (firstSlot) {
+      //   selectedTime.value = firstSlot.value
+      //   isWithinOneHour.value = false
+      // }
     }
   }
 }
@@ -268,13 +275,16 @@ const selectDate = (date) => {
 const selectTime = (time, isImmediate = false) => {
   selectedTime.value = time
   isWithinOneHour.value = isImmediate
+  selectedDay.value = selectedCurrentDay.value
+  confirm()
 }
 
 // ----- 初始化弹窗(打开时)-----
 const initSelection = () => {
   if (dateList.value.length) {
     // 直接调用 selectDate,复用自动选择逻辑
-    selectDate(dateList.value[0].value)
+    selectDate(dateList.value[selectedCurrentDayPosition.value].value,selectedCurrentDayPosition.value)	
+	selectedDay.value = selectedCurrentDay.value
   }
 }
 

+ 151 - 140
jd_logistics-app/pages/order/create_order.vue

@@ -9,7 +9,7 @@
 				<view class="user-info">
 					<AddressInfo v-if="addressSend.addressId" :address="addressSend" />
 					<view v-else class="create-btn" @click="handleAddAddress('sender')">新建寄件人</view>
-					
+
 				</view>
 				<view class="img-status-text right" @click="openAddressBook('sender')">
 					<image src="/static/img/create-order-address.png" mode="" class="address-image"></image>
@@ -112,68 +112,85 @@
 			</view>
 		</view>
 
-		<view class="pickup-title">增值服务</view>
+		<!-- 增值服务标题(带折叠箭头) -->
+		<view class="pickup-title" style="display: flex; justify-content: space-between; align-items: center;">
+			<text>增值服务</text>
+			<u-icon :name="showValueAdded ? 'arrow-up' : 'arrow-down'" size="18" color="#999" @click="showValueAdded = !showValueAdded"></u-icon>
+		</view>
 
-		<!-- 增值服务卡片 -->
+		<!-- 增值服务卡片(折叠内容) -->
 		<view class="goods-card">
-			<view class="goods-item" v-if="product === '1'">
-				<view class="item-label">包装服务</view>
-				<view class="item-control">
-					<switch color="#007AFF" :checked="valueServices.isPack" @change="onPackagingChange" />
+			<block v-if="showValueAdded">
+				<!-- 展开状态:显示所有增值服务项 -->
+				<view class="goods-item" v-if="product === '1'">
+					<view class="item-label">包装服务</view>
+					<view class="item-control">
+						<switch color="#007AFF" :checked="valueServices.isPack" @change="onPackagingChange" />
+					</view>
 				</view>
-			</view>
 
-			<view class="goods-item">
-				<view class="item-label">保价</view>
-				<view class="item-control">
-					<switch color="#007AFF" :checked="insuranceAmountChecked" @change="onInsuranceChange" />
+				<view class="goods-item">
+					<view class="item-label">保价</view>
+					<view class="item-control">
+						<switch color="#007AFF" :checked="insuranceAmountChecked" @change="onInsuranceChange" />
+					</view>
 				</view>
-			</view>
 
-			<view v-if="insuranceAmountChecked" class="goods-item">
-				<view class="item-label">保价金额(元)</view>
-				<view class="item-control">
-					<input class="input-field" placeholder="请输入保价金额" placeholder-class="placeholder"
-						v-model="insuranceAmount" type="digit" maxlength="10" @input="validateInsuranceAmount" />
+				<view v-if="insuranceAmountChecked" class="goods-item">
+					<view class="item-label">保价金额(元)</view>
+					<view class="item-control">
+						<input class="input-field" placeholder="请输入保价金额" placeholder-class="placeholder"
+							v-model="insuranceAmount" type="digit" maxlength="10" @input="validateInsuranceAmount" />
+					</view>
 				</view>
-			</view>
 
-			<!-- 超长超重(顺丰/京东) -->
-		<!-- 	<view class="goods-item" v-if="product === '2'">
-				<view class="item-label">超长超重</view>
-				<view class="item-control">
-					<switch color="#007AFF" :checked="valueServices.isOverLongWeight" @change="onOverweightChange" />
-				</view>
-			</view> -->
+				<!-- 超长超重(顺丰/京东) -->
+				<!-- 	<view class="goods-item" v-if="product === '2'">
+					<view class="item-label">超长超重</view>
+					<view class="item-control">
+						<switch color="#007AFF" :checked="valueServices.isOverLongWeight" @change="onOverweightChange" />
+					</view>
+				</view> -->
 
-			<!-- 签单返还 -->
-			<view class="goods-item"  v-if="product === '1'">
-				<view class="item-label">签单返还</view>
-				<view class="item-control">
-					<switch color="#007AFF" :checked="valueServices.isReceiptCollect" @change="onSignReturnChange" />
+				<!-- 签单返还 -->
+				<view class="goods-item" v-if="product === '1'">
+					<view class="item-label">签单返还</view>
+					<view class="item-control">
+						<switch color="#007AFF" :checked="valueServices.isReceiptCollect" @change="onSignReturnChange" />
+					</view>
 				</view>
-			</view>
 
-			<!-- 顺丰:签单返还类型选择 -->
-			<view v-if="product === '2' && valueServices.isReceiptCollect" class="goods-item">
-				<view class="item-label">返还类型</view>
-				<view class="item-control">
-					<picker :range="receiptReturnTypes" :range-key="'label'" @change="onReceiptReturnTypeChange"
-						:value="receiptReturnTypeIndex">
-						<view class="picker-text">{{ receiptReturnTypes[receiptReturnTypeIndex]?.label || '请选择返还类型' }}
-						</view>
-					</picker>
-					<u-icon class="arrow" name='arrow-right' size="18"></u-icon>
+				<!-- 顺丰:签单返还类型选择 -->
+				<view v-if="product === '2' && valueServices.isReceiptCollect" class="goods-item">
+					<view class="item-label">返还类型</view>
+					<view class="item-control">
+						<picker :range="receiptReturnTypes" :range-key="'label'" @change="onReceiptReturnTypeChange"
+							:value="receiptReturnTypeIndex">
+							<view class="picker-text">{{ receiptReturnTypes[receiptReturnTypeIndex]?.label || '请选择返还类型' }}
+							</view>
+						</picker>
+						<u-icon class="arrow" name='arrow-right' size="18"></u-icon>
+					</view>
 				</view>
-			</view>
 
-			<!-- 打木架(仅顺丰) -->
-		<!-- 	<view v-if="product === '2'" class="goods-item">
-				<view class="item-label">打木架</view>
-				<view class="item-control">
-					<switch color="#007AFF" :checked="valueServices.isWoodenCrate" @change="onWoodenFrameChange" />
+				<!-- 打木架(仅顺丰) -->
+				<!-- 	<view v-if="product === '2'" class="goods-item">
+					<view class="item-label">打木架</view>
+					<view class="item-control">
+						<switch color="#007AFF" :checked="valueServices.isWoodenCrate" @change="onWoodenFrameChange" />
+					</view>
+				</view> -->
+			</block>
+			<block v-else>
+				<!-- 折叠状态:显示一个可点击的展开提示行 -->
+				<view class="goods-item" @click="showValueAdded = true">
+					<view class="item-label">增值服务</view>
+					<view class="item-control">
+						<text class="picker-text">点击展开</text>
+						<u-icon name="arrow-down" size="18" color="#999"></u-icon>
+					</view>
 				</view>
-			</view> -->
+			</block>
 		</view>
 
 		<!-- 协议同意 -->
@@ -187,9 +204,12 @@
 			</view>
 		</view>
 
-		<!-- 下单按钮 -->
-		<view class="submit-btn" :class="{ disabled: !agreed }" :disabled="!agreed" @click="submitOrder">
-			提交订单
+
+		<view class="add-btn-container">
+			<!-- 下单按钮 -->
+			<view class="submit-btn" :class="{ disabled: !agreed }" :disabled="!agreed" @click="submitOrder">
+				提交订单
+			</view>
 		</view>
 
 		<!-- 安全区域占位 -->
@@ -256,9 +276,12 @@
 
 	// ==================== 时间选择 ====================
 	const showTimePicker = ref(false)
-	const selectedTimeData = ref(null)
+	const selectedTimeData = ref({
+		startTime:undefined,
+		endTime:undefined
+	})
 	const selectedTimeLabel = computed(() => {
-		if (!selectedTimeData.value) return '请选择时间'
+		if (!selectedTimeData.value.startTime) return '一小时内'
 		const {
 			dateLabel,
 			timeLabel,
@@ -346,6 +369,9 @@
 		}
 	])
 
+	// ==================== 折叠控制 ====================
+	const showValueAdded = ref(false) // 默认折叠
+
 	// ==================== 协议 ====================
 	const agreed = ref(true)
 
@@ -514,71 +540,32 @@
 			});
 			return false
 		}
-		// // 寄件人信息完整性
-		// if (!addressSend.value.contactName || !addressSend.value.contactPhone) {
-		// 	uni.showToast({
-		// 		title: '寄件人信息不完整',
-		// 		icon: 'none'
-		// 	});
-		// 	return false
-		// }
-		// if (!/^1[3-9]\d{9}$/.test(addressSend.value.contactPhone)) {
-		// 	uni.showToast({
-		// 		title: '寄件人手机号格式错误',
-		// 		icon: 'none'
-		// 	});
-		// 	return false
-		// }
-		// if (addressSend.value.contactName.length < 1 || addressSend.value.contactName.length > 20) {
-		// 	uni.showToast({
-		// 		title: '寄件人姓名长度1-20字符',
-		// 		icon: 'none'
-		// 	});
-		// 	return false
-		// }
-		// if (!addressSend.value.detailedAddress) {
-		// 	uni.showToast({
-		// 		title: '请填写寄件人人详细地址',
-		// 		icon: 'none'
-		// 	});
-		// 	return false
-		// }
-
-		// if (!addressReceive.value.contactName || !addressReceive.value.contactPhone) {
-		// 	uni.showToast({
-		// 		title: '收件人信息不完整',
-		// 		icon: 'none'
-		// 	});
-		// 	return false
-		// }
-		// if (!/^1[3-9]\d{9}$/.test(addressReceive.value.contactPhone)) {
-		// 	uni.showToast({
-		// 		title: '收件人手机号格式错误',
-		// 		icon: 'none'
-		// 	});
-		// 	return false
-		// }
-		// if (addressReceive.value.contactName.length < 1 || addressReceive.value.contactName.length > 20) {
-		// 	uni.showToast({
-		// 		title: '收件人姓名长度1-20字符',
-		// 		icon: 'none'
-		// 	});
-		// 	return false
-		// }
-		// if (!addressReceive.value.detailedAddress) {
-		// 	uni.showToast({
-		// 		title: '请填写收件人详细地址',
-		// 		icon: 'none'
-		// 	});
-		// 	return false
-		// }
 
 		// 时间
-		if (!selectedTimeData.value) {
+		if (!selectedTimeData.value.startTime) {
+			// 这没有数据的时候  默认一个小时内 获取当前时间
+			selectedTimeData.value.startTime = twentyMinutesLater()
+			selectedTimeData.value.endTime = oneHourLater()
+		}
+
+		if (isBeforeNineAM(selectedTimeData.value.startTime) || isAfterEightPM(selectedTimeData.value.startTime)) {
+			// 不在工作时间内
+			uni.showToast({
+				title: '请选择合适的寄件时间',
+				icon: 'none'
+			});
+			selectedTimeData.value.startTime = undefined
+			selectedTimeData.value.endTime = undefined
+			return false
+		}
+
+		if (isAfterEightPM(selectedTimeData.value.endTime)) {
 			uni.showToast({
-				title: '请选择期望上门时间',
+				title: '请选择合适的寄件时间',
 				icon: 'none'
 			});
+			selectedTimeData.value.startTime = undefined
+			selectedTimeData.value.endTime = undefined
 			return false
 		}
 
@@ -670,6 +657,25 @@
 		return true
 	}
 
+
+	const oneHourLater = () => {
+		const now = new Date()
+		return now.getHours() + now.getMinutes() / 60 + 1
+	}
+
+	const twentyMinutesLater = () => {
+		const now = new Date()
+		now.setMinutes(now.getMinutes() + 1)
+		return now
+	}
+
+	function isBeforeNineAM(date) {
+		return date.getHours() < 9;
+	}
+
+	function isAfterEightPM(date) {
+		return date.getHours() > 20 || (date.getHours() === 20 && date.getMinutes() > 0);
+	}
 	const isSubmit = ref(false)
 	// ==================== 提交订单 ====================
 	const submitOrder = async () => {
@@ -684,8 +690,7 @@
 				.value) : null,
 			isReceiptCollect: product.value === '2' ?
 				(valueServices.value.isReceiptCollect ? receiptReturnTypes.value[receiptReturnTypeIndex.value]
-					?.value : null) :
-				(valueServices.value.isReceiptCollect ? true : null),
+					?.value : null) : (valueServices.value.isReceiptCollect ? true : null),
 			isOverLongWeight: valueServices.value.isOverLongWeight || null,
 			isWoodenCrate: valueServices.value.isWoodenCrate || null
 		}
@@ -723,7 +728,7 @@
 
 		uni.showLoading({
 			title: '提交中...',
-			mask:true
+			mask: true
 		})
 		try {
 			const res = await createOrder(orderData)
@@ -734,7 +739,7 @@
 					icon: 'success',
 					mask: true
 				})
-				uni.redirectTo({
+				uni.switchTab({
 					url: '/pages/order/index'
 				})
 			} else {
@@ -751,7 +756,7 @@
 				icon: 'none'
 			})
 			console.error('订单提交失败', error)
-		} finally{
+		} finally {
 			// uni.hideLoading()
 		}
 	}
@@ -790,7 +795,7 @@
 				saveAddressToStorage('receiverAddress', data.address)
 			}
 		})
-		if(!addressSend.addressId){
+		if (!addressSend.addressId) {
 			fetchDefaultSenderAddress()
 		}
 	})
@@ -806,12 +811,12 @@
 	.order-container {
 		min-height: 100vh;
 		background-color: #F5F7FA;
-		padding: 20rpx;
 		padding-bottom: 180rpx;
 		box-sizing: border-box;
 	}
 
 	.info-card {
+		margin: 0rpx 20rpx;
 		background: #fff;
 		border-radius: 32rpx;
 		padding: 20rpx;
@@ -882,6 +887,7 @@
 	}
 
 	.pickup-title {
+		margin: 0rpx 20rpx;
 		font-size: 32rpx;
 		font-weight: 600;
 		color: #333;
@@ -889,6 +895,7 @@
 	}
 
 	.goods-card {
+		margin: 0rpx 20rpx;
 		background-color: #fff;
 		border-radius: 32rpx;
 		padding: 0rpx 20rpx;
@@ -1023,6 +1030,7 @@
 	}
 
 	.agreement-card {
+		margin: 0rpx 20rpx;
 		background-color: #fff;
 		border-radius: 32rpx;
 		padding: 30rpx 20rpx;
@@ -1047,30 +1055,33 @@
 		}
 	}
 
-	.submit-btn {
+	.add-btn-container {
+		width: 100%;
 		position: fixed;
-		bottom: 40rpx;
-		left: 30rpx;
-		right: 30rpx;
-		width: 686rpx;
-		height: 88rpx;
-		background: #1B64F0;
-		border-radius: 44rpx;
-		display: flex;
-		justify-content: center;
-		align-items: center;
-		font-size: 32rpx;
-		color: #FFFFFF;
-		line-height: 88rpx;
-		text-align: center;
-		z-index: 10;
+		bottom: 0rpx;
+		padding: 32rpx;
+		background-color: #fff;
+		border-top: 1rpx solid #eee;
+		box-sizing: border-box;
 
-		&.disabled {
-			background: #f5f5f5;
-			color: #999;
+		/* 确定按钮 */
+		.submit-btn {
+			height: 88rpx;
+			background: #1B64F0;
+			border-radius: 44rpx;
+			color: #fff;
+			font-size: 32rpx;
+			font-weight: 500;
+			height: 88rpx;
+			line-height: 88rpx;
+			text-align: center
 		}
+
 	}
 
+
+
+
 	.safe-area {
 		height: 140rpx;
 	}

+ 11 - 3
jd_logistics-app/pages/order/index.vue

@@ -27,7 +27,7 @@
 		<!-- 订单列表(保持不变) -->
 		<view class="order-list" @scrolltolower="loadMore">
 			<view v-if="ordersList.length" v-for="order in ordersList" :key="order.id">
-				<OrderItem :order-detail="order" @success="getOrderList()"></OrderItem>
+				<OrderItem :order-detail="order" @success="getOrderList()"/>
 			</view>
 			<view class="empty-state" v-else>
 				<u-icon class="empty-icon" name="list" size="60" color="#ccc"></u-icon>
@@ -142,10 +142,18 @@
 </script>
 
 <style lang="scss" scoped>
+	.container {
+		width: 100%;
+		min-height: 100vh;
+		background: linear-gradient( 135deg, #CFE9FF 0%, #F5F7FA 50.86%);
+		display: flex;
+		flex-direction: column;
+	}
+	
 	.search-section {
-		background-color: #fff;
-		padding: 16rpx;
 		margin-left: 14rpx;
+		margin-top: 96rpx;
+		margin-right: 210rpx;
 	}
 
 	.search-box {

+ 1 - 0
jd_logistics-app/pages/search/search.vue

@@ -66,6 +66,7 @@
 		})
 		return
 	}
+
 </script>
 
 <style lang="scss" scoped>

BIN
jd_logistics-app/static/img/default-avatar.png


BIN
jd_logistics-app/static/img/tabs/order.png


BIN
jd_logistics-app/static/img/tabs/order_active.png


+ 1 - 0
jd_logistics-app/stores/app.js

@@ -44,6 +44,7 @@ export const useAppStore = defineStore("app", {
       this.userInfo = undefined;
       Cache.clear(USER_INFO);
       Cache.clear(TOKEN);
+
     },
     UPDATE_USERINFO(userInfo) {
       this.userInfo = userInfo;

+ 10 - 4
jd_logistics-app/utils/request.js

@@ -21,7 +21,8 @@ function baseRequest(url, method, data, {
 	const appStore = useAppStore();
   const { Toast } = useToast();
 	let Url = HTTP_REQUEST_URL,header = HEADER
-	const TOKEN = 'Bearer ' + appStore.token
+	
+	const tempToken = 'Bearer ' + appStore.token
 	if (params != undefined) {
 		header = HEADERPARAMS;
 	}
@@ -35,7 +36,7 @@ function baseRequest(url, method, data, {
 	// 		});
 	// 	}
 	// }
-	if (TOKEN) header[TOKENNAME] = TOKEN;
+	if (appStore.token) header[TOKENNAME] = tempToken;
 	return new Promise((reslove, reject) => {
 		Url=HTTP_REQUEST_URL || 'http://api.front.hdq.xbdzz.cn'
 		uni.request({
@@ -52,9 +53,14 @@ function baseRequest(url, method, data, {
 					reslove(res.data, res);
 				else if ([410000, 410001, 410002, 401,403].indexOf(res.data.code) !== -1) {
 					// toLogin();
-					appStore.LOGOUT();
-					Toast({title: res.data.msg || '登录过期,请重新登录'});
+					Toast({title: '登录过期,请重新登录' });
 					reject(res.data);
+					appStore.LOGOUT();
+					setTimeout(()=>{
+						uni.switchTab({
+							url:'/pages/mine/mine'
+						})
+					},800)
 				} else
           Toast({title: res.data.msg || '系统错误'})
 					reject(res.data.msg || '系统错误');