Compare commits

..

No commits in common. "master" and "multiple_refund" have entirely different histories.

365 changed files with 2438 additions and 36257 deletions

1
.gitignore vendored
View File

@ -34,4 +34,3 @@ build/
.vscode/
/logs/
/ghy-admin/src/test/
ghy-shop/ADDRESS_QUERY_EXAMPLE.md

View File

@ -1,214 +0,0 @@
<!-- @author Yifei.Kuang -->
# 房间 / 群 / 群员业务需求说明文档
## 一、项目背景与目标
- **背景**
在现有「师傅 / 商城 / 分销」体系上,引入「房间(圈子)+ 群 + 分销」的新结构,实现多房间、多群、多身份的精细化运营与监管。
- **目标**
- 建立清晰的层级结构:**平台 → 房间 → 群 → 群员/分销**。
- 统一分销身份规则,保证订单与佣金归属准确。
- 支持群主、房间主、下级分销、运营商等多角色协同。
- 为后续房间收费、群收费、群员收费等模式预留空间。
---
## 二、核心概念定义
### 2.1 平台
- 系统最上层运营主体,负责全局参数(平台扣点、结算规则等)。
### 2.2 房间(圈子)
- **定义**:平台下的独立运营空间,一个平台可创建多个房间。
- **特点**
- 房间名称:限制在 46 个字。
- 房间标识图片、品牌注解由房间主配置。
- 顶部功能栏:默认为「师傅库 / 商城 / 会话厅」,文字可改,总长度有限制但功能不变。
- 房间可配置自身的功能权限(是否开放商城、是否允许群选品等)以及扣点、收费策略。
- **关系**
- 「微社圈」是整体产品名,“切换圈子”即切换不同房间。
### 2.3 群(分销群)
- **定义**:隶属于某房间的运营群,每个房间下可以创建多个群。
- **建群要求**
- 填写城市、区域、主营品类、预期群规模等信息。
- 建群申请需由房间主及后台审核(形式类似现有分销申请)。
- **职责**
- 每个群经营自己的商品与客户。
- 群商城中仅群主有选品权限,下级分销不能选品。
### 2.4 群主
- 该群的最高级分销者。
- 新建群后自动成为本群顶级分销(无上级分销)。
- 负责本群的选品、群成员管理、群内规则等。
### 2.5 群员 / 分销人员
- 所有群员可根据既有三级分销规则绑定上级关系。
- **分销身份规则**
- 每个群员在「平台 + 房间 + 群」这一组合下有一个独立分销身份。
- 同一微信号在不同房间、不同群中,对系统而言是多个独立身份。
- **影响**
- 每个身份对应一条独立的分销线。
- 订单结算与分账都按所在群对应的分销线进行。
### 2.6 系统机器人 / 监管号
- 平台可在任意群中驻入一个“系统机器人”账号:
- 拥有类似群主的管理能力及后台监管能力。
- 用于监管群运营是否健康、是否违规。
### 2.7 运营商(按微信号)
- 以微信号为主体的运营视角。
- 同一微信号在多个房间、多个群中有多条分销线,但在运营统计中可统一聚合。
---
## 三、分销身份与订单归属规则
### 3.1 唯一身份线
- 每条分销身份线由四段组合定义:
**平台ID + 房间ID + 群ID + 用户ID**
- 每一条组合都被视为“系统中的一个人、一条分销线”。
### 3.2 多群多房间身份
- 同一微信号在不同房间/群中创建或加入时:
- 系统会为其生成新的分销身份线。
- 不同房间、群的身份互不影响。
### 3.3 分销绑定
- 在某群中被拉入的新成员:
- 按现有三级分销规则建立上下级关系。
- 上下级关系限定在本群对应的分销线中。
### 3.4 订单与分销归属
- 用户从某个群入口进入商城并下单:
- 所有分销与分账都按该群的分销线计算。
- 即使服务商在其他群也有身份,本订单仍只归属于当前群对应的身份线。
---
## 四、房间与群的前台结构
### 4.1 房间首页结构
- 房间头部展示:
- 房间头像/标识图;
- 品牌名称46 字);
- 简短品牌注解。
- 顶部功能栏:
- 默认入口为:「师傅库 / 商城 / 会话厅」。
- 房间主可修改这三个名称(总长度有限制),但功能含义不变。
- 顶部入口与底部导航对应,为功能快捷入口。
### 4.2 师傅库
- 展示本房间下已入驻的师傅与服务店铺。
- 支持按街道、服务品类筛选。
- 师傅资料在现有认证信息基础上增加头像和定位信息。
- 用户可在师傅详情中:
- 直接发起“发布订单”给该师傅;
- 或将已有未接订单指派给该师傅。
### 4.3 商城
- 房间/群共用一个商城体系:
- 房间级定义基础类目与商品池。
- 群主在此基础上为本群做选品配置。
- 首页默认展示热门服务类目,可左划展示其他商品类目。
- 列表支持按价格、评分、销量筛选。
- 商品销量按整条上架商品做统一统计。
### 4.4 会话厅
- 作为房间的首页使用:
- 展示全部群、自建群、已加入群、单聊会话等。
- 顶部菜单包含:申请房间、申请建群、搜索群、房间名称设置等入口。
- 与群聊页面不同,主要承载群列表与会话入口。
---
## 五、订单与发布相关需求(概要)
### 5.1 师傅端状态汇总
- 师傅端首页顶部使用黄条展示:
- 新订单数量;
- 未约订单数量;
- 待上门/待发货数量。
- 点击不同统计可跳转到对应订单列表。
### 5.2 发单入口
- 页面底部设置蓝色「+」按钮作为发布主单入口。
- 支持:
- 服务类/商品类发单;
- 选择到第 4 级类目,可多选;
- 将常用配置保存为模板。
- 支持代填发布,由专业师傅代填问题内容,客户补充地址、电话后提交。
### 5.3 保险规则(概念级)
- 发单时默认勾选“启用保险核查服务费”。
- 发单方需选择保险费用由谁承担:
- 服务费由发单方支付;
- 服务费在订单中扣除。
- 到付场景下,已产生的保险费用仍需保留,并可在后续订单中抵扣。
### 5.4 报价/加价模式(概念级)
- 在满足一定条件(报价模式或允许商家报价)时,显示“加价/报价”入口。
- 支持大厅主单、未约/未排/监控单、已接单主单进行报价。
- 客户最多可选择 3 家(特例 4 家)报价,确认后进入支付流程。
---
## 六、「我的」与运营统计(概念级)
- “我的”页面延用现有结构:
- 展示分销中心、订单、选品等信息。
- 运营统计以微信号为主体:
- 汇总展示多房间、多群的运营数据;
- 可按房间、群维度下钻查看。
---
## 七、商品与服务上架(概念级)
- 服务上架沿用当前规则。
- 商品上架需区分于服务:
- 针对库存、规格、展示方式做单独设计;
- 与服务上架在前台展示上明显区分。
---
## 八、后台与安全监管(概念级)
- 房间级管理:
- 房间创建与审核;
- 房间启用/禁用;
- 房间收费与扣点配置。
- 群级管理:
- 建群审核;
- 群启用/禁用;
- 群主调整;
- 系统机器人驻入/移除。
- 操作审计:
- 记录房间、群创建和重要参数修改,便于运营追溯。
---
**文档定位**:业务需求说明(偏产品视角)
**用途**:为后续详细设计与开发提供业务背景和规则依据

View File

@ -1,285 +0,0 @@
<!-- @author Yifei.Kuang -->
# 房间 / 群 / 分销功能说明文档(开发视角)
## 一、整体架构
- 层级结构:
- 平台 → 房间Room→ 群Group→ 群员 / 分销身份Distributor
- 身份核心:
- 每条分销身份由「平台 + 房间 + 群 + 用户」组合唯一确定,用于分销归属和订单结算。
---
## 二、房间模块Room
### 2.1 房间功能点
- 创建房间申请:
- 用户提交房间名称、头像、品牌注解等信息。
- 后台审核通过后,生成房间,并指定房间主。
- 房间信息维护:
- 房间主可编辑名称、头像、品牌注解。
- 房间顶部功能栏配置:
- 默认显示「师傅库 / 商城 / 会话厅」三项。
- 房间主可以修改显示文案(总字数受限),功能类型不变。
- 房间权限与扣点设置(后台):
- 是否开启本房间商城。
- 是否允许本房间下的群进行选品。
- 房间级扣点与收费策略配置。
- 房间切换:
- 同一微信可加入多个房间,通过「切换圈子」在不同房间间切换。
---
## 三、群模块Group
### 3.1 建群与审核
- 在某房间内,用户可发起建群申请。
- 填写群基础信息(城市、区域、主营类目、群规模等)。
- 审核流程:
- 房间主初审;
- 后台终审;
- 通过后创建群,申请人自动成为群主。
### 3.2 群基本操作
- 群信息维护:
- 群主可编辑群名、介绍、主营描述等。
- 群状态控制(后台):
- 支持群的启用/禁用;
- 禁用后,群内发单、接单、分销等操作关闭或受限。
- 群主变更:
- 后台可在必要时调整群主(例如违规处理)。
### 3.3 群监管
- 支持在任意群中驻入“系统机器人/系统监管号”:
- 具备基本群管理与后台数据采集、监控能力。
- 用于运营与风险控制。
---
## 四、群员 / 分销身份模块
### 4.1 分销身份规则
- 每个用户在某「平台 + 房间 + 群」组合下对应一个分销身份。
- 同一微信在不同房间/群中拥有多个独立身份:
- 每个身份有独立的分销链;
- 后台视为多个“人”。
### 4.2 加入群与分销绑定
- 成员加入群时:
- 若在该群下不存在分销身份,则系统为其创建一条新身份线。
- 按既有三级分销规则绑定上级分销。
- 上下级分销关系:
- 限定在当前群对应的分销线中,不跨群共享。
### 4.3 角色与权限(概念层)
- 群主:
- 本群最高级分销;
- 拥有选品、群配置、成员管理等高权限。
- 管理员:
- 由群主任命,可拥有部分管理能力(禁言、审核、公告等)。
- 普通分销/群员:
- 不能在群内进行选品;
- 可以拉人建立下级分销关系。
---
## 五、会话厅与群聊相关功能
### 5.1 订单页面导航(左侧)
- 导航栏包含 4 项:
- 资源库;
- 商品城;
- 会话厅;
- 附近圈动态。
- 群主可以:
- 修改导航名称(总字数有限制);
- 单独开放/禁用任一入口;
- 与外层房间首页的导航机制保持一致。
- 右下角「会话大厅」按钮:
- 进入群聊页面(中间页);
- 文案可改,群主/平台可控制是否可用。
### 5.2 资源库A
- 展示服务师傅资料与店铺:
- 格式类似现有“师傅圈”,但样式可定制。
- 群主可设置仅群内成员可见,或继承房间级展示。
- 提供发布入口,支持基于群选品的类目发单。
### 5.3 商品城B
- 群级商城展示逻辑:
- 与整体商城逻辑一致;
- 差异在于:群商城的选品由群主独立配置。
- 所有人看到的商品、类目等均来源于群主选品结果。
- 首页热门类目默认服务类,可左滑出商品类目列表。
- 列表筛选按价格、评分、销量进行。
- 销量统计按整条商品聚合,不再按规格拆分。
### 5.4 会话厅C
- 会话厅为“会话/订单流”页面,不是群聊页面。
- 默认进入订单页时落在该列:
- 支持上拉刷新;
- 承载订单、系统相关信息的流式展示。
### 5.5 附近圈动态D
- 展示商家图文动态的“公共圈子”区域:
- 默认名称为“附近圈动态”;
- 群主可以改名,但含义不变(商家圈/动态圈)。
### 5.6 会话大厅图与编辑订单E
- 页面中部展示“会话大厅相关图”:
- 使用会话大厅图的一部分放大,作为视觉入口。
- 支持进入“编辑订单/发单页”:
- 编辑后的订单可发至全群;
- 管理员可选择仅发送至单个客户。
---
## 六、群聊在线控制与刷新机制
### 6.1 在线人数限制
- 当群聊在线人数超过上限(群主/后台可配置):
- 群主与管理员不受上线限制,始终在线。
- 系统自动将部分成员标记为离线:
- 优先踢出近期未发言的成员;
- 该过程对成员前端为“默默离线”,不会强制踢出页面。
### 6.2 重新上线与刷新
- 被标记为离线的成员:
- 在输入框输入内容时,自动重新上线。
- 新进群但未发言的成员:
- 一段时间后,输入框变为“消息刷新”按钮;
- 点击后重新加载消息,并作为新上线行为。
- 在已超上线限制的状态下:
- 新进入成员默认离线;
- 需主动刷新或发言才开始拉取实时消息。
### 6.3 页面跳转与上线状态
- 在群聊中点击任何产品、品类跳转其他页面:
- 无论是否超限,都视为离线(停止实时连接)。
- 从商品/其他页面返回群聊页:
- 自动恢复为在线状态。
- 在商品页面点击“聊天”:
- 跳回群聊,并恢复在线。
---
## 七、会话厅顶部类目与选品关系
### 7.1 顶部类目区
- 顶部显示:
- 「全部」入口;
- 若干热门类目。
- 热门类目:
- 群主从本群的主营/重点品类中选定;
- 可对特别重要的类目打红点标记。
- 展示方式:
- 左右滑动;
- 每行最多 8 个类目,最多展示两行。
### 7.2 选品关系
- 群主 = 分销顶层:
- 群主在本群选品的结果,体现在“全部”和热门类目展示中。
- 群员:
- 无法直接在群内进行选品;
- 仅能浏览、转发商品并参与分销。
---
## 八、群内订单与全域订单
### 8.1 群内订单发起
- 在群聊页面可以通过以下方式生成群内订单:
- 使用专门的“群内订单发单入口”;
- 将当前输入框的文字通过快捷键转换为订单(跳转到发单确认页)。
- 生成的群内订单:
- 在群聊中以订单卡片形式展示;
- 提供“接单”按钮。
### 8.2 与专业版(师傅端)的联动
- 若群内发单时勾选“保险”等高级字段:
- 该订单将按专业版(师傅端)逻辑处理;
- 接单、保险、结算等均走专业端流程。
- 群主可配置:
- 群内订单是否仅允许本群服务人员接单;
- 或是否允许进入大厅,被所有专业师傅接单。
### 8.3 全域订单
- 群主可将部分群内订单开放到“全域订单池”:
- 其他群的服务商也能在“全域订单”中看到这些订单并接单。
- 展示限制:
- 在群页面或全域订单列表中:
- 只有服务商能看到具体金额;
- 普通消费者看不到金额。
### 8.4 订单生命周期(概念)
- 典型状态流:
- 已发单 → 待服务(需要填写上门时间)→ 已提交 → 已付款 → 已完成。
- 客户侧操作:
- 在“已提交”中查看支付方式并确认;
- 确认支付后进入“已付款”。
- 服务侧操作:
- 服务方确认“已收款,结单”,进入“已完成”。
### 8.5 纯发单群模式
- 对于“只发单、不聊天”的群:
- 群聊可以不保持实时连接;
- 用户仅在手动刷新时看到新订单;
- 群形态接近“单纯接单页面”,以降低系统实时成本。
---
## 九、「我的」与运营视角
- “我的”页面沿用现有商城结构:
- 包含分销中心、订单、选品等模块。
- 统计以微信号为主视角:
- 汇总展示该用户在不同房间、群中的运营情况;
- 可按房间、群进行明细下钻。
---
## 十、后台与审计(功能级)
- 房间管理:
- 房间申请审批;
- 房间启用/禁用;
- 房间级扣点/收费配置。
- 群管理:
- 建群申请审核;
- 群启用/禁用;
- 群主调整;
- 系统机器人驻入/移除。
- 审计日志:
- 创建/修改房间、群;
- 修改扣点与重要配置;
- 关键权限调整(如群主、管理员变更)等操作均需记录。
---
**文档定位**:开发可读的功能说明(不含字段/接口细节)
**用途**:指导后续接口设计、表结构设计与前后端实现拆分

View File

@ -1,299 +0,0 @@
# 群成员身份标签与权限管理功能文档
## 文档说明
本文档描述群聊中**群成员身份标签、分类管理、权限控制、消息通知**相关的功能逻辑,不涉及字段/表结构设计,仅面向功能实现。
---
## 一、群成员身份标签系统
### 1.1 身份标签类型
系统支持以下身份标签:
- **创建者**:群创建者(通常也是群主)
- **管理员**:被群主任命的管理员
- **服务商家**:提供服务的商家/师傅
- **商品商家**:提供商品的商家
- **消费者**:普通消费者
- **发单人**:经常发单的用户
- **接单人**:经常接单的用户
- **群成员**:普通群成员
- **VIP客户**VIP客户
### 1.2 标签分配流程
- **入群时自选标签**
- 用户加入群时,系统提供两个初始选项:
- **非商家**
- **商家**
- 用户选择一个作为初始身份标识。
- **群主/管理员最终确认**
- 群主或管理员可以在群成员资料中:
- 查看用户自选的标签。
- 从系统标签库中选择一个标签,覆盖或确认用户的标签。
- 后续可以随时修改成员的标签。
- **标签对外展示**
- 标签会显示在群成员资料、群成员列表等位置,作为该成员在群内的“对外身份”。
### 1.3 群成员资料栏位
- **群成员资料页包含7个栏位**
- 每个栏位可以放置一个名称/备注。
- 这些栏位对所有身份/标签的群员都开放使用。
- 用途:方便所有群员查看和识别成员信息。
---
## 二、群成员分类/分组系统
### 2.1 分类概念
- **分类定义**
- 群内成员可以按照“分类”进行组织,每个分类可以理解为“分组”或“分仓”。
- 系统支持创建 **1~7个分类**
- 每个分类可以自定义命名例如“1类”、“2类”或自定义别名如“核心商家组”、“普通客户组”等
- **分类与标签的关系**
- 分类与身份标签是**独立的两套体系**
- 一个成员可以拥有一个身份标签(如“服务商家”)。
- 同时该成员可以被放入任意一个分类中如“1类”
- 标签不影响分类归属,分类也不影响标签展示。
### 2.2 分类操作
- **成员分类归属**
- 任何成员可以被放入任意一个分类中。
- 例如可以将某个“服务商家”放入“1类”也可以将某个“消费者”放入“1类”。
- 成员可以只属于一个分类,也可以不属于任何分类(显示在“未分类”或“全部”中)。
- **按分类查看成员**
- 群主与管理员可以:
- 按分类查看成员列表。
- 按标签查看成员列表。
- 按“分类+标签”组合筛选查看。
- **普通群成员查看**
- 普通群成员在群名单中:
- 可以按“全部”及“标签身份”查看成员信息。
- 不能按分类查看(分类信息对普通成员不展示)。
### 2.3 分类消息发送
- **管理员按分类发消息**
- 管理员可以:
- 选择向某个分类的所有成员发送消息(其他分类看不到)。
- 选择向某个分类中的单个成员发送消息。
- 用途:主要用于群管理员进行精细化运营和定向通知。
---
## 三、管理员任命与权限体系
### 3.1 管理员任命
- **任命流程**
- 群主可以任命任意群成员为管理员。
- 任命时可以:
- 标注该管理员的“岗位名称”(例如“客服主管”、“运营专员”等)。
- 有岗位名称的管理员会在“服务团队消息专列”中显示。
- **订单交付权限(独立于管理员)**
- 订单交付栏的权限与管理员身份独立:
- 群主可以勾选某些成员(不一定是管理员)拥有“订单交付权限”。
- 拥有交付权限的人可以在订单交付栏中发布交付信息。
### 3.2 管理员权限列表
群主在任命管理员时,可以勾选该管理员拥有的权限项。管理员在哪个分类中不影响其权限范围。
#### 权限1按类发群信息
- 管理员可以向指定分类的所有成员发送群消息(其他分类看不到)。
#### 权限2禁言与消息可见性控制
- **禁言功能(实际为“审核可见”)**
- 管理员可以按分类或单个成员设置“禁言”。
- 被禁言的成员:
- 仍然可以发送消息,但消息默认**仅管理员可见 + 自己可见**。
- 管理员可以在后台审核这些消息,勾选后才会展示到群聊页面。
- 严格来说这不是传统“禁言”,而是“审核可见”机制。
- **消息可见性设置**
- 管理员可以:
- 按分类设置:该类群员发的消息仅该类成员可见,或仅管理员可见。
- 按单个成员设置:该成员发的消息仅管理员可见(在群内形成独立通道,对其他人无感)。
- **特殊规则**
- 被禁言的成员仍然可以发送商品链接到群(商品链接不受禁言限制)。
- 管理员查看消息的规则:
- 如果管理员属于某个分类,只能看到该类群员发的信息。
- 如果管理员在“全部”分类中,可以看到所有分类群员发的信息。
- **管理员@解禁**
- 管理员可以@被禁言的成员临时解禁3小时。
#### 权限3禁止接单
- 管理员可以按分类或单个成员设置“禁止点击接单键”。
- 被禁止的成员无法接取群消息中的订单。
#### 权限4禁止发单
- 管理员可以按分类或单个成员设置“禁止点击发单键”。
- 被禁止的成员无法使用发单功能(包括类目发单)。
#### 权限5禁止互加好友
- 管理员可以按分类或单个成员设置“禁止互加好友”。
- 被禁止的成员:
- 别人无法添加他为好友。
- 他也无法添加别人为好友。
- **特殊规则**
- 即使被禁止加好友,双方仍然可以:
- 在服务团队聊天中直接对话(通过服务团队入口)。
#### 权限6屏蔽群内信息
- 管理员可以按分类或单个成员设置“屏蔽群内信息”。
- 被屏蔽的成员:
- 看不到群内在发的消息。
- **但订单仍然可见可接**(屏蔽消息,不屏蔽订单展示)。
#### 权限7禁止发圈信息
- 管理员可以按分类或单个成员设置“禁止发圈信息”。
- 被禁止的成员无法在商家圈/动态圈中发布内容。
#### 权限8审核成员入群
- 管理员可以审核新成员的入群申请。
#### 权限9删除成员与撤回消息
- 管理员可以:
- 删除群成员(将成员移出群)。
- 撤回群成员的消息:
- 可以撤回任意成员的一条消息。
- 可以彻底删除消息(删除后不可见,不可恢复)。
#### 权限10分类分标签发公告
- 管理员可以:
- 按分类发送公告。
- 按标签发送公告。
- 按“分类+标签”组合发送公告。
---
## 四、群主专属权限
### 4.1 群名设置
- 群主可以修改群名称。
### 4.2 群转让
- 群主可以将群主身份转让给其他成员。
### 4.3 开通入群申请
- 群主可以开启/关闭“入群申请”功能。
- 开启后,新成员需要申请才能加入群。
### 4.4 待接单显示规则(待定)
- 群主可以设置“待接单是否仅显示本群的订单”(此功能待定,可能不实现)。
---
## 五、群消息通知机制
### 5.1 消息通知基础规则
#### 未打开登录页面的通知策略
- 用户未打开登录页面APP未打开
- 系统每 **5分钟** 聚合一次新消息,发送一条通知。
- 通知内容显示所有群的新消息汇总例如“您有X条新消息”
- 用户打开APP后不再发送聚合通知。
#### 群外消息计数
- 在群列表页面(群外):
- 每个群名旁边显示该群的消息数量角标。
- APP端统一使用角标显示。
### 5.2 群消息免打扰设置
#### 免打扰选项
每个群成员可以为自己设置该群的“免打扰”策略,选项包括:
- **仅1小时1条**1小时内只通知一次。
- **仅1天1条**1天内只通知一次。
- **仅3天1条**3天内只通知一次。
- **仅10天1条**10天内只通知一次。
#### 免打扰与通知队列的关系
- 系统维护多个通知队列:
- **5分钟通知队列**默认队列每5分钟通知一次。
- **1小时通知队列**设置了“1小时1条”的用户进入此队列。
- **1天通知队列**设置了“1天1条”的用户进入此队列。
- **3天通知队列**设置了“3天1条”的用户进入此队列。
- **10天通知队列**设置了“10天1条”的用户进入此队列。
- 用户设置免打扰后:
- 从“5分钟队列”中剔除进入对应的免打扰队列。
- 例如设置“1小时1条”后每1小时聚合通知一次而不是每5分钟
#### 通知时间窗口
- **5分钟队列与1小时队列**
- 晚上7点后不通知。
- 早上8点后才开始通知。
- **1天队列、3天队列、10天队列**
- 通知时间点可以设定在12点或错开时间点例如1天队列12点3天队列14点10天队列16点以减少大量通知同时推送。
#### 用户类型与免打扰选择
- **经营者(商家/师傅)**
- 更多选择“5分钟通知”或“1小时通知”需要及时响应
- **客户(消费者)**
- 更多选择“3天通知”或“10天通知”降低打扰频率
### 5.3 @通知机制
#### @通知规则
- **无论用户是否设置免打扰**,被@时:
- 使用**手机上方消息栏**直接通知(不进入队列等待)。
- 通知带有声音提醒(用户可以自定义声音)。
- 不等待5分钟/1小时等时间窗口立即推送。
#### @通知展示位置
- @通知显示在手机顶部通知栏(系统级通知)。
---
## 六、消息通知总结
### 6.1 通知队列体系
系统维护以下通知队列:
1. **5分钟通知队列**(默认)
- 时间窗口早上8点 ~ 晚上7点。
- 每5分钟聚合通知一次。
2. **1小时通知队列**
- 时间窗口早上8点 ~ 晚上7点。
- 每1小时聚合通知一次。
3. **1天通知队列**
- 在指定时间点例如12点通知一次。
4. **3天通知队列**
- 在指定时间点例如14点通知一次。
5. **10天通知队列**
- 在指定时间点例如16点通知一次。
### 6.2 特殊通知(不受队列限制)
- **@通知**
- 立即推送,使用手机顶部通知栏。
- 带声音提醒。
- 不受免打扰设置影响。
### 6.3 通知聚合规则
- **未打开APP时**
- 所有群的新消息统一聚合为一条通知例如“您有X条新消息”
- 按用户所属队列的时间窗口进行通知。
- **打开APP后**
- 不再发送聚合通知。
- 用户可以在APP内查看各群的具体消息。
---
## 七、功能总结
### 7.1 身份标签与分类
- 9种身份标签入群时自选群主/管理员可最终确认和修改。
- 支持1~7个分类分类与标签独立成员可被放入任意分类。
### 7.2 管理员权限
- 10个权限点群主可灵活配置每个管理员的权限。
- 订单交付权限独立于管理员身份。
### 7.3 消息通知
- 5个通知队列5分钟/1小时/1天/3天/10天用户可自由选择。
- @通知立即推送,不受免打扰影响。
- 时间窗口控制,避免夜间打扰。
---
## 八、待定事项
- 待接单是否仅显示本群的订单(功能待定)。
---
**文档版本**v1.0
**最后更新**2024年

View File

@ -17,38 +17,6 @@
<dependencies>
<dependency>
<groupId>com.tencentcloudapi.cls</groupId>
<artifactId>tencentcloud-cls-logback-appender</artifactId>
<version>1.0.3</version>
</dependency>
<!-- 阿里云api-SDK -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dytnsapi20200217</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>tea-openapi</artifactId>
<version>0.3.6</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>tea-console</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>tea-util</artifactId>
<version>0.2.23</version>
</dependency>
<!-- SpringBoot集成thymeleaf模板 -->
<dependency>
<groupId>org.springframework.boot</groupId>
@ -143,10 +111,6 @@
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.ghy</groupId>
<artifactId>ghy-shop</artifactId>
</dependency>
</dependencies>

View File

@ -4,18 +4,13 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* 启动程序
*
* @author clunt
*/
@EnableScheduling
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class GhyApplication
{
@ -39,25 +34,4 @@ public class GhyApplication
public RestTemplate restTemplate(){
return new RestTemplate();
}
private CorsConfiguration corsConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
// 请求常用的三种配置*代表允许所有当时你也可以自定义属性比如header只能带什么只能是post方式等等
// corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.setAllowCredentials(true);
corsConfiguration.addAllowedOriginPattern("*");
corsConfiguration.setMaxAge(3600L);
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfig());
return new CorsFilter(source);
}
}

View File

@ -7,27 +7,21 @@ import com.ghy.common.adapay.model.Event;
import com.ghy.common.adapay.model.PayCallback;
import com.ghy.common.adapay.model.PaymentDTO;
import com.ghy.common.enums.PayStatus;
import com.ghy.order.domain.OrderAddSubtract;
import com.ghy.order.domain.OrderMaster;
import com.ghy.order.mapper.OrderMasterMapper;
import com.ghy.order.service.IOrderAddSubtractService;
import com.ghy.order.service.OrderMasterService;
import com.ghy.payment.domain.FinancialChangeRecord;
import com.ghy.payment.domain.FinancialDetail;
import com.ghy.payment.domain.FinancialMaster;
import com.ghy.payment.domain.PaymentRelation;
import com.ghy.payment.mapper.PaymentRelationMapper;
import com.ghy.payment.service.CallBackService;
import com.ghy.payment.service.FinancialChangeRecordService;
import com.ghy.payment.service.FinancialDetailService;
import com.ghy.payment.service.FinancialMasterService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
@ -35,160 +29,98 @@ import java.util.concurrent.CompletableFuture;
*
* @author HH 2022/5/31
*/
@Slf4j
@Service("payCallbackService")
public class PayCallbackService implements CallBackService {
@Resource
OrderMasterService orderMasterService;
private static final Logger logger = LoggerFactory.getLogger(PayCallbackService.class);
@Resource
FinancialMasterService financialMasterService;
@Resource
PaymentRelationMapper paymentRelationMapper;
@Resource
FinancialDetailService financialDetailService;
@Resource
IOrderAddSubtractService orderAddSubtractService;
@Resource
FinancialChangeRecordService financialChangeRecordService;
@Override
@Transactional(rollbackFor = Exception.class)
public void onCallback(Event event) {
log.info("支付回调: {}", event);
logger.info("支付回调: {}", event);
String data = event.getData();
PayCallback payment = JSON.parseObject(data, PayCallback.class);
PaymentDTO dto = financialMasterService.selectPaymentById(payment.getId());
// 支付ID
final String paymentId = dto.getId();
// 是否支付成功
final boolean succeeded = AdapayStatusEnum.succeeded.code.equals(payment.getStatus());
// 异步更新交易记录 避免被其它业务异常回滚
// 校验是否是本系统发出去的支付请求
if (dto != null) {
CompletableFuture.runAsync(() -> {
// 异步更新交易记录 避免被回滚
PaymentDTO param = new PaymentDTO();
param.setId(payment.getId());
param.setStatus(payment.getStatus());
if (succeeded) {
// 如果支付成功 更新支付渠道支付时间手续费
param.setPayChannel(payment.getPayChannel());
param.setFeeAmt(payment.getFeeAmt());
param.setStatus(payment.getStatus());
param.setPayTime(LocalDateTime.now());
if ("delay".equals(dto.getPayMode())) {
// 如果支付成功 且是延迟分账模式 更新可用金额=交易金额
param.setAvailableAmt(dto.getPayAmt());
}
}
financialMasterService.updatePayment(param);
});
if (AdapayStatusEnum.succeeded.code.equals(payment.getStatus())) {
if (payment.getOrderNo().split("_").length > 2) {
// 支付回调中的加价记录ID
String fcrIdStr = payment.getOrderNo().split("_")[1];
String[] fcrIds = fcrIdStr.split(",");
if (succeeded) {
// 支付成功 查询支付关联的订单
List<PaymentRelation> paymentRelations = paymentRelationMapper.selectByPaymentId(paymentId);
if (CollectionUtils.isEmpty(paymentRelations)) {
log.error("未关联订单的支付回调: {}", data);
return;
}
BigDecimal totalChangeMoney = BigDecimal.ZERO;
Long financialMasterId = null;
for (String fcrId : fcrIds) {
FinancialChangeRecord financialChangeRecord = new FinancialChangeRecord();
financialChangeRecord.setId(Long.valueOf(fcrId));
financialChangeRecord.setPayStatus(1);
// 加价的支付paymentId回填到remark
financialChangeRecord.setRemark(payment.getId());
financialChangeRecord.setRemark(payment.getId());
financialChangeRecord.setPaymentId(payment.getId());
financialChangeRecordService.update(financialChangeRecord);
for (PaymentRelation relation : paymentRelations) {
Long relationId = relation.getRelationId();
if (PaymentRelation.FINANCIAL_MASTER.equals(relation.getRelationIdType())) {
FinancialMaster financialMaster = financialMasterService.selectById(relationId);
// 更新主订单的支付信息
orderMasterService.updatePayStatus(financialMaster.getOrderMasterId(), PayStatus.PAID.getCode());
// 更新主财务单的支付信息
financialMasterService.updatePay(relationId, paymentId, PayStatus.PAID.getCode());
log.info("主财务单[{}]支付成功", relationId);
// 检查是否为商品订单且有关联的服务订单需要同步更新服务订单财务主单支付状态
try {
OrderMaster orderMaster = orderMasterService.selectById(financialMaster.getOrderMasterId());
if (orderMaster != null && orderMaster.getOrderType() == 1 && orderMaster.getHasServiceOrder() == 1) {
// 查询关联的服务订单
OrderMaster serviceOrder = orderMasterService.selectByGoodsOrderMasterId(orderMaster.getId());
if (serviceOrder != null) {
// 查询服务订单对应的财务主单
FinancialMaster serviceFinancialMaster = financialMasterService.selectByOrderMasterId(serviceOrder.getId());
if (serviceFinancialMaster != null && !PayStatus.PAID.getCode().equals(serviceFinancialMaster.getPayStatus())) {
// 更新服务订单财务主单支付状态
financialMasterService.updatePay(serviceFinancialMaster.getId(), paymentId, PayStatus.PAID.getCode());
// 更新服务订单支付状态
orderMasterService.updatePayStatus(serviceOrder.getId(), PayStatus.PAID.getCode());
log.info("商品订单[{}]关联的服务订单[{}]财务主单[{}]支付状态已同步更新为已支付",
orderMaster.getId(), serviceOrder.getId(), serviceFinancialMaster.getId());
}
}
}
} catch (Exception e) {
log.error("同步更新商品订单关联服务订单支付状态时发生异常商品订单ID: {}, 异常信息: {}",
financialMaster.getOrderMasterId(), e.getMessage(), e);
}
} else if (PaymentRelation.FINANCIAL_CHANGE.equals(relation.getRelationIdType())) {
// 更新加价单的支付信息
financialChangeRecordService.updatePay(relationId, paymentId, PayStatus.PAID.getCode());
FinancialChangeRecord fc = financialChangeRecordService.selectFinancialChangeRecordById(relationId);
// 修改子订单的payMoney
FinancialDetail fd = financialDetailService.selectByOrderDetailId(fc.getOrderDetailId());
FinancialDetail fd2Update = new FinancialDetail();
fd2Update.setId(fd.getId());
fd2Update.setPayMoney(fd.getPayMoney());
fd2Update.setPayStatus(PayStatus.PAID.getCode());
financialDetailService.updateFinancialDetail(fd2Update);
FinancialChangeRecord fc = financialChangeRecordService.selectFinancialChangeRecordById(financialChangeRecord.getId());
FinancialDetail financialDetail = financialDetailService.selectByOrderDetailId(fc.getOrderDetailId());
FinancialDetail financialDetail2Update = new FinancialDetail();
financialDetail2Update.setId(financialDetail.getId());
financialDetail2Update.setPayMoney(financialDetail.getPayMoney().add(fc.getChangeMoney()));
financialDetail2Update.setPayStatus(PayStatus.PAID.getCode());
financialDetailService.updateFinancialDetail(financialDetail2Update);
totalChangeMoney = totalChangeMoney.add(fc.getChangeMoney());
if (financialMasterId == null) {
financialMasterId = financialDetail.getFinancialMasterId();
}
}
// 修改主单的payMoney
FinancialMaster financialMaster = financialMasterService.selectById(fd.getFinancialMasterId());
FinancialMaster financialMaster = financialMasterService.selectById(financialMasterId);
FinancialMaster financialMaster2Update = new FinancialMaster();
financialMaster2Update.setId(financialMaster.getId());
financialMaster2Update.setPayMoney(financialMaster.getPayMoney());
financialMaster2Update.setPayMoney(financialMaster.getPayMoney().add(totalChangeMoney));
financialMaster2Update.setPayStatus(PayStatus.PAID.getCode());
financialMasterService.updateFinancialMaster(financialMaster2Update);
// 更新主订单的支付信息
orderMasterService.updatePayStatus(financialMaster.getOrderMasterId(), PayStatus.PAID.getCode());
log.info("FinancialChange[{}]支付成功", relationId);
} else if (PaymentRelation.ORDER_ADD.equals(relation.getRelationIdType())) {
// 更新订单追加单的支付信息
orderAddSubtractService.updatePay(relationId, paymentId, PayStatus.PAID.getCode());
OrderAddSubtract orderAdd = orderAddSubtractService.selectById(relationId);
// 修改子订单的payMoney
FinancialDetail fd = financialDetailService.selectByOrderDetailId(orderAdd.getOrderDetailId());
FinancialDetail fd2Update = new FinancialDetail();
fd2Update.setId(fd.getId());
fd2Update.setPayMoney(fd.getPayMoney());
fd2Update.setPayStatus(PayStatus.PAID.getCode());
financialDetailService.updateFinancialDetail(fd2Update);
// 修改主单的payMoney
FinancialMaster financialMaster = financialMasterService.selectById(fd.getFinancialMasterId());
FinancialMaster financialMaster2Update = new FinancialMaster();
financialMaster2Update.setId(financialMaster.getId());
financialMaster2Update.setPayMoney(financialMaster.getPayMoney());
financialMaster2Update.setPayStatus(PayStatus.PAID.getCode());
financialMasterService.updateFinancialMaster(financialMaster2Update);
log.info("订单追加[{}]支付成功", relationId);
} else if (PaymentRelation.CONSULT_ADD.equals(relation.getRelationIdType())) {
// 更新加价单的支付信息
financialChangeRecordService.updatePay(relationId, paymentId, PayStatus.PAID.getCode());
// TODO 拆分对应的分账流水
}
// 更新主财务单状态
financialMasterService.paySucceeded(payment.getId(), payment.getPayChannel());
} else {
log.error("未知的订单类型: relationIdType={}, relationId={}", relation.getRelationIdType(), relationId);
}
logger.warn("支付失败 : {}", data);
}
} else {
logger.warn("系统中不存在这条交易记录: {}", event);
}
}
@Override
public void onResponse(JSONObject response) {
log.info("发起支付 Response: {}", response.toJSONString());
logger.info("发起支付 Response: {}", response.toJSONString());
// 保存一条支付记录
PaymentDTO payment = response.toJavaObject(PaymentDTO.class);
String status = payment.getStatus();
payment.setStatus(AdapayStatusEnum.pending.code);
financialMasterService.insertPayment(payment);
if (!AdapayStatusEnum.succeeded.code.equals(status)) {
log.warn("发起支付失败 : {}", response.toJSONString());
logger.warn("发起支付失败 : {}", response.toJSONString());
}
}

View File

@ -1,66 +0,0 @@
package com.ghy.callback;
import com.alibaba.fastjson.JSONObject;
import com.ghy.common.adapay.model.AdapayStatusEnum;
import com.ghy.common.adapay.model.Event;
import com.ghy.common.adapay.model.PaymentDTO;
import com.ghy.common.utils.MoneyUtil;
import com.ghy.payment.domain.PaymentConfirm;
import com.ghy.payment.mapper.PaymentConfirmMapper;
import com.ghy.payment.mapper.PaymentMapper;
import com.ghy.payment.service.CallBackService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
@Service("paymentConfirmCallbackService")
public class PaymentConfirmCallbackService implements CallBackService {
@Resource
private PaymentMapper paymentMapper;
@Resource
private PaymentConfirmMapper paymentConfirmMapper;
@Override
public void onCallback(Event event) {
// 支付确认没有callback
}
@Override
public void onResponse(JSONObject response) {
if (AdapayStatusEnum.succeeded.code.equals(response.getString("status")) ||
AdapayStatusEnum.pending.code.equals(response.getString("status"))) {
// 支付确认 操作成功
PaymentConfirm paymentConfirm = response.toJavaObject(PaymentConfirm.class);
// 保存支付确认记录
paymentConfirmMapper.insert(paymentConfirm);
// 更新支付单信息
updatePayment(paymentConfirm);
}
}
private synchronized void updatePayment(PaymentConfirm paymentConfirm) {
String paymentId = paymentConfirm.getPaymentId();
PaymentDTO payment = paymentMapper.selectById(paymentId);
// 支付金额
BigDecimal payAmt = new BigDecimal(payment.getPayAmt());
// 已确认金额
BigDecimal confirmedAmt = new BigDecimal(paymentConfirm.getConfirmedAmt());
// 已退款金额
BigDecimal refundedAmt = new BigDecimal(paymentConfirm.getRefundedAmt());
// 已撤销金额
BigDecimal reservedAmt = new BigDecimal(paymentConfirm.getReservedAmt());
// 可支配金额 = 支付金额 - 已确认金额 - 已退款金额 - 已撤销金额
BigDecimal availableAmt = payAmt.subtract(confirmedAmt).subtract(refundedAmt).subtract(reservedAmt);
// 更新支付单信息
PaymentDTO payment2up = new PaymentDTO();
payment2up.setId(paymentId);
payment2up.setConfirmedAmt(paymentConfirm.getConfirmedAmt());
payment2up.setRefundedAmt(paymentConfirm.getRefundedAmt());
payment2up.setReservedAmt(paymentConfirm.getReservedAmt());
payment2up.setAvailableAmt(MoneyUtil.toS(availableAmt));
paymentMapper.updatePayment(payment2up);
}
}

View File

@ -1,44 +0,0 @@
package com.ghy.web.controller;
import com.ghy.common.dto.DataEntityDTO;
import com.ghy.common.enums.WxMsgEnum;
import com.ghy.common.utils.WechatMsgUtils;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @Author 但星霖
* @Date 2023-09-28 104256
* 说明
*/
@RestController
@RequestMapping("/mesg/test")
public class MesgTestController {
@GetMapping("/{openId}")
public void edit(@PathVariable("openId") String openId){
try {
// 消息组装
Map<String, Object> paramsNew = new HashMap<>();
// 订单编号
paramsNew.put("character_string1", new DataEntityDTO("12312"));
// 名称
paramsNew.put("thing2", new DataEntityDTO("订单被拒通知"));
// 预约时间
paramsNew.put("data8", new DataEntityDTO(com.ghy.common.utils.DateUtils.parseDateToStr("yyyy年MM月dd日 HH:mm", new Date())));
// 师傅姓名
paramsNew.put("name3", new DataEntityDTO("测试"));
// 服务区域
paramsNew.put("thing4", new DataEntityDTO("成都市"));
// 消息推送
WechatMsgUtils.sendWeChatMsg(WechatMsgUtils.getToken(), openId, WxMsgEnum.TEXT, paramsNew);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -1,576 +0,0 @@
package com.ghy.web.controller;
import com.ghy.common.core.controller.BaseController;
import com.ghy.shop.domain.Shop;
import com.ghy.shop.domain.ShopDistanceQuery;
import com.ghy.shop.service.ShopService;
import com.ghy.common.core.domain.AjaxResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import org.springframework.web.client.RestTemplate;
import com.ghy.common.utils.LocationUtils;
import java.util.stream.Collectors;
import java.util.Comparator;
/**
* 店铺管理接口
*/
@RestController
@RequestMapping("/shop")
public class ShopController extends BaseController {
@Autowired
private ShopService shopService;
@Autowired
private RestTemplate restTemplate;
@PostMapping("/add")
public AjaxResult addShop(@RequestBody Shop shop) {
// 如果没有经纬度尝试通过地址解析获取
if ((shop.getLatitude() == null || shop.getLongitude() == null) &&
shop.getAddress() != null && !shop.getAddress().trim().isEmpty()) {
try {
Map<String, Double> coordinates = getCoordinatesByAddress(shop);
if (coordinates != null) {
shop.setLatitude(coordinates.get("latitude"));
shop.setLongitude(coordinates.get("longitude"));
logger.info("为店铺[{}]自动获取到坐标: 经度={}, 纬度={}",
shop.getShopName(), shop.getLongitude(), shop.getLatitude());
}
} catch (Exception e) {
logger.warn("获取地址经纬度失败: {}", e.getMessage());
}
}
int result = shopService.addShop(shop);
if (result > 0) {
Map<String, Object> response = new HashMap<>();
response.put("shopId", shop.getShopId());
response.put("shopName", shop.getShopName());
response.put("latitude", shop.getLatitude());
response.put("longitude", shop.getLongitude());
response.put("address", shop.getAddress());
return AjaxResult.success("店铺创建成功", response);
} else {
return AjaxResult.error("店铺创建失败");
}
}
@GetMapping("/list")
public AjaxResult listShops() {
List<Shop> list = shopService.listShops();
return AjaxResult.success(list);
}
@GetMapping("/{id}")
public AjaxResult getShop(@PathVariable Long id) {
Shop shop = shopService.getShop(id);
return shop != null ? AjaxResult.success(shop) : AjaxResult.error("未找到店铺");
}
@PostMapping("/update")
public AjaxResult updateShop(@RequestBody Shop shop) {
// 如果没有经纬度但有地址尝试通过地址解析获取经纬度
if ((shop.getLatitude() == null || shop.getLongitude() == null) &&
shop.getAddress() != null && !shop.getAddress().trim().isEmpty()) {
try {
Map<String, Double> coordinates = getCoordinatesByAddress(shop);
if (coordinates != null) {
shop.setLatitude(coordinates.get("latitude"));
shop.setLongitude(coordinates.get("longitude"));
}
} catch (Exception e) {
logger.warn("更新店铺时获取地址经纬度失败: {}", e.getMessage());
}
}
return toAjax(shopService.updateShop(shop));
}
@PostMapping("/delete/{id}")
public AjaxResult deleteShop(@PathVariable Long id) {
return toAjax(shopService.deleteShop(id));
}
@GetMapping("/{id}/location")
public AjaxResult getShopLocation(@PathVariable Long id) {
Shop shop = shopService.getShop(id);
if (shop == null) {
return AjaxResult.error("未找到店铺");
}
Map<String, Object> location = new HashMap<>();
location.put("address", shop.getAddress());
location.put("latitude", shop.getLatitude());
location.put("longitude", shop.getLongitude());
location.put("provinceName", shop.getProvinceName());
location.put("cityName", shop.getCityName());
location.put("countryName", shop.getCountryName());
location.put("streetName", shop.getStreetName());
return AjaxResult.success(location);
}
// @GetMapping("/getCurrentLocation")
// public AjaxResult getCurrentLocation() {
// try {
// // 直接调用百度地图API获取当前位置信息
// String url = "/tool/baidu/getLocation";
// return restTemplate.getForObject(url, AjaxResult.class);
// } catch (Exception e) {
// return AjaxResult.error("获取当前位置失败:" + e.getMessage());
// }
// }
@GetMapping("/worker/{workerId}")
public AjaxResult getShopsByWorkerId(@PathVariable Long workerId) {
List<Shop> shops = shopService.getShopsByWorkerId(workerId);
return AjaxResult.success(shops);
}
// /**
// * 通过地址获取经纬度坐标
// */
// @PostMapping("/getCoordinates")
// public AjaxResult getCoordinatesByAddress(@RequestBody Shop shop) {
// try {
// Map<String, Double> coordinates = getCoordinatesByAddress(shop);
// if (coordinates != null) {
// return AjaxResult.success("获取坐标成功", coordinates);
// } else {
// return AjaxResult.error("无法获取该地址的坐标信息");
// }
// } catch (Exception e) {
// logger.error("获取坐标失败: {}", e.getMessage(), e);
// return AjaxResult.error("获取坐标失败: " + e.getMessage());
// }
// }
/**
* 通过经纬度逆解析获取地址信息并保存到店铺
*/
@PostMapping("/saveShopByLocation")
public AjaxResult saveShopByLocation(@RequestBody Map<String, Object> params) {
try {
String location = params.get("location").toString(); // 格式: "经度,纬度"
// 调用百度地图逆解析API
String url = "/tool/baidu/getLocation";
Map<String, String> requestBody = new HashMap<>();
requestBody.put("location", location);
// 这里应该调用百度接口获取地址信息
// AjaxResult locationResult = restTemplate.postForObject(url, requestBody, AjaxResult.class);
// 解析经纬度
String[] coordinates = location.split(",");
if (coordinates.length != 2) {
return AjaxResult.error("location格式错误应为经度,纬度");
}
Double longitude = Double.parseDouble(coordinates[0]);
Double latitude = Double.parseDouble(coordinates[1]);
// 创建店铺对象
Shop shop = new Shop();
shop.setLongitude(longitude);
shop.setLatitude(latitude);
// 设置其他信息
if (params.containsKey("shopName")) {
shop.setShopName(params.get("shopName").toString());
}
if (params.containsKey("workerId")) {
shop.setWorkerId(Long.valueOf(params.get("workerId").toString()));
}
if (params.containsKey("phone")) {
shop.setPhone(params.get("phone").toString());
}
// 保存店铺
int result = shopService.addShop(shop);
if (result > 0) {
Map<String, Object> response = new HashMap<>();
response.put("shopId", shop.getShopId());
response.put("longitude", longitude);
response.put("latitude", latitude);
response.put("location", location);
return AjaxResult.success("店铺创建成功", response);
} else {
return AjaxResult.error("店铺创建失败");
}
} catch (Exception e) {
logger.error("通过位置创建店铺失败: {}", e.getMessage(), e);
return AjaxResult.error("创建失败: " + e.getMessage());
}
}
/**
* 内部方法通过地址解析获取经纬度
*/
private Map<String, Double> getCoordinatesByAddress(Shop shop) {
try {
// 构建完整地址
StringBuilder fullAddress = new StringBuilder();
if (shop.getProvinceName() != null) fullAddress.append(shop.getProvinceName());
if (shop.getCityName() != null) fullAddress.append(shop.getCityName());
if (shop.getCountryName() != null) fullAddress.append(shop.getCountryName());
if (shop.getStreetName() != null) fullAddress.append(shop.getStreetName());
if (shop.getAddress() != null) fullAddress.append(shop.getAddress());
String address = fullAddress.toString();
if (address.isEmpty()) {
return null;
}
logger.info("开始解析地址获取坐标: {}", address);
// TODO: 这里应该调用真实的地图API
// 示例百度地图正向地理编码API
// String url = "https://api.map.baidu.com/geocoding/v3/?address=" +
// java.net.URLEncoder.encode(address, "UTF-8") +
// "&output=json&ak=YOUR_BAIDU_API_KEY";
//
// String result = restTemplate.getForObject(url, String.class);
// JSONObject jsonResult = JSONObject.parseObject(result);
//
// if ("0".equals(jsonResult.getString("status"))) {
// JSONObject location = jsonResult.getJSONObject("result").getJSONObject("location");
// Double lng = location.getDouble("lng");
// Double lat = location.getDouble("lat");
//
// Map<String, Double> coordinates = new HashMap<>();
// coordinates.put("longitude", lng);
// coordinates.put("latitude", lat);
// return coordinates;
// }
// 临时返回示例坐标实际使用时请替换为真实的API调用
Map<String, Double> coordinates = new HashMap<>();
coordinates.put("latitude", 39.915 + Math.random() * 0.1); // 示例纬度
coordinates.put("longitude", 116.404 + Math.random() * 0.1); // 示例经度
logger.info("地址解析成功: {} -> 经度={}, 纬度={}",
address, coordinates.get("longitude"), coordinates.get("latitude"));
return coordinates;
} catch (Exception e) {
logger.error("地址解析失败: {}", e.getMessage(), e);
return null;
}
}
/**
* 手动设置店铺经纬度
*/
@PostMapping("/setCoordinates")
public AjaxResult setCoordinates(@RequestBody Map<String, Object> params) {
try {
Long shopId = Long.valueOf(params.get("shopId").toString());
Double latitude = Double.valueOf(params.get("latitude").toString());
Double longitude = Double.valueOf(params.get("longitude").toString());
Shop shop = new Shop();
shop.setShopId(shopId);
shop.setLatitude(latitude);
shop.setLongitude(longitude);
int result = shopService.updateShop(shop);
if (result > 0) {
Map<String, Object> response = new HashMap<>();
response.put("shopId", shopId);
response.put("latitude", latitude);
response.put("longitude", longitude);
return AjaxResult.success("坐标设置成功", response);
} else {
return AjaxResult.error("坐标设置失败");
}
} catch (Exception e) {
logger.error("设置坐标失败: {}", e.getMessage(), e);
return AjaxResult.error("设置坐标失败: " + e.getMessage());
}
}
/**
* 批量查询店铺包含经纬度信息
*/
@PostMapping("/listWithLocation")
public AjaxResult listShopsWithLocation(@RequestBody(required = false) Map<String, Object> params) {
try {
List<Shop> shops = shopService.listShops();
// 可以根据参数进行筛选
if (params != null) {
// 按城市筛选
if (params.containsKey("cityId")) {
Long cityId = Long.valueOf(params.get("cityId").toString());
shops = shops.stream()
.filter(shop -> shop.getCityId() != null && shop.getCityId().equals(cityId))
.collect(java.util.stream.Collectors.toList());
}
// 按师傅筛选
if (params.containsKey("workerId")) {
Long workerId = Long.valueOf(params.get("workerId").toString());
shops = shops.stream()
.filter(shop -> shop.getWorkerId() != null && shop.getWorkerId().equals(workerId))
.collect(java.util.stream.Collectors.toList());
}
// 只返回有坐标的店铺
if (params.containsKey("hasLocation") && Boolean.valueOf(params.get("hasLocation").toString())) {
shops = shops.stream()
.filter(shop -> shop.getLatitude() != null && shop.getLongitude() != null)
.collect(java.util.stream.Collectors.toList());
}
}
return AjaxResult.success(shops);
} catch (Exception e) {
logger.error("查询店铺列表失败: {}", e.getMessage(), e);
return AjaxResult.error("查询失败: " + e.getMessage());
}
}
/**
* 查询附近的店铺
*/
@PostMapping("/nearby")
public AjaxResult getNearbyShops(@RequestBody Map<String, Object> params) {
try {
Double latitude = Double.valueOf(params.get("latitude").toString());
Double longitude = Double.valueOf(params.get("longitude").toString());
Double radiusKm = params.containsKey("radiusKm") ?
Double.valueOf(params.get("radiusKm").toString()) : 5.0; // 默认5公里
// 验证坐标有效性
if (!LocationUtils.isValidCoordinate(latitude, longitude)) {
return AjaxResult.error("无效的坐标参数");
}
// 获取所有店铺
List<Shop> allShops = shopService.listShops();
// 筛选出有坐标的店铺并计算距离
List<Map<String, Object>> nearbyShops = allShops.stream()
.filter(shop -> LocationUtils.isValidCoordinate(shop.getLatitude(), shop.getLongitude()))
.map(shop -> {
double distance = LocationUtils.getDistanceInKilometers(
latitude, longitude, shop.getLatitude(), shop.getLongitude());
Map<String, Object> shopWithDistance = new HashMap<>();
shopWithDistance.put("shop", shop);
shopWithDistance.put("distance", distance);
shopWithDistance.put("distanceText", LocationUtils.formatDistance(distance * 1000));
// 计算方向
double bearing = LocationUtils.getBearing(latitude, longitude,
shop.getLatitude(), shop.getLongitude());
shopWithDistance.put("direction", LocationUtils.getDirectionDescription(bearing));
shopWithDistance.put("bearing", bearing);
return shopWithDistance;
})
.filter(shopMap -> (Double) shopMap.get("distance") <= radiusKm)
.sorted(Comparator.comparingDouble(shopMap -> (Double) shopMap.get("distance")))
.collect(Collectors.toList());
Map<String, Object> result = new HashMap<>();
result.put("centerLatitude", latitude);
result.put("centerLongitude", longitude);
result.put("radiusKm", radiusKm);
result.put("totalCount", nearbyShops.size());
result.put("shops", nearbyShops);
return AjaxResult.success("查询成功", result);
} catch (Exception e) {
logger.error("查询附近店铺失败: {}", e.getMessage(), e);
return AjaxResult.error("查询失败: " + e.getMessage());
}
}
/**
* 计算两个店铺之间的距离
*/
@PostMapping("/distance")
public AjaxResult getShopsDistance(@RequestBody Map<String, Object> params) {
try {
Long shopId1 = Long.valueOf(params.get("shopId1").toString());
Long shopId2 = Long.valueOf(params.get("shopId2").toString());
Shop shop1 = shopService.getShop(shopId1);
Shop shop2 = shopService.getShop(shopId2);
if (shop1 == null || shop2 == null) {
return AjaxResult.error("店铺不存在");
}
if (!LocationUtils.isValidCoordinate(shop1.getLatitude(), shop1.getLongitude()) ||
!LocationUtils.isValidCoordinate(shop2.getLatitude(), shop2.getLongitude())) {
return AjaxResult.error("店铺坐标信息不完整");
}
double distanceKm = LocationUtils.getDistanceInKilometers(
shop1.getLatitude(), shop1.getLongitude(),
shop2.getLatitude(), shop2.getLongitude());
double bearing = LocationUtils.getBearing(
shop1.getLatitude(), shop1.getLongitude(),
shop2.getLatitude(), shop2.getLongitude());
Map<String, Object> result = new HashMap<>();
result.put("shop1", shop1);
result.put("shop2", shop2);
result.put("distanceKm", distanceKm);
result.put("distanceText", LocationUtils.formatDistance(distanceKm * 1000));
result.put("direction", LocationUtils.getDirectionDescription(bearing));
result.put("bearing", bearing);
return AjaxResult.success("计算成功", result);
} catch (Exception e) {
logger.error("计算店铺距离失败: {}", e.getMessage(), e);
return AjaxResult.error("计算失败: " + e.getMessage());
}
}
/**
* 通过店铺ID查询详细信息并计算距离
* 最终效果
* 1. 传入的详细地址 转换为经纬度
* 2. 店铺有经纬度 直接使用
* 3. 店铺没有经纬度 通过详细地址生成经纬度
* 4. 最终通过经纬度计算距离 放在店铺的距离字段上
*
* @param query 距离查询请求实体
* @return 包含距离信息的完整店铺详情
*/
@PostMapping("/getShopDetailWithDistance")
public AjaxResult getShopDetailWithDistance(@RequestBody ShopDistanceQuery query) {
try {
// 验证参数
if (query.getShopId() == null) {
return AjaxResult.error("店铺ID不能为空");
}
// 验证是否有足够的信息来计算距离或获取位置
if (!query.hasEnoughInfo()) {
return AjaxResult.error("请提供经纬度或地址信息");
}
// 如果提供了经纬度验证其有效性
if (query.hasCoordinateInfo() && !LocationUtils.isValidCoordinate(query.getLatitude(), query.getLongitude())) {
return AjaxResult.error("无效的坐标参数");
}
// 验证地址参数如果提供了地址信息则验证其完整性
if (query.hasAddressInfo()) {
String fullAddress = query.getFullAddress();
if (fullAddress.trim().length() < 5) {
return AjaxResult.error("地址信息不完整,请提供更详细的地址");
}
logger.info("使用传入的地址信息: {}", fullAddress);
}
// 调用服务层方法获取店铺详情和距离
Shop shop = shopService.getShopWithDistance(query);
if (shop == null) {
return AjaxResult.error("未找到店铺");
}
// 检查距离是否有效
if (shop.getDistance() == null || shop.getDistance().equals("无法计算距离")) {
if (query.hasCoordinateInfo()) {
return AjaxResult.error("无法计算店铺距离,请检查店铺地址信息或提供更详细的地址参数");
} else {
// 如果没有经纬度只获取位置信息
logger.info("仅获取店铺位置信息,无法计算距离");
}
}
// 构建返回结果
Map<String, Object> result = new HashMap<>();
result.put("shopId", shop.getShopId());
result.put("shopName", shop.getShopName());
result.put("imageUrl", shop.getImageUrl());
result.put("workerId", shop.getWorkerId());
result.put("provinceId", shop.getProvinceId());
result.put("provinceName", shop.getProvinceName());
result.put("cityId", shop.getCityId());
result.put("cityName", shop.getCityName());
result.put("countryId", shop.getCountryId());
result.put("countryName", shop.getCountryName());
result.put("streetId", shop.getStreetId());
result.put("streetName", shop.getStreetName());
result.put("address", shop.getAddress());
result.put("phone", shop.getPhone());
result.put("latitude", shop.getLatitude());
result.put("longitude", shop.getLongitude());
result.put("distance", shop.getDistance());
return AjaxResult.success("查询成功", result);
} catch (Exception e) {
logger.error("查询店铺详情失败: {}", e.getMessage(), e);
return AjaxResult.error("查询失败: " + e.getMessage());
}
}
// /**
// * 获取店铺覆盖范围内的其他店铺
// */
// @PostMapping("/coverage")
// public AjaxResult getShopsCoverage(@RequestBody Map<String, Object> params) {
// try {
// Long shopId = Long.valueOf(params.get("shopId").toString());
// Double radiusKm = params.containsKey("radiusKm") ?
// Double.valueOf(params.get("radiusKm").toString()) : 10.0; // 默认10公里
//
// Shop centerShop = shopService.getShop(shopId);
// if (centerShop == null) {
// return AjaxResult.error("店铺不存在");
// }
//
// if (!LocationUtils.isValidCoordinate(centerShop.getLatitude(), centerShop.getLongitude())) {
// return AjaxResult.error("中心店铺坐标信息不完整");
// }
//
// // 获取附近的店铺
// Map<String, Object> nearbyParams = new HashMap<>();
// nearbyParams.put("latitude", centerShop.getLatitude());
// nearbyParams.put("longitude", centerShop.getLongitude());
// radiusKm);
//
// AjaxResult nearbyResult = getNearbyShops(nearbyParams);
// if (nearbyResult.isSuccess()) {
// Map<String, Object> data = (Map<String, Object>) nearbyResult.get("data");
// List<Map<String, Object>> shops = (List<Map<String, Object>>) data.get("shops");
//
// // 排除自己
// shops = shops.stream()
// .filter(shopMap -> {
// Shop shop = (Shop) shopMap.get("shop");
// return !shop.getShopId().equals(shopId);
// })
// .collect(Collectors.toList());
//
// data.put("centerShop", centerShop);
// data.put("shops", shops);
// data.put("totalCount", shops.size());
//
// return AjaxResult.success("查询成功", data);
// } else {
// return nearbyResult;
// }
//
// } catch (Exception e) {
// logger.error("查询店铺覆盖范围失败: {}", e.getMessage(), e);
// return AjaxResult.error("查询失败: " + e.getMessage());
// }
// }
}

View File

@ -1,60 +0,0 @@
package com.ghy.web.controller.config;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.system.service.ISysGlobalConfigService;
import com.ghy.web.pojo.vo.SysGlobalConfigRequestVO;
import com.ghy.web.pojo.vo.SysGlobalConfigResponseVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
/**
* @Author: 但星霖
* @Date: 2023-11-09 14:42
* @Version: 1.0
* @Description: web-系统配置控制层
*/
@Controller
@RequestMapping("/config/globalConfig")
@Tag(name = "web-系统配置控制层")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SysGlobalConfigController {
private String prefix = "config/globalConfig";
@RequiresPermissions("sys:order:audio:config")
@GetMapping()
public String place() {
return prefix + "/edit";
}
private final ISysGlobalConfigService service;
@ResponseBody
@Operation(summary = "系统配置查询接口(根据类型查询)", method = "GET")
@Parameters({
@Parameter(name = "typeId", description = "配置类型Code", required = true, in = ParameterIn.PATH)
})
@GetMapping(path = "/search/type/{typeId}", produces = MediaType.APPLICATION_JSON_VALUE)
public AjaxResult searchByType(@PathVariable("typeId") Integer typeId) {
return AjaxResult.success(SysGlobalConfigResponseVO.toVo(service.loadByConfigType(typeId)));
}
@ResponseBody
@RequiresPermissions("sys:order:audio:config:update")
@Operation(summary = "系统配置修改", method = "PUT")
@PutMapping(path = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
public AjaxResult update(@RequestBody SysGlobalConfigRequestVO sysConfigRequestVO) {
return AjaxResult.success(service.update(SysGlobalConfigRequestVO.toModel(sysConfigRequestVO)));
}
}

View File

@ -1,6 +1,5 @@
package com.ghy.web.controller.customer;
import cn.hutool.core.util.ObjectUtil;
import com.ghy.common.core.controller.BaseController;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.utils.ExceptionUtil;
@ -13,8 +12,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
@Controller
@RequestMapping("/customer/address")
@ -103,20 +100,6 @@ public class CustomerAddressController extends BaseController {
@ResponseBody
AjaxResult insertCustomerAddress(@RequestBody CustomerAddress customerAddress){
try {
// 判断下当前是否是默认地址
if(ObjectUtil.equals(customerAddress.getIsDefault(), 1)){
CustomerAddress param = new CustomerAddress();
param.setNeedNameFlag(false);
param.setCustomerId(customerAddress.getCustomerId());
param.setIsDefault(1);
List<CustomerAddress> sourceDefaultAddress = customerAddressService.getCustomerAddressList(param);
for (CustomerAddress defaultAddress : sourceDefaultAddress) {
CustomerAddress defaultParam = new CustomerAddress();
defaultParam.setCustomerAddressId(defaultAddress.getCustomerAddressId());
defaultParam.setIsDefault(0);
customerAddressService.updateCustomerAddress(defaultParam);
}
}
customerAddressService.insertCustomerAddress(customerAddress);
return AjaxResult.success("操作成功");
}catch (Exception e){
@ -131,24 +114,7 @@ public class CustomerAddressController extends BaseController {
@PostMapping("/update")
@ResponseBody
AjaxResult updateCustomerAddress(@RequestBody CustomerAddress customerAddress){
logger.info("地址库的订单修改方法{}",customerAddress);
try {
// 判断下当前是否是默认地址
if(ObjectUtil.equals(customerAddress.getIsDefault(), 1)){
CustomerAddress param = new CustomerAddress();
param.setNeedNameFlag(false);
param.setCustomerId(customerAddress.getCustomerId());
param.setIsDefault(1);
List<CustomerAddress> sourceDefaultAddress = customerAddressService.getCustomerAddressList(param);
for (CustomerAddress defaultAddress : sourceDefaultAddress) {
if(!Objects.equals(defaultAddress.getCustomerAddressId(), customerAddress.getCustomerAddressId())){
CustomerAddress defaultParam = new CustomerAddress();
defaultParam.setCustomerAddressId(defaultAddress.getCustomerAddressId());
defaultParam.setIsDefault(0);
customerAddressService.updateCustomerAddress(defaultParam);
}
}
}
customerAddressService.updateCustomerAddress(customerAddress);
return AjaxResult.success("操作成功");
}catch (Exception e){

View File

@ -18,7 +18,6 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@ -46,8 +45,6 @@ public class CustomerBankController {
@ResponseBody
private AjaxResult bindBankCard(@RequestBody @Valid BindBankCardRequest request) throws BaseAdaPayException {
Set<Merchant> merchants = AdapayConfig.getMerchants();
String phone = request.getPhone();
phone = StringUtils.trimAllWhitespace(phone);
for (Merchant merchant : merchants) {
String memberId = AdapayUtils.getCustomerMemberId(request.getCustomerId(), merchant.getDeptId());
@ -63,7 +60,7 @@ public class CustomerBankController {
log.info("用户[memberId={}]已存在 跳过实名直接绑卡", memberId);
} else {
// 先在Adapay创建实名用户
Map<String, Object> result1 = adapayService.createMember(merchant.getDeptId(), memberId, phone,
Map<String, Object> result1 = adapayService.createMember(merchant.getDeptId(), memberId, request.getPhone(),
request.getName(), request.getCertId());
if (!AdapayStatusEnum.succeeded.code.equals(result1.get("status"))) {
log.error("实名认证失败[{}]", JSON.toJSONString(result1));
@ -73,7 +70,7 @@ public class CustomerBankController {
// 开始创建结算账户
JSONObject result2 = adapayService.createSettleAccount(merchant.getDeptId(), memberId, request.getBankNum(), request.getName(),
"2", request.getCertId(), phone, null, null, null);
"2", request.getCertId(), request.getPhone(), null, null, null);
if (!AdapayStatusEnum.succeeded.code.equals(result2.get("status"))) {
if ("account_exists".equals(result2.get("error_code"))) {
log.info("用户[memberId={}]结算账户已存在 跳过", memberId);
@ -88,7 +85,7 @@ public class CustomerBankController {
customerBank.setName(request.getName());
customerBank.setCertId(request.getCertId());
customerBank.setBankNum(request.getBankNum());
customerBank.setPhone(phone);
customerBank.setPhone(request.getPhone());
customerBank.setDeptId(merchant.getDeptId());
customerBank.setAdapayMemberId(memberId);
customerBank.setSettleAccount(1);

View File

@ -4,16 +4,13 @@ import com.ghy.common.adapay.model.AnalyseItemEnum;
import com.ghy.common.core.controller.BaseController;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.core.page.TableDataInfo;
import com.ghy.common.enums.FinancialDetailType;
import com.ghy.common.enums.PlaceStatus;
import com.ghy.common.enums.UserStatus;
import com.ghy.common.utils.ExceptionUtil;
import com.ghy.customer.domain.Customer;
import com.ghy.customer.service.CustomerService;
import com.ghy.goods.domain.InsuranceManager;
import com.ghy.order.domain.OrderMaster;
import com.ghy.order.service.OrderMasterService;
import com.ghy.payment.domain.FinancialDetail;
import com.ghy.payment.domain.FinancialMaster;
import com.ghy.payment.service.FinancialMasterService;
import com.ghy.web.pojo.vo.AnalyseItem;
@ -22,7 +19,6 @@ import org.apache.commons.collections.CollectionUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
@ -76,19 +72,17 @@ public class CustomerController extends BaseController {
startPage();
List<Customer> list = customerService.getCustomerList(customer);
for (Customer curCustomer: list) {
Long teamNum = 0L;
List<Long> customerIds = new ArrayList<Long>(){{
add(curCustomer.getCustomerId());
}};
List<Long> nextLevelCustomerIds = new ArrayList<>();
if (customer.getIsDistributor()) {
// 分销商需要查询所有下一级分销用户作为统计条件
Customer customerQry = new Customer();
customerQry.setCustomerPlace(curCustomer.getCustomerId());
customerQry.setStatus(Integer.valueOf(UserStatus.OK.getCode()));
List<Customer> nextLevelCustomers = customerService.getCustomerList(customerQry);
teamNum = teamNum + nextLevelCustomers.stream().filter(x->PlaceStatus.CAN_PLACE.getCode().equals(x.getPlaceStatus())).count();
nextLevelCustomerIds = nextLevelCustomers.stream().map(Customer::getCustomerId).collect(Collectors.toList());
List<Long> nextLevelCustomerIds = nextLevelCustomers.stream().map(Customer::getCustomerId).collect(Collectors.toList());
customerIds.addAll(nextLevelCustomerIds);
}
// 本月第一天
@ -109,7 +103,6 @@ public class CustomerController extends BaseController {
.setValue(customerService.countCustomer(customerParams));
analyseItems.add(aItem1);
// 本月绑定客户数
customerParams.setPlaceStatus(null);
customerParams.setUpdateTimeStart(firstDayCurMonth.atStartOfDay());
AnalyseItem aItem2 = new AnalyseItem()
.setType(AnalyseItemEnum.CUSTOMER_NUM_ADDED_CUR_MONTH.getType())
@ -118,27 +111,22 @@ public class CustomerController extends BaseController {
.setValue(customerService.countCustomer(customerParams));
analyseItems.add(aItem2);
// 团队
customerParams.setUpdateTimeStart(null);
customerParams.setPlaceStatus(PlaceStatus.CAN_PLACE.getCode());
AnalyseItem aItem11 = new AnalyseItem()
.setType(AnalyseItemEnum.TEAM_MEMBER_NUM.getType())
.setTitle(AnalyseItemEnum.TEAM_MEMBER_NUM.getTitle())
.setUnit(AnalyseItemEnum.TEAM_MEMBER_NUM.getUnit())
.setValue(customerService.countCustomer(customerParams));
.setValue(aItem1.getValue());
analyseItems.add(aItem11);
// 本月绑定客户数
customerParams.setUpdateTimeStart(firstDayCurMonth.atStartOfDay());
customerParams.setPlaceStatus(PlaceStatus.CAN_PLACE.getCode());
AnalyseItem aItem12 = new AnalyseItem()
.setType(AnalyseItemEnum.TEAM_MEMBER_ADDED_CUR_MONTH.getType())
.setTitle(AnalyseItemEnum.TEAM_MEMBER_ADDED_CUR_MONTH.getTitle())
.setUnit(AnalyseItemEnum.TEAM_MEMBER_ADDED_CUR_MONTH.getUnit())
.setValue(customerService.countCustomer(customerParams));
.setValue(aItem2.getValue());
analyseItems.add(aItem12);
// 本月订单数及本月订单额
OrderMaster orderParams1 = new OrderMaster();
customerIds.addAll(nextLevelCustomerIds);
orderParams1.setCustomerIds(customerIds);
orderParams1.setCreateTimeStart(firstDayCurMonth.atStartOfDay());
List<OrderMaster> ordersCurMonth1 = orderMasterService.selectOrderMasterList(orderParams1);
@ -220,7 +208,7 @@ public class CustomerController extends BaseController {
OrderMaster orderParams4 = new OrderMaster();
orderParams4.setCustomerIds(customerIds);
orderParams4.setCreateTimeStart(firstDayCurWeek.atStartOfDay());
List<OrderMaster> ordersCurWeek = orderMasterService.selectOrderMasterList(orderParams4);
List<OrderMaster> ordersCurWeek = orderMasterService.selectOrderMasterList(orderParams3);
List<Long> orderIdsCurWeek = ordersCurWeek.stream().map(OrderMaster::getId).collect(Collectors.toList());
BigDecimal totalMoneyCurWeek = new BigDecimal(0);
if (CollectionUtils.isNotEmpty(orderIdsCurWeek)) {
@ -254,25 +242,6 @@ public class CustomerController extends BaseController {
return getDataTable(response);
}
@GetMapping("/changePlace/{customerId}")
public String changePlace(@PathVariable("customerId") Long customerId, ModelMap mmap)
{
mmap.put("customerId", customerId);
mmap.put("customerPlaces", customerService.getPlaceCustomerList());
return prefix + "/changePlace";
}
@PostMapping("/changePlace")
@ResponseBody
@Transactional(rollbackFor = Exception.class)
public AjaxResult changePlace(Customer customer) {
Customer place = customerService.selectByCustomerId(customer.getCustomerPlace());
customer.setParentCustomerPlace(place.getCustomerPlace());
customerService.updateCustomer(customer);
return AjaxResult.success();
}
@RequiresPermissions("customer:customer:resetPwd")
@GetMapping("/resetPwd/{customerId}")
public String resetPwd(@PathVariable("customerId") Long customerId, ModelMap mmap)

View File

@ -1,8 +1,6 @@
package com.ghy.web.controller.customer;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import com.ghy.common.exception.base.BaseException;
import com.ghy.customer.domain.Customer;
@ -64,22 +62,6 @@ public class CustomerSelectionController extends BaseController
return getDataTable(list);
}
/**
* 查询消费者选品列表
*/
@PostMapping("/listNoPage")
@ResponseBody
public AjaxResult listNoPage(@RequestBody CustomerSelection customerSelection)
{
// 判断是否有上级有上级则取上级的 -- 没有则就是自身
Customer customer = customerService.selectByCustomerId(customerSelection.getCustomerId());
if(customer.getPlaceStatus() != 2 && customer.getCustomerPlace() != null){
customerSelection.setCustomerId(customer.getCustomerPlace());
}
List<CustomerSelection> list = customerSelectionService.selectCustomerSelectionList(customerSelection);
return AjaxResult.success(list.stream().map(CustomerSelection::getDeptCategoryId).collect(Collectors.toList()));
}
/**
* App查询消费者选品列表
*/
@ -147,28 +129,18 @@ public class CustomerSelectionController extends BaseController
}else {
workId = workList.get(0).getWorkerId();
}
// 删除历史的
CustomerSelection hisParam = new CustomerSelection();
hisParam.setCustomerId(customerSelection.getCustomerId());
hisParam.setSelectionType(customerSelection.getSelectionType());
List<CustomerSelection> hisList = customerSelectionService.selectCustomerSelectionList(hisParam);
if(!CollectionUtils.isEmpty(hisList)){
List<String> hisIds = hisList.stream()
.filter(customerSelection1 -> Objects.equals(customerSelection1.getType(), customerSelection.getType())).map(CustomerSelection::getId).collect(Collectors.toList());
StringBuilder ids = new StringBuilder();
hisIds.forEach(model->{
ids.append(model.trim()).append(",");
});
if(!StringUtil.isEmpty(ids)&&ids.length()>0){
String idString = ids.substring(0, ids.length()-1);
customerSelectionService.deleteCustomerSelectionByIds(idString);
}
}
// 判断是否有历史数据 - 有则删除
customerSelection.getDeptCategoryIds().forEach(selection->{
customerSelection.setWorkId(workId);
customerSelection.setDeptCategoryId(selection);
CustomerSelection param = new CustomerSelection();
param.setDeptCategoryId(selection);
param.setSelectionType(customerSelection.getSelectionType());
param.setCustomerId(customerSelection.getCustomerId());
List<CustomerSelection> customerSelections = customerSelectionService.selectCustomerSelectionList(param);
if(CollectionUtils.isEmpty(customerSelections)){
customerSelectionService.insertCustomerSelection(customerSelection);
}
});
return AjaxResult.success("新增成功");
}catch (Exception e){

View File

@ -1,6 +1,5 @@
package com.ghy.web.controller.goods;
import cn.hutool.core.collection.CollectionUtil;
import com.ghy.common.annotation.Log;
import com.ghy.common.constant.UserConstants;
import com.ghy.common.core.controller.BaseController;
@ -8,24 +7,16 @@ import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.core.domain.Ztree;
import com.ghy.common.enums.BusinessType;
import com.ghy.common.utils.ShiroUtils;
import com.ghy.common.utils.StringUtils;
import com.ghy.goods.domain.CategoryInsuranceRelation;
import com.ghy.goods.domain.GoodsCategory;
import com.ghy.goods.domain.InsuranceManager;
import com.ghy.goods.service.GoodsCategoryService;
import com.ghy.goods.service.ICategoryInsuranceRelationService;
import com.ghy.goods.service.IInsuranceManagerService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author HH 2022/3/19
@ -39,12 +30,6 @@ public class GoodsCategoryController extends BaseController {
@Resource
private GoodsCategoryService goodsCategoryService;
@Resource
private IInsuranceManagerService insuranceManagerService;
@Resource
private ICategoryInsuranceRelationService categoryInsuranceRelationService;
@RequiresPermissions("goods:category:view")
@GetMapping()
public String goodsCategory() {
@ -58,7 +43,6 @@ public class GoodsCategoryController extends BaseController {
@GetMapping("/add/{parentCategoryId}")
public String add(@PathVariable("parentCategoryId") Long parentCategoryId, ModelMap mmap) {
mmap.put("goodsCategory", goodsCategoryService.selectById(parentCategoryId));
mmap.put("insurances", insuranceManagerService.selectInsuranceManagerList(new InsuranceManager()));
return PREFIX + "/add";
}
@ -66,8 +50,7 @@ public class GoodsCategoryController extends BaseController {
* 新增商品类别页面
*/
@GetMapping("/add")
public String add(ModelMap mmap) {
mmap.put("insurances", insuranceManagerService.selectInsuranceManagerList(new InsuranceManager()));
public String add() {
return PREFIX + "/add";
}
@ -77,21 +60,7 @@ public class GoodsCategoryController extends BaseController {
@RequiresPermissions("goods:category:edit")
@GetMapping("/edit/{goodsId}")
public String edit(@PathVariable("goodsId") Long goodsId, ModelMap mmap) {
GoodsCategory goodsCategory = goodsCategoryService.selectById(goodsId);
mmap.put("goodsCategory", goodsCategory);
List<InsuranceManager> list = insuranceManagerService.selectInsuranceManagerList(new InsuranceManager());
CategoryInsuranceRelation param = new CategoryInsuranceRelation();
param.setGoodsCategoryId(goodsCategory.getGoodsCategoryId());
List<CategoryInsuranceRelation> relations = categoryInsuranceRelationService.selectCategoryInsuranceRelationList(param);
if(CollectionUtil.isNotEmpty(relations)){
Map<Long, List<CategoryInsuranceRelation>> map = relations.stream().collect(Collectors.groupingBy(CategoryInsuranceRelation::getInsuranceId));
list.forEach(model->{
if(map.containsKey(model.getId())){
model.setFlag(true);
}
});
}
mmap.put("insurances", list);
mmap.put("goodsCategory", goodsCategoryService.selectById(goodsId));
return PREFIX + "/edit";
}
@ -134,10 +103,12 @@ public class GoodsCategoryController extends BaseController {
@Log(title = "商品类别管理", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
@Transactional
public AjaxResult editSave(@Validated GoodsCategory category) {
// 更新保险设置
categoryInsuranceRelationService.updateCategoryInsuranceRelation(category.getInsuranceIds(), category.getGoodsCategoryId());
// if (goodsCategoryService.checkGoodsCategoryNameUnique(category)) {
// return error("新增商品类别'" + category.getGoodsCategoryName() + "'失败,商品类别名称已存在");
// } else if (goodsCategoryService.checkGoodsCategoryCodeUnique(category)) {
// return error("新增商品类别'" + category.getGoodsCategoryCode() + "'失败,商品类别编码已存在");
// }
category.setUpdateBy(getLoginName());
return toAjax(goodsCategoryService.updateGoodsCategory(category));
}
@ -181,25 +152,6 @@ public class GoodsCategoryController extends BaseController {
return goodsCategoryService.selectCategoryTree(new GoodsCategory());
}
/**
* 选择服务类目树
*/
@GetMapping("/selectServiceCategoryTree")
public String selectServiceCategoryTree(ModelMap mmap) {
return PREFIX + "/serviceTree";
}
/**
* 获取服务类目树数据
*/
@GetMapping("/serviceTreeData")
@ResponseBody
public List<Ztree> serviceTreeData() {
GoodsCategory category = new GoodsCategory();
category.setType(1); // 1表示服务类
return goodsCategoryService.selectCategoryTree(category);
}
/**
* 商品类别表
*/

View File

@ -10,13 +10,8 @@ import com.ghy.common.utils.ShiroUtils;
import com.ghy.common.utils.StringUtils;
import com.ghy.common.utils.bean.BeanUtils;
import com.ghy.common.utils.poi.ExcelUtil;
import com.ghy.common.utils.LocationUtils;
import com.ghy.common.utils.http.HttpUtils;
import com.alibaba.fastjson.JSONObject;
import com.ghy.goods.domain.*;
import com.ghy.goods.service.*;
import com.ghy.shop.domain.Shop;
import com.ghy.shop.service.ShopService;
import com.ghy.system.domain.SysArea;
import com.ghy.system.service.ISysAreaService;
import io.swagger.annotations.ApiModel;
@ -31,7 +26,6 @@ import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import com.ghy.common.utils.BaiduMapUtils;
@Controller
@RequestMapping("/goods/goods")
@ -53,14 +47,6 @@ public class GoodsController extends BaseController {
private GoodsStandardService goodsStandardService;
@Resource
private ISysAreaService sysAreaService;
@Resource
private IInsuranceManagerService insuranceManagerService;
@Resource
private IDeptCategoryInsuranceRelationService deptCategoryInsuranceRelationService;
@Resource
private ShopService shopService;
@Resource
private BaiduMapUtils baiduMapUtils;
@RequiresPermissions("goods:goods:view")
@GetMapping()
@ -174,15 +160,6 @@ public class GoodsController extends BaseController {
@PostMapping("/app/list")
@ResponseBody
public TableDataInfo appList(@RequestBody Goods goods) {
Integer type=goods.getType();
if (type==null){
goods.setType(1);
}
// 获取用户当前位置
Double userLatitude = goods.getLatitude();
Double userLongitude = goods.getLongitude();
// 判断类目id是否为第三级不是的话需要找到所有符合条件的第三级类目id作为新的条件
if (goods.getDeptGoodsCategoryId() != null) {
logger.info("入参:" + goods.getDeptGoodsCategoryId());
@ -221,40 +198,9 @@ public class GoodsController extends BaseController {
}
}
// 通过商品规格名称模糊查询
if (StringUtils.isNotEmpty(goods.getGoodsStandard())) {
logger.info("通过商品规格查询:{}", goods.getGoodsStandard());
List<GoodsStandard> matchedStandards = goodsStandardService.selectByStandardNameLike(goods.getGoodsStandard());
if (CollectionUtils.isNotEmpty(matchedStandards)) {
// 获取所有符合规格条件的商品ID
List<Long> goodsIds = matchedStandards.stream()
.map(GoodsStandard::getGoodsId)
.distinct()
.collect(Collectors.toList());
logger.info("通过规格查询到的商品ID列表{}", goodsIds);
// 设置商品ID筛选条件与现有的类目筛选条件组合使用
if (goods.getGoodsIds() == null) {
goods.setGoodsIds(goodsIds);
} else {
// 如果已有商品ID筛选条件取交集
goods.getGoodsIds().retainAll(goodsIds);
}
} else {
logger.info("未找到符合规格条件的商品,设置空结果");
// 如果没找到符合条件的规格设置一个不存在的商品ID
goods.setGoodsIds(Arrays.asList(-1L));
}
}
startPage();
List<Goods> list = goodsService.selectGoodsList(goods);
logger.info("传入的类目id汇总{},传入的goods信息为{},获取到的所有商品{}",goods.getDeptGoodsCategoryIds(),goods,list);
// 用于缓存店铺信息避免重复查询
Map<Long, Shop> shopCache = new HashMap<>();
list.forEach(one -> {
// 补全商品服务区域
List<GoodsArea> goodsAreas = goodsAreaService.selectByGoodsId(one.getGoodsId());
@ -272,89 +218,10 @@ public class GoodsController extends BaseController {
one.setParGoodsCategoryId(parGoodsCategory.getGoodsCategoryId());
one.setParGoodsCategoryName(parGoodsCategory.getGoodsCategoryName());
}
logger.debug("验证坐标是否合理: {}", LocationUtils.isValidCoordinate(userLatitude, userLongitude));
// 计算距离逻辑
if (LocationUtils.isValidCoordinate(userLatitude, userLongitude) && one.getShopId() != null) {
try {
// 从缓存获取店铺信息避免重复查询
Shop shop = shopCache.computeIfAbsent(one.getShopId(),
shopId -> shopService.getShop(shopId));
if (shop != null && LocationUtils.isValidCoordinate(shop.getLatitude(), shop.getLongitude())) {
// 计算距离
double distanceInMeters = LocationUtils.getDistanceInMeters(
userLatitude, userLongitude,
shop.getLatitude(), shop.getLongitude()
);
// 格式化距离并设置到商品对象
one.setDistance(LocationUtils.formatDistance(distanceInMeters));
logger.debug("商品[{}]距离用户: {}", one.getGoodsName(), one.getDistance());
} else {
// 店铺坐标不完整
one.setDistance(null);
}
} catch (Exception e) {
logger.warn("计算商品[{}]距离失败: {}", one.getGoodsName(), e.getMessage());
// 计算异常时设为null
one.setDistance(null);
}
} else {
// 用户未提供位置或商品无店铺信息
one.setDistance(null);
}
});
// 如果用户提供了位置信息按距离排序距离为null的排在最后
if (LocationUtils.isValidCoordinate(userLatitude, userLongitude)) {
list.sort((goods1, goods2) -> {
String distance1 = goods1.getDistance();
String distance2 = goods2.getDistance();
// 距离为null的排在最后
if (distance1 == null && distance2 == null) return 0;
if (distance1 == null) return 1;
if (distance2 == null) return -1;
// 解析距离数值进行比较
try {
double dist1 = parseDistanceToMeters(distance1);
double dist2 = parseDistanceToMeters(distance2);
return Double.compare(dist1, dist2);
} catch (Exception e) {
// 解析失败时保持原顺序
return 0;
}
});
logger.info("已按距离排序,用户位置: 纬度={}, 经度={}", userLatitude, userLongitude);
}
return getDataTable(list);
}
/**
* 解析距离字符串为米数用于排序
*/
private double parseDistanceToMeters(String distanceText) {
if (distanceText == null || distanceText.trim().isEmpty()) {
return Double.MAX_VALUE;
}
try {
if (distanceText.endsWith("")) {
return Double.parseDouble(distanceText.replace("", ""));
} else if (distanceText.endsWith("公里")) {
return Double.parseDouble(distanceText.replace("公里", "")) * 1000;
}
} catch (NumberFormatException e) {
logger.warn("无法解析距离字符串: {}", distanceText);
}
return Double.MAX_VALUE;
}
@PostMapping("/hot/list")
@ResponseBody
public TableDataInfo hotList(@RequestBody Goods goods) {
@ -404,225 +271,11 @@ public class GoodsController extends BaseController {
}
}
/**
* 获取商品详情
*
* @param requestBody 请求参数
* @return 商品详情信息
*/
@PostMapping("/getDetail")
@ResponseBody
public AjaxResult getDetail(@RequestBody JSONObject requestBody) {
public AjaxResult getDetail(@RequestBody Goods goods) {
try {
// 从请求体中提取参数
Long goodsId = requestBody.getLong("goodsId");
Double userLatitude = requestBody.getDouble("latitude");
Double userLongitude = requestBody.getDouble("longitude");
String provinceName = requestBody.getString("provinceName");
String cityName = requestBody.getString("cityName");
String countryName = requestBody.getString("countryName");
String streetName = requestBody.getString("streetName");
String address = requestBody.getString("address");
if (goodsId == null) {
return AjaxResult.error("商品ID不能为空");
}
Goods result = goodsService.selectById(goodsId);
if (result == null) {
return AjaxResult.error("商品不存在");
}
// 如果用户没有提供经纬度但有详细地址则通过地址获取经纬度
if ((userLatitude == null || userLongitude == null) &&
(provinceName != null || cityName != null ||
countryName != null || streetName != null ||
address != null)) {
try {
// 使用BaiduMapUtils工具类获取经纬度
Map<String, Double> coordinates = baiduMapUtils.getCoordinatesByAddress(
provinceName, cityName, countryName, streetName, address
);
if (coordinates != null) {
userLongitude = coordinates.get("longitude");
userLatitude = coordinates.get("latitude");
logger.info("通过地址获取到用户经纬度: 经度={}, 纬度={}", userLongitude, userLatitude);
} else {
logger.warn("通过地址获取用户经纬度失败");
}
} catch (Exception e) {
logger.error("调用百度地图API异常: {}", e.getMessage(), e);
}
}
// 获取商品店铺信息
Shop goodsShop = null;
if (result.getShopId() != null) {
try {
goodsShop = shopService.getShop(result.getShopId());
} catch (Exception e) {
logger.warn("获取商品店铺信息失败: {}", e.getMessage());
}
}
// 获取服务店铺信息
Shop serviceShop = null;
if (result.getDeptGoodsCategoryId() != null) {
try {
// 1. 通过商品的类目ID获取类目信息
DeptGoodsCategory deptGoodsCategory = deptGoodsCategoryService.selectOneByGoodsCategoryId(result.getDeptGoodsCategoryId());
Long serviceCategoryId = null;
if (deptGoodsCategory != null) {
// 先检查当前类目是否有服务类目ID
if (deptGoodsCategory.getServiceCategoryId() != null) {
serviceCategoryId = deptGoodsCategory.getServiceCategoryId();
logger.debug("当前类目[{}]的服务类目ID: {}", deptGoodsCategory.getGoodsCategoryName(), serviceCategoryId);
} else {
// 如果当前类目没有服务类目ID查找上一级类目
logger.debug("当前类目[{}]未配置服务类目ID查找上一级类目", deptGoodsCategory.getGoodsCategoryName());
if (deptGoodsCategory.getParentCategoryId() != null) {
DeptGoodsCategory parentCategory = deptGoodsCategoryService.selectOneByGoodsCategoryId(deptGoodsCategory.getParentCategoryId());
if (parentCategory != null && parentCategory.getServiceCategoryId() != null) {
serviceCategoryId = parentCategory.getServiceCategoryId();
logger.debug("上一级类目[{}]的服务类目ID: {}", parentCategory.getGoodsCategoryName(), serviceCategoryId);
} else {
logger.debug("上一级类目[{}]也未配置服务类目ID", parentCategory != null ? parentCategory.getGoodsCategoryName() : "null");
}
} else {
logger.debug("当前类目没有父级类目");
}
}
}
if (serviceCategoryId != null) {
// 2. 通过服务类目ID查询所有使用该服务类目的商品
Goods queryGoods = new Goods();
queryGoods.setDeptGoodsCategoryId(serviceCategoryId);
queryGoods.setStatus(0); // 只查询上架的商品
List<Goods> goodsList = goodsService.selectGoodsList(queryGoods);
if (goodsList.size()==0){
DeptGoodsCategory deptGoodsCategory1=deptGoodsCategoryService.selectOneByGoodsCategoryId(serviceCategoryId);
serviceCategoryId=deptGoodsCategory1.getDeptGoodsCategoryId();
// 直接使用新方法获取商品列表
goodsList = goodsStandardService.selectGoodsByDeptGoodsCategoryId(serviceCategoryId);
// 过滤只保留上架的商品
goodsList = goodsList.stream()
.filter(goods -> goods.getStatus() != null && goods.getStatus() == 0)
.collect(Collectors.toList());
}
logger.info("获取到的服务类目id{} 取到的商品列表:{}", serviceCategoryId,goodsList);
// 3. 提取所有店铺ID去重
Set<Long> shopIds = goodsList.stream()
.filter(g -> g.getShopId() != null)
.map(Goods::getShopId)
.collect(Collectors.toSet());
logger.info("取到的店铺列表:{}", shopIds);
if (!shopIds.isEmpty()) {
// 找到最近的店铺
Shop nearestShop = null;
double minDistance = Double.MAX_VALUE;
for (Long shopId : shopIds) {
Shop shop = shopService.getShop(shopId);
if (shop != null && LocationUtils.isValidCoordinate(shop.getLatitude(), shop.getLongitude())) {
if (LocationUtils.isValidCoordinate(userLatitude, userLongitude)) {
try {
double distanceInMeters = LocationUtils.getDistanceInMeters(
userLatitude, userLongitude,
shop.getLatitude(), shop.getLongitude()
);
if (distanceInMeters < minDistance) {
minDistance = distanceInMeters;
nearestShop = shop;
}
} catch (Exception e) {
logger.warn("计算店铺[{}]距离失败: {}", shop.getShopName(), e.getMessage());
}
} else {
// 如果用户没有提供位置选择第一个有效店铺
if (nearestShop == null) {
nearestShop = shop;
}
}
}
}
serviceShop = nearestShop;
} else {
logger.debug("服务类目[{}]下没有找到商品", serviceCategoryId);
}
} else {
logger.debug("未找到有效的服务类目ID");
}
} catch (Exception e) {
logger.warn("获取服务店铺信息失败: {}", e.getMessage());
}
}
// 设置商品店铺和服务店铺信息
if(result.getType()==1){
serviceShop=goodsShop;
result.setServiceShop(serviceShop);
}else {
result.setShop(goodsShop);
}
// 计算距离逻辑
if (LocationUtils.isValidCoordinate(userLatitude, userLongitude)) {
// 计算服务店铺距离
if (serviceShop != null) {
try {
if (LocationUtils.isValidCoordinate(serviceShop.getLatitude(), serviceShop.getLongitude())) {
// 计算距离
double distanceInMeters = LocationUtils.getDistanceInMeters(
userLatitude, userLongitude,
serviceShop.getLatitude(), serviceShop.getLongitude()
);
// 格式化距离并设置到服务店铺对象
serviceShop.setDistance(LocationUtils.formatDistance(distanceInMeters));
logger.debug("商品[{}]服务店铺距离用户: {}", result.getGoodsName(), serviceShop.getDistance());
} else {
// 店铺坐标不完整
serviceShop.setDistance(null);
}
} catch (Exception e) {
logger.warn("计算商品[{}]服务店铺距离失败: {}", result.getGoodsName(), e.getMessage());
// 计算异常时设为null
serviceShop.setDistance(null);
}
}
// 计算商品店铺距离
if (goodsShop != null) {
try {
if (LocationUtils.isValidCoordinate(goodsShop.getLatitude(), goodsShop.getLongitude())) {
// 计算距离
double distanceInMeters = LocationUtils.getDistanceInMeters(
userLatitude, userLongitude,
goodsShop.getLatitude(), goodsShop.getLongitude()
);
// 格式化距离并设置到商品店铺对象
goodsShop.setDistance(LocationUtils.formatDistance(distanceInMeters));
logger.debug("商品[{}]商品店铺距离用户: {}", result.getGoodsName(), goodsShop.getDistance());
} else {
// 店铺坐标不完整
goodsShop.setDistance(null);
}
} catch (Exception e) {
logger.warn("计算商品[{}]商品店铺距离失败: {}", result.getGoodsName(), e.getMessage());
// 计算异常时设为null
goodsShop.setDistance(null);
}
}
}
result.setServiceShop(serviceShop);
Goods result = goodsService.selectById(goods.getGoodsId());
// 补全商品类目及父级类目信息
GoodsCategory goodsCategory = goodsCategoryService.selectById(result.getDeptGoodsCategoryId());
@ -669,24 +322,7 @@ public class GoodsController extends BaseController {
goodsStandard.setFinalPrice(finalPrice);
});
result.setGoodsStandardList(goodsStandards);
// 所有保险信息
List<InsuranceManager> insuranceManagers = insuranceManagerService.selectInsuranceManagerList(new InsuranceManager());
// 查询本类目保险信息
DeptCategoryInsuranceRelation param = new DeptCategoryInsuranceRelation();
param.setType("01");
param.setDeptCategoryId(goodsStandards.get(0).getDeptGoodsCategoryId());
List<DeptCategoryInsuranceRelation> deptCategoryInsuranceRelations = deptCategoryInsuranceRelationService.selectDeptCategoryInsuranceRelationList(param);
if(CollectionUtils.isNotEmpty(deptCategoryInsuranceRelations)){
Map<Long, List<DeptCategoryInsuranceRelation>> insuranceMap = deptCategoryInsuranceRelations.stream().collect(Collectors.groupingBy(DeptCategoryInsuranceRelation::getInsuranceId));
// 目标保险
List<InsuranceManager> goal = new ArrayList<>();
insuranceManagers.forEach(model->{
if(insuranceMap.containsKey(model.getId())){
goal.add(model);
}
});
result.setInsuranceManagers(goal);
}
return AjaxResult.success(result);
} catch (Exception e) {
e.printStackTrace();
@ -695,186 +331,6 @@ public class GoodsController extends BaseController {
}
}
/**
* 根据商品ID和用户位置获取服务店铺列表
* @return 服务店铺列表按距离排序
*/
@PostMapping("/getShopsByGoodsId")
@ResponseBody
public AjaxResult getShopsByGoodsId(@RequestBody JSONObject requestBody) {
try {
Long goodsId = requestBody.getLong("goodsId");
Double latitude = requestBody.getDouble("latitude");
Double longitude = requestBody.getDouble("longitude");
String provinceName = requestBody.getString("provinceName");
String cityName = requestBody.getString("cityName");
String countryName = requestBody.getString("countryName");
String streetName = requestBody.getString("streetName");
String address = requestBody.getString("address");
if (goodsId == null) {
return AjaxResult.error("商品ID不能为空");
}
// 如果用户没有提供经纬度但有详细地址则通过地址获取经纬度
if ((latitude == null || longitude == null) &&
(provinceName != null || cityName != null || countryName != null ||
streetName != null || address != null)) {
try {
// 使用BaiduMapUtils工具类获取经纬度
Map<String, Double> coordinates = baiduMapUtils.getCoordinatesByAddress(
provinceName, cityName, countryName, streetName, address
);
if (coordinates != null) {
longitude = coordinates.get("longitude");
latitude = coordinates.get("latitude");
logger.info("通过地址获取到用户经纬度: 经度={}, 纬度={}", longitude, latitude);
} else {
logger.warn("通过地址获取用户经纬度失败");
}
} catch (Exception e) {
logger.error("调用百度地图API异常: {}", e.getMessage(), e);
}
}
// 获取商品信息
Goods goods = goodsService.selectById(goodsId);
if (goods == null) {
return AjaxResult.error("商品不存在");
}
List<Shop> serviceShops = new ArrayList<>();
// 通过商品的服务类目获取服务店铺
if (goods.getDeptGoodsCategoryId() != null) {
try {
// 1. 通过商品的类目ID获取类目信息
DeptGoodsCategory deptGoodsCategory = deptGoodsCategoryService.selectOneByGoodsCategoryId(goods.getDeptGoodsCategoryId());
Long serviceCategoryId = null;
if (deptGoodsCategory != null) {
// 先检查当前类目是否有服务类目ID
if (deptGoodsCategory.getServiceCategoryId() != null) {
serviceCategoryId = deptGoodsCategory.getServiceCategoryId();
logger.debug("当前类目[{}]的服务类目ID: {}", deptGoodsCategory.getGoodsCategoryName(), serviceCategoryId);
} else {
// 如果当前类目没有服务类目ID查找上一级类目
logger.debug("当前类目[{}]未配置服务类目ID查找上一级类目", deptGoodsCategory.getGoodsCategoryName());
if (deptGoodsCategory.getParentCategoryId() != null) {
DeptGoodsCategory parentCategory = deptGoodsCategoryService.selectOneByGoodsCategoryId(deptGoodsCategory.getParentCategoryId());
if (parentCategory != null && parentCategory.getServiceCategoryId() != null) {
serviceCategoryId = parentCategory.getServiceCategoryId();
logger.debug("上一级类目[{}]的服务类目ID: {}", parentCategory.getGoodsCategoryName(), serviceCategoryId);
} else {
logger.debug("上一级类目[{}]也未配置服务类目ID", parentCategory != null ? parentCategory.getGoodsCategoryName() : "null");
}
} else {
logger.debug("当前类目没有父级类目");
}
}
}
List<Goods> goodsList = new ArrayList<>();
if (serviceCategoryId != null) {
// 2. 通过服务类目ID查询所有使用该服务类目的商品
Goods queryGoods = new Goods();
queryGoods.setDeptGoodsCategoryId(serviceCategoryId);
queryGoods.setStatus(0); // 只查询上架的商品
goodsList = goodsService.selectGoodsList(queryGoods);
if (goodsList.size() == 0) {
DeptGoodsCategory deptGoodsCategory1 = deptGoodsCategoryService.selectOneByGoodsCategoryId(serviceCategoryId);
serviceCategoryId = deptGoodsCategory1.getDeptGoodsCategoryId();
// 直接使用新方法获取商品列表
goodsList = goodsStandardService.selectGoodsByDeptGoodsCategoryId(serviceCategoryId);
// 过滤只保留上架的商品
goodsList = goodsList.stream()
.filter(g -> g.getStatus() != null && g.getStatus() == 0)
.collect(Collectors.toList());
}
logger.info("获取到的服务类目id{} 取到的商品列表:{}", serviceCategoryId, goodsList);
}
if (!goodsList.isEmpty()) {
logger.debug("通过商品ID[{}]找到{}个相关服务商品", goodsId, goodsList.size());
// 提取所有店铺ID去重
Set<Long> shopIds = goodsList.stream()
.filter(g -> g.getShopId() != null)
.map(Goods::getShopId)
.collect(Collectors.toSet());
if (!shopIds.isEmpty()) {
// 获取所有店铺信息并计算距离
for (Long shopId : shopIds) {
Shop shop = shopService.getShop(shopId);
if (shop != null) {
// 计算距离
if (LocationUtils.isValidCoordinate(latitude, longitude) &&
LocationUtils.isValidCoordinate(shop.getLatitude(), shop.getLongitude())) {
try {
double distanceInMeters = LocationUtils.getDistanceInMeters(
latitude, longitude,
shop.getLatitude(), shop.getLongitude()
);
shop.setDistance(LocationUtils.formatDistance(distanceInMeters));
} catch (Exception e) {
logger.warn("计算店铺[{}]距离失败: {}", shop.getShopName(), e.getMessage());
shop.setDistance(null);
}
} else {
shop.setDistance(null);
}
serviceShops.add(shop);
}
}
// 按距离排序有距离的排在前面然后按距离升序
serviceShops.sort((s1, s2) -> {
if (s1.getDistance() == null && s2.getDistance() == null) {
return 0;
}
if (s1.getDistance() == null) {
return 1;
}
if (s2.getDistance() == null) {
return -1;
}
// 提取距离数值进行比较
try {
double d1 = Double.parseDouble(s1.getDistance().replaceAll("[^0-9.]", ""));
double d2 = Double.parseDouble(s2.getDistance().replaceAll("[^0-9.]", ""));
return Double.compare(d1, d2);
} catch (Exception e) {
return 0;
}
});
}
} else {
logger.debug("未找到商品ID[{}]的相关服务商品", goodsId);
}
} catch (Exception e) {
logger.warn("获取服务店铺信息失败: {}", e.getMessage());
}
}
JSONObject result = new JSONObject();
result.put("goodsId", goodsId);
result.put("goodsName", goods.getGoodsName());
result.put("userLatitude", latitude);
result.put("userLongitude", longitude);
result.put("serviceShops", serviceShops);
result.put("totalCount", serviceShops.size());
return AjaxResult.success(result);
} catch (Exception e) {
logger.error("获取服务店铺列表失败: {}", e.getMessage(), e);
return AjaxResult.error("获取服务店铺列表失败: " + ExceptionUtil.getExceptionMessage(e));
}
}
@Log(title = "商品管理", businessType = BusinessType.EXPORT)
@RequiresPermissions("goods:goods:export")
@PostMapping("/export")
@ -945,13 +401,6 @@ public class GoodsController extends BaseController {
@ResponseBody
public AjaxResult editSave(@Validated Goods goods) {
goods.setUpdateBy(getLoginName());
// 处理Long类型字段的空值情况
// 当前端传入0或空字符串时将shopId设置为null以便清空
if (goods.getShopId() != null && goods.getShopId().equals(0L)) {
goods.setShopId(null);
}
return toAjax(goodsService.updateGoods(goods));
}
@ -959,12 +408,6 @@ public class GoodsController extends BaseController {
@ResponseBody
public AjaxResult appEditSave(@RequestBody @Validated Goods goods) {
// 处理Long类型字段的空值情况
// 当前端传入0或空字符串时将shopId设置为null以便清空
if (goods.getShopId() != null && goods.getShopId().equals(0L)) {
goods.setShopId(null);
}
goodsService.edit(goods);
return AjaxResult.success();
}
@ -1024,6 +467,4 @@ public class GoodsController extends BaseController {
return AjaxResult.error(ExceptionUtil.getExceptionMessage(e));
}
}
}

View File

@ -1,7 +1,5 @@
package com.ghy.web.controller.goods;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.ghy.common.annotation.Log;
import com.ghy.common.core.controller.BaseController;
import com.ghy.common.core.domain.AjaxResult;
@ -12,8 +10,10 @@ import com.ghy.common.enums.ImgType;
import com.ghy.common.utils.ExceptionUtil;
import com.ghy.common.utils.ShiroUtils;
import com.ghy.common.utils.StringUtils;
import com.ghy.goods.domain.*;
import com.ghy.goods.service.*;
import com.ghy.goods.domain.DeptGoodsCategory;
import com.ghy.goods.domain.GoodsImgs;
import com.ghy.goods.service.DeptGoodsCategoryService;
import com.ghy.goods.service.GoodsImgsService;
import com.ghy.web.pojo.vo.AppCategoryRequest;
import com.ghy.web.pojo.vo.HotCategoryResponse;
import org.apache.shiro.authz.annotation.RequiresPermissions;
@ -30,7 +30,6 @@ import java.util.List;
import java.util.stream.Collectors;
@Controller
@CrossOrigin(origins = "*")
@RequestMapping("goods/deptcategory")
public class GoodsDeptCategoryController extends BaseController {
@ -39,18 +38,6 @@ public class GoodsDeptCategoryController extends BaseController {
@Resource
DeptGoodsCategoryService deptGoodsCategoryService;
@Resource
private GoodsCategoryService goodsCategoryService;
@Resource
ICategoryInsuranceRelationService categoryInsuranceRelationService;
@Resource
IDeptCategoryInsuranceRelationService deptCategoryInsuranceRelationService;
@Resource
IInsuranceManagerService insuranceManagerService;
@Autowired
private GoodsImgsService goodsImgsService;
@ -158,57 +145,6 @@ public class GoodsDeptCategoryController extends BaseController {
@GetMapping("/edit/{id}")
public String edit(@PathVariable("id") Long id, ModelMap mmap) {
DeptGoodsCategory deptGoodsCategory = deptGoodsCategoryService.get(id);
CategoryInsuranceRelation relation = new CategoryInsuranceRelation();
relation.setGoodsCategoryId(deptGoodsCategory.getGoodsCategoryId());
List<CategoryInsuranceRelation> relations = categoryInsuranceRelationService.selectCategoryInsuranceRelationList(relation);
// 当第四级没有的时候往上找三级
if(CollectionUtil.isEmpty(relations)){
GoodsCategory model = goodsCategoryService.selectById(deptGoodsCategory.getGoodsCategoryId());
CategoryInsuranceRelation parentRelation = new CategoryInsuranceRelation();
parentRelation.setGoodsCategoryId(model.getParentCategoryId());
relations = categoryInsuranceRelationService.selectCategoryInsuranceRelationList(parentRelation);
// 当第三级没有的时候往上找二级
if(CollectionUtil.isEmpty(relations)){
GoodsCategory parentModel = goodsCategoryService.selectById(model.getParentCategoryId());
CategoryInsuranceRelation topRelation = new CategoryInsuranceRelation();
topRelation.setGoodsCategoryId(parentModel.getParentCategoryId());
relations = categoryInsuranceRelationService.selectCategoryInsuranceRelationList(topRelation);
}
}
// pc保险设置
List<InsuranceManager> pcInsuranceList = new ArrayList<>();
// 商城保险设置
List<InsuranceManager> shopInsuranceList = new ArrayList<>();
if(CollectionUtil.isNotEmpty(relations)){
List<InsuranceManager> list = insuranceManagerService.selectByIds(relations.stream().map(CategoryInsuranceRelation::getInsuranceId).collect(Collectors.toList()));
list.forEach(model->{
model.setInsuranceName(model.getCompanyName() + "||" + model.getInsuranceName() + "||" + model.getInsuranceAmount() + "");
// 查看pc勾选状态
DeptCategoryInsuranceRelation pcParam = new DeptCategoryInsuranceRelation();
pcParam.setType("02");
pcParam.setInsuranceId(model.getId());
pcParam.setDeptCategoryId(deptGoodsCategory.getDeptGoodsCategoryId());
InsuranceManager pcModel = new InsuranceManager();
BeanUtil.copyProperties(model, pcModel);
if(CollectionUtil.isNotEmpty(deptCategoryInsuranceRelationService.selectDeptCategoryInsuranceRelationList(pcParam))){
pcModel.setFlag(true);
}
pcInsuranceList.add(pcModel);
DeptCategoryInsuranceRelation shopParam = new DeptCategoryInsuranceRelation();
shopParam.setType("01");
shopParam.setInsuranceId(model.getId());
shopParam.setDeptCategoryId(deptGoodsCategory.getDeptGoodsCategoryId());
InsuranceManager shopModel = new InsuranceManager();
BeanUtil.copyProperties(model, shopModel);
if(CollectionUtil.isNotEmpty(deptCategoryInsuranceRelationService.selectDeptCategoryInsuranceRelationList(shopParam))){
shopModel.setFlag(true);
}
shopInsuranceList.add(shopModel);
});
}
mmap.put("pcInsurances", pcInsuranceList);
mmap.put("shopInsurances", shopInsuranceList);
mmap.put("deptGoodsCategory", deptGoodsCategory);
return PREFIX + "/edit";
}
@ -217,8 +153,6 @@ public class GoodsDeptCategoryController extends BaseController {
@PostMapping("/edit")
@ResponseBody
public AjaxResult edit(DeptGoodsCategory category) {
// 更新保险设置
deptCategoryInsuranceRelationService.updateDeptCategoryInsuranceRelation(category.getPcInsuranceIds(), category.getShopInsuranceIds(), category.getDeptGoodsCategoryId());
category.setUpdateBy(getLoginName());
deptGoodsCategoryService.edit(category);
return AjaxResult.success();

View File

@ -3,7 +3,6 @@ package com.ghy.web.controller.goods;
import com.ghy.common.core.controller.BaseController;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.core.page.TableDataInfo;
import com.ghy.goods.domain.Goods;
import com.ghy.goods.domain.GoodsStandard;
import com.ghy.goods.service.GoodsStandardService;
import com.ghy.order.domain.OrderTemplate;
@ -65,14 +64,4 @@ public class GoodsStandardController extends BaseController {
return toAjax(goodsStandardService.save(goodsStandardList));
}
/**
* 根据部门商品分类ID获取商品列表
*/
@ResponseBody
@GetMapping("/goods/by-dept-category/{deptGoodsCategoryId}")
public AjaxResult getGoodsByDeptCategoryId(@PathVariable("deptGoodsCategoryId") Long deptGoodsCategoryId) {
List<Goods> goodsList = goodsStandardService.selectGoodsByDeptGoodsCategoryId(deptGoodsCategoryId);
return AjaxResult.success(goodsList);
}
}

View File

@ -1,135 +0,0 @@
package com.ghy.web.controller.goods;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import com.ghy.common.annotation.Log;
import com.ghy.common.enums.BusinessType;
import com.ghy.goods.domain.InsuranceManager;
import com.ghy.goods.service.IInsuranceManagerService;
import com.ghy.common.core.controller.BaseController;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.utils.poi.ExcelUtil;
import com.ghy.common.core.page.TableDataInfo;
/**
* 保险管理Controller
*
* @author clunt
* @date 2024-09-25
*/
@Controller
@RequestMapping("/goods/manager")
public class InsuranceManagerController extends BaseController
{
private String prefix = "goods/manager";
@Autowired
private IInsuranceManagerService insuranceManagerService;
@RequiresPermissions("goods:manager:view")
@GetMapping()
public String manager()
{
return prefix + "/manager";
}
/**
* 查询保险管理列表
*/
@RequiresPermissions("goods:manager:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(InsuranceManager insuranceManager)
{
startPage();
List<InsuranceManager> list = insuranceManagerService.selectInsuranceManagerList(insuranceManager);
return getDataTable(list);
}
/**
* App查询保险管理列表
*/
@PostMapping("/app/list")
@ResponseBody
public TableDataInfo appList(@RequestBody InsuranceManager insuranceManager)
{
startPage();
List<InsuranceManager> list = insuranceManagerService.selectInsuranceManagerList(insuranceManager);
return getDataTable(list);
}
/**
* 导出保险管理列表
*/
@RequiresPermissions("goods:manager:export")
@Log(title = "保险管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(InsuranceManager insuranceManager)
{
List<InsuranceManager> list = insuranceManagerService.selectInsuranceManagerList(insuranceManager);
ExcelUtil<InsuranceManager> util = new ExcelUtil<InsuranceManager>(InsuranceManager.class);
return util.exportExcel(list, "保险管理数据");
}
/**
* 新增保险管理
*/
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
* 新增保存保险管理
*/
@RequiresPermissions("goods:manager:add")
@Log(title = "保险管理", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(InsuranceManager insuranceManager)
{
return toAjax(insuranceManagerService.insertInsuranceManager(insuranceManager));
}
/**
* 修改保险管理
*/
@RequiresPermissions("goods:manager:edit")
@GetMapping("/edit/{id}")
public String edit(@PathVariable("id") Long id, ModelMap mmap)
{
InsuranceManager insuranceManager = insuranceManagerService.selectInsuranceManagerById(id);
mmap.put("insuranceManager", insuranceManager);
return prefix + "/edit";
}
/**
* 修改保存保险管理
*/
@RequiresPermissions("goods:manager:edit")
@Log(title = "保险管理", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(InsuranceManager insuranceManager)
{
return toAjax(insuranceManagerService.updateInsuranceManager(insuranceManager));
}
/**
* 删除保险管理
*/
@RequiresPermissions("goods:manager:remove")
@Log(title = "保险管理", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(insuranceManagerService.deleteInsuranceManagerByIds(ids));
}
}

View File

@ -1,88 +0,0 @@
package com.ghy.web.controller.order;
import java.math.BigDecimal;
/**
* 售后纠纷处理请求
*
* @author system
* @date 2024-12-19
*/
public class AfterServiceDisputeRequest {
/**
* 售后记录ID
*/
private String recordId;
/**
* 主单ID
*/
private Long orderMasterId;
/**
* 子单ID
*/
private Long orderDetailId;
/**
* 退款金额
*/
private BigDecimal refundAmount;
/**
* 售后纠纷平台处理原因
*/
private String platformHandleReason;
public String getRecordId() {
return recordId;
}
public void setRecordId(String recordId) {
this.recordId = recordId;
}
public Long getOrderMasterId() {
return orderMasterId;
}
public void setOrderMasterId(Long orderMasterId) {
this.orderMasterId = orderMasterId;
}
public Long getOrderDetailId() {
return orderDetailId;
}
public void setOrderDetailId(Long orderDetailId) {
this.orderDetailId = orderDetailId;
}
public BigDecimal getRefundAmount() {
return refundAmount;
}
public void setRefundAmount(BigDecimal refundAmount) {
this.refundAmount = refundAmount;
}
public String getPlatformHandleReason() {
return platformHandleReason;
}
public void setPlatformHandleReason(String platformHandleReason) {
this.platformHandleReason = platformHandleReason;
}
@Override
public String toString() {
return "AfterServiceDisputeRequest{" +
"recordId='" + recordId + '\'' +
", orderMasterId=" + orderMasterId +
", orderDetailId=" + orderDetailId +
", refundAmount=" + refundAmount +
", platformHandleReason='" + platformHandleReason + '\'' +
'}';
}
}

View File

@ -134,22 +134,11 @@ public class AfterServiceRecordController extends BaseController {
public AjaxResult editSave(@RequestBody AfterServiceRecord afterServiceRecord) {
logger.info("修改售后记录:{}", afterServiceRecord);
try {
return afterServiceRecordService.updateAfterServiceRecord(afterServiceRecord);
} catch (Exception exception) {
logger.error(ExceptionUtils.getStackTrace(exception));
return AjaxResult.error(exception.getMessage());
OrderDetail orderDetail = orderDetailService.selectById(afterServiceRecord.getOrderDetailId());
if(orderDetail.getDrawCashTime() != null){
return AjaxResult.error("已发起分账子单,请联系师傅处理线下售后!");
}
}
/**
* 修改商品售后记录
*/
@PostMapping("/editGoods")
@ResponseBody
public AjaxResult editGoodsSave(@RequestBody AfterServiceRecord afterServiceRecord) {
logger.info("修改商品售后记录:{}", afterServiceRecord);
try {
return afterServiceRecordService.updateGoodsAfterServiceRecord(afterServiceRecord);
return toAjax(afterServiceRecordService.updateAfterServiceRecord(afterServiceRecord));
} catch (Exception exception) {
logger.error(ExceptionUtils.getStackTrace(exception));
return AjaxResult.error(exception.getMessage());
@ -166,34 +155,4 @@ public class AfterServiceRecordController extends BaseController {
public AjaxResult remove(String ids) {
return toAjax(afterServiceRecordService.deleteAfterServiceRecordByIds(ids));
}
/**
* 师傅重发/补发操作
* 师傅端点击重发补发按钮保存重发/补发方案
*/
@PostMapping("/workerResendPlan")
@ResponseBody
public AjaxResult workerResendPlan(@RequestBody AfterServiceRecord afterServiceRecord) {
return afterServiceRecordService.workerResendPlan(afterServiceRecord);
}
/**
* 退货操作
* 客户或师傅端进行退货操作保存退货信息
*/
@PostMapping("/returnGoods")
@ResponseBody
public AjaxResult returnGoods(@RequestBody AfterServiceRecord afterServiceRecord) {
return afterServiceRecordService.returnGoods(afterServiceRecord);
}
/**
* 师傅确认收货
* 师傅确认收到货物后根据同意处理方式决定是否执行退款
*/
@PostMapping("/workerConfirmReceive")
@ResponseBody
public AjaxResult workerConfirmReceive(@RequestBody AfterServiceRecord afterServiceRecord) {
return afterServiceRecordService.workerConfirmReceive(afterServiceRecord);
}
}

View File

@ -1,143 +0,0 @@
package com.ghy.web.controller.order;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import com.ghy.common.annotation.Log;
import com.ghy.common.enums.BusinessType;
import com.ghy.order.domain.OrderAddRecord;
import com.ghy.order.service.IOrderAddRecordService;
import com.ghy.common.core.controller.BaseController;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.utils.poi.ExcelUtil;
import com.ghy.common.core.page.TableDataInfo;
/**
* 发单加价记录Controller
*
* @author clunt
* @date 2023-11-03
*/
@Controller
@RequestMapping("/add/record")
public class OrderAddRecordController extends BaseController
{
private String prefix = "add/record";
@Autowired
private IOrderAddRecordService orderAddRecordService;
@RequiresPermissions("worker:record:view")
@GetMapping()
public String record()
{
return prefix + "/record";
}
/**
* 查询发单加价记录列表
*/
@RequiresPermissions("worker:record:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(OrderAddRecord orderAddRecord)
{
startPage();
List<OrderAddRecord> list = orderAddRecordService.selectOrderAddRecordList(orderAddRecord);
return getDataTable(list);
}
/**
* App查询发单加价记录列表
*/
@PostMapping("/app/list")
@ResponseBody
public TableDataInfo appList(@RequestBody OrderAddRecord orderAddRecord)
{
startPage();
List<OrderAddRecord> list = orderAddRecordService.selectOrderAddRecordList(orderAddRecord);
return getDataTable(list);
}
@PostMapping("/app/add")
@ResponseBody
public AjaxResult appAddSave(@RequestBody OrderAddRecord orderAddRecord)
{
return toAjax(orderAddRecordService.insertOrderAddRecord(orderAddRecord));
}
/**
* 导出发单加价记录列表
*/
@RequiresPermissions("worker:record:export")
@Log(title = "发单加价记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(OrderAddRecord orderAddRecord)
{
List<OrderAddRecord> list = orderAddRecordService.selectOrderAddRecordList(orderAddRecord);
ExcelUtil<OrderAddRecord> util = new ExcelUtil<OrderAddRecord>(OrderAddRecord.class);
return util.exportExcel(list, "发单加价记录数据");
}
/**
* 新增发单加价记录
*/
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
* 新增保存发单加价记录
*/
@RequiresPermissions("worker:record:add")
@Log(title = "发单加价记录", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(OrderAddRecord orderAddRecord)
{
return toAjax(orderAddRecordService.insertOrderAddRecord(orderAddRecord));
}
/**
* 修改发单加价记录
*/
@RequiresPermissions("worker:record:edit")
@GetMapping("/edit/{id}")
public String edit(@PathVariable("id") Long id, ModelMap mmap)
{
OrderAddRecord orderAddRecord = orderAddRecordService.selectOrderAddRecordById(id);
mmap.put("orderAddRecord", orderAddRecord);
return prefix + "/edit";
}
/**
* 修改保存发单加价记录
*/
@RequiresPermissions("worker:record:edit")
@Log(title = "发单加价记录", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(OrderAddRecord orderAddRecord)
{
return toAjax(orderAddRecordService.updateOrderAddRecord(orderAddRecord));
}
/**
* 删除发单加价记录
*/
@RequiresPermissions("worker:record:remove")
@Log(title = "发单加价记录", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(orderAddRecordService.deleteOrderAddRecordByIds(ids));
}
}

View File

@ -1,157 +0,0 @@
package com.ghy.web.controller.order;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import com.ghy.common.annotation.Log;
import com.ghy.common.enums.BusinessType;
import com.ghy.order.domain.OrderAttachmentRecord;
import com.ghy.order.service.IOrderAttachmentRecordService;
import com.ghy.common.core.controller.BaseController;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.utils.poi.ExcelUtil;
import com.ghy.common.core.page.TableDataInfo;
/**
* 附件费Controller
*
* @author clunt
* @date 2024-01-02
*/
@Controller
@RequestMapping("/order/attach")
public class OrderAttachmentRecordController extends BaseController
{
private String prefix = "order/attach";
@Autowired
private IOrderAttachmentRecordService orderAttachmentRecordService;
@RequiresPermissions("attach:record:view")
@GetMapping()
public String record()
{
return prefix + "/record";
}
/**
* 查询附件费列表
*/
@RequiresPermissions("attach:record:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(OrderAttachmentRecord orderAttachmentRecord)
{
startPage();
List<OrderAttachmentRecord> list = orderAttachmentRecordService.selectOrderAttachmentRecordList(orderAttachmentRecord);
return getDataTable(list);
}
/**
* App查询附件费列表
*/
@PostMapping("/app/list")
@ResponseBody
public TableDataInfo appList(@RequestBody OrderAttachmentRecord orderAttachmentRecord)
{
startPage();
List<OrderAttachmentRecord> list = orderAttachmentRecordService.selectOrderAttachmentRecordList(orderAttachmentRecord);
return getDataTable(list);
}
/**
* 导出附件费列表
*/
@RequiresPermissions("attach:record:export")
@Log(title = "附件费", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(OrderAttachmentRecord orderAttachmentRecord)
{
List<OrderAttachmentRecord> list = orderAttachmentRecordService.selectOrderAttachmentRecordList(orderAttachmentRecord);
ExcelUtil<OrderAttachmentRecord> util = new ExcelUtil<OrderAttachmentRecord>(OrderAttachmentRecord.class);
return util.exportExcel(list, "附件费数据");
}
/**
* 新增附件费
*/
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
* 新增保存附件费
*/
@RequiresPermissions("attach:record:add")
@Log(title = "附件费", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(OrderAttachmentRecord orderAttachmentRecord)
{
return toAjax(orderAttachmentRecordService.insertOrderAttachmentRecord(orderAttachmentRecord));
}
@PostMapping("/appAdd")
@ResponseBody
public AjaxResult appAdd(OrderAttachmentRecord orderAttachmentRecord)
{
return toAjax(orderAttachmentRecordService.insertOrderAttachmentRecord(orderAttachmentRecord));
}
/**
* 修改附件费
*/
@RequiresPermissions("attach:record:edit")
@GetMapping("/edit/{id}")
public String edit(@PathVariable("id") Long id, ModelMap mmap)
{
OrderAttachmentRecord orderAttachmentRecord = orderAttachmentRecordService.selectOrderAttachmentRecordById(id);
mmap.put("orderAttachmentRecord", orderAttachmentRecord);
return prefix + "/edit";
}
/**
* 修改保存附件费
*/
@RequiresPermissions("attach:record:edit")
@Log(title = "附件费", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(OrderAttachmentRecord orderAttachmentRecord)
{
return toAjax(orderAttachmentRecordService.updateOrderAttachmentRecord(orderAttachmentRecord));
}
/**
* 删除附件费
*/
@RequiresPermissions("attach:record:remove")
@Log(title = "附件费", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(orderAttachmentRecordService.deleteOrderAttachmentRecordByIds(ids));
}
/**
* 删除附件费 根据子单id
*/
@PostMapping( "/deleteByDetailId")
@ResponseBody
public AjaxResult deleteByDetailId(@RequestParam Long orderDetailId)
{
return toAjax(orderAttachmentRecordService.deleteOrderAttachmentRecordByOrderDetailId(orderDetailId));
}
}

View File

@ -1,137 +0,0 @@
package com.ghy.web.controller.order;
import java.util.List;
import com.ghy.order.domain.OrderCallRecord;
import com.ghy.order.service.IOrderCallRecordService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import com.ghy.common.annotation.Log;
import com.ghy.common.enums.BusinessType;
import com.ghy.common.core.controller.BaseController;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.utils.poi.ExcelUtil;
import com.ghy.common.core.page.TableDataInfo;
/**
* 订单约单记录Controller
*
* @author clunt
* @date 2023-06-04
*/
@Controller
@RequestMapping("/order/record")
public class OrderCallRecordController extends BaseController
{
private String prefix = "order/record";
@Autowired
private IOrderCallRecordService orderCallRecordService;
// @RequiresPermissions("worker:record:view")
@GetMapping()
public String record(Long orderId, ModelMap mmap)
{
mmap.put("orderId", orderId);
return prefix;
}
/**
* 查询订单约单记录列表
*/
@RequiresPermissions("worker:record:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(OrderCallRecord orderCallRecord)
{
startPage();
List<OrderCallRecord> list = orderCallRecordService.selectOrderCallRecordList(orderCallRecord);
return getDataTable(list);
}
/**
* App查询订单约单记录列表
*/
@PostMapping("/app/list")
@ResponseBody
public TableDataInfo appList(@RequestBody OrderCallRecord orderCallRecord)
{
startPage();
List<OrderCallRecord> list = orderCallRecordService.selectOrderCallRecordList(orderCallRecord);
return getDataTable(list);
}
/**
* 导出订单约单记录列表
*/
@RequiresPermissions("worker:record:export")
@Log(title = "订单约单记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(OrderCallRecord orderCallRecord)
{
List<OrderCallRecord> list = orderCallRecordService.selectOrderCallRecordList(orderCallRecord);
ExcelUtil<OrderCallRecord> util = new ExcelUtil<OrderCallRecord>(OrderCallRecord.class);
return util.exportExcel(list, "订单约单记录数据");
}
/**
* 新增订单约单记录
*/
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
* 新增保存订单约单记录
*/
@RequiresPermissions("worker:record:add")
@Log(title = "订单约单记录", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(OrderCallRecord orderCallRecord)
{
return toAjax(orderCallRecordService.insertOrderCallRecord(orderCallRecord));
}
/**
* 修改订单约单记录
*/
@RequiresPermissions("worker:record:edit")
@GetMapping("/edit/{id}")
public String edit(@PathVariable("id") Long id, ModelMap mmap)
{
OrderCallRecord orderCallRecord = orderCallRecordService.selectOrderCallRecordById(id);
mmap.put("orderCallRecord", orderCallRecord);
return prefix + "/edit";
}
/**
* 修改保存订单约单记录
*/
@RequiresPermissions("worker:record:edit")
@Log(title = "订单约单记录", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(OrderCallRecord orderCallRecord)
{
return toAjax(orderCallRecordService.updateOrderCallRecord(orderCallRecord));
}
/**
* 删除订单约单记录
*/
@RequiresPermissions("worker:record:remove")
@Log(title = "订单约单记录", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(orderCallRecordService.deleteOrderCallRecordByIds(ids));
}
}

View File

@ -1,159 +0,0 @@
package com.ghy.web.controller.order;
import java.util.List;
import com.ghy.web.pojo.vo.CertNoTwoElementReq;
import com.ghy.web.service.AliCloudService;
import com.ghy.web.service.InsuranceService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import com.ghy.common.annotation.Log;
import com.ghy.common.enums.BusinessType;
import com.ghy.order.domain.OrderDetailInsuranceUser;
import com.ghy.order.service.IOrderDetailInsuranceUserService;
import com.ghy.common.core.controller.BaseController;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.utils.poi.ExcelUtil;
import com.ghy.common.core.page.TableDataInfo;
/**
* 订单保险人员Controller
*
* @author clunt
* @date 2024-10-21
*/
@Slf4j
@Controller
@RequestMapping("/insurance/user")
public class OrderDetailInsuranceUserController extends BaseController
{
private String prefix = "insurance/user";
@Autowired
private IOrderDetailInsuranceUserService orderDetailInsuranceUserService;
@Autowired
private AliCloudService aliCloudService;
@Autowired
private InsuranceService insuranceService;
@RequiresPermissions("worker:user:view")
@GetMapping()
public String user()
{
return prefix + "/user";
}
/**
* 查询订单保险人员列表
*/
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(OrderDetailInsuranceUser orderDetailInsuranceUser)
{
startPage();
List<OrderDetailInsuranceUser> list = orderDetailInsuranceUserService.selectOrderDetailInsuranceUserList(orderDetailInsuranceUser);
return getDataTable(list);
}
/**
* App查询订单保险人员列表
*/
@PostMapping("/app/list")
@ResponseBody
public TableDataInfo appList(@RequestBody OrderDetailInsuranceUser orderDetailInsuranceUser)
{
startPage();
List<OrderDetailInsuranceUser> list = orderDetailInsuranceUserService.selectOrderDetailInsuranceUserList(orderDetailInsuranceUser);
return getDataTable(list);
}
/**
* 导出订单保险人员列表
*/
@PostMapping("/export")
@ResponseBody
public AjaxResult export(OrderDetailInsuranceUser orderDetailInsuranceUser)
{
List<OrderDetailInsuranceUser> list = orderDetailInsuranceUserService.selectOrderDetailInsuranceUserList(orderDetailInsuranceUser);
ExcelUtil<OrderDetailInsuranceUser> util = new ExcelUtil<OrderDetailInsuranceUser>(OrderDetailInsuranceUser.class);
return util.exportExcel(list, "订单保险人员数据");
}
/**
* 新增订单保险人员
*/
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
* 新增保存订单保险人员
*/
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@RequestBody OrderDetailInsuranceUser orderDetailInsuranceUser)
{
// 先校验身份证信息是否ok
CertNoTwoElementReq req = new CertNoTwoElementReq();
req.setCertName(orderDetailInsuranceUser.getName());
req.setCertNo(orderDetailInsuranceUser.getIdCardNum());
try {
aliCloudService.certNoTwoElementVerification(req);
} catch (Exception e) {
log.error("身份证二要素校验失败:{}", e.getMessage(), e);
return AjaxResult.error("请核对姓名与身份证号!");
}
// 将保险人员增员到原保险订单上去
try {
insuranceService.editInsurance(orderDetailInsuranceUser);
orderDetailInsuranceUserService.insertOrderDetailInsuranceUser(orderDetailInsuranceUser);
return AjaxResult.success("增员完毕,保险已生效。");
}catch (Exception e){
log.error("保险增员失败:{}", e.getMessage(), e);
return AjaxResult.error("保险正生成中,可能需几秒或几分钟,请稍等即可!若超半小时可联系发单方或平台。");
}
}
/**
* 修改订单保险人员
*/
@RequiresPermissions("worker:user:edit")
@GetMapping("/edit/{id}")
public String edit(@PathVariable("id") Long id, ModelMap mmap)
{
OrderDetailInsuranceUser orderDetailInsuranceUser = orderDetailInsuranceUserService.selectOrderDetailInsuranceUserById(id);
mmap.put("orderDetailInsuranceUser", orderDetailInsuranceUser);
return prefix + "/edit";
}
/**
* 修改保存订单保险人员
*/
@RequiresPermissions("worker:user:edit")
@Log(title = "订单保险人员", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(OrderDetailInsuranceUser orderDetailInsuranceUser)
{
return toAjax(orderDetailInsuranceUserService.updateOrderDetailInsuranceUser(orderDetailInsuranceUser));
}
/**
* 删除订单保险人员
*/
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(orderDetailInsuranceUserService.deleteOrderDetailInsuranceUserByIds(ids));
}
}

View File

@ -35,23 +35,14 @@ public class OrderGoodsController extends BaseController {
@Resource
private OrderMasterService orderMasterService;
// @RequiresPermissions("order:goods:view")
@RequiresPermissions("order:goods:view")
@GetMapping()
public String orderGoods(Long orderId, ModelMap mmap) {
OrderMaster orderMaster = orderMasterService.selectById(orderId);
mmap.put("orderId", orderId);
mmap.put("orderMaster", orderMaster);
return prefix;
}
@GetMapping(value = "/master")
public String orderMasterGoods(Long orderId, ModelMap mmap) {
OrderMaster orderMaster = orderMasterService.selectById(orderId);
mmap.put("orderId", orderId);
mmap.put("orderMaster", orderMaster);
return "order/masterGoods";
}
// @RequiresPermissions("order:goods:list")
@PostMapping("/list")
@ResponseBody
@ -62,7 +53,7 @@ public class OrderGoodsController extends BaseController {
}
@Log(title = "主订单管理", businessType = BusinessType.EXPORT)
// @RequiresPermissions("order:goods:export")
@RequiresPermissions("order:goods:export")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(OrderGoods orderGoods) {
@ -71,7 +62,7 @@ public class OrderGoodsController extends BaseController {
return util.exportExcel(list, "主订单数据");
}
// @RequiresPermissions("order:goods:remove")
@RequiresPermissions("order:goods:remove")
@Log(title = "主订单管理", businessType = BusinessType.DELETE)
@PostMapping("/remove")
@ResponseBody
@ -87,7 +78,7 @@ public class OrderGoodsController extends BaseController {
/**
* 修改主订单
*/
// @RequiresPermissions("order:goods:edit")
@RequiresPermissions("order:goods:edit")
@GetMapping("/edit/{orderGoodsId}")
public String edit(@PathVariable("orderGoodsId") Long orderGoodsId, ModelMap mmap) {
mmap.put("orderGoods", orderGoodsService.selectById(orderGoodsId));

View File

@ -1,152 +0,0 @@
package com.ghy.web.controller.order;
import java.util.List;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import com.ghy.common.annotation.Log;
import com.ghy.common.enums.BusinessType;
import com.ghy.order.domain.OrderOperationRecord;
import com.ghy.order.service.IOrderOperationRecordService;
import com.ghy.common.core.controller.BaseController;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.utils.poi.ExcelUtil;
import com.ghy.common.core.page.TableDataInfo;
/**
* 订单操作记录Controller
*
* @author clunt
* @date 2024-02-17
*/
@Api
@Controller
@RequestMapping("/order/operate")
public class OrderOperationRecordController extends BaseController
{
private String prefix = "order/operate";
@Autowired
private IOrderOperationRecordService orderOperationRecordService;
@RequiresPermissions("order:operate:view")
@GetMapping()
public String record()
{
return prefix + "/operate";
}
/**
* 查询订单操作记录列表
*/
@RequiresPermissions("order:operate:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(OrderOperationRecord orderOperationRecord)
{
startPage();
List<OrderOperationRecord> list = orderOperationRecordService.selectOrderOperationRecordList(orderOperationRecord);
return getDataTable(list);
}
/**
* App查询订单操作记录列表
*/
@ApiOperation("订单操作记录列表")
@PostMapping("/app/list")
@ResponseBody
public TableDataInfo appList(@RequestBody OrderOperationRecord orderOperationRecord)
{
startPage();
List<OrderOperationRecord> list = orderOperationRecordService.selectOrderOperationRecordList(orderOperationRecord);
return getDataTable(list);
}
/**
* 新增保存订单操作记录
*/
@ApiOperation("新增订单操作记录")
@PostMapping("/app/add")
@ResponseBody
public AjaxResult appAdd(@RequestBody OrderOperationRecord orderOperationRecord)
{
return toAjax(orderOperationRecordService.insertOrderOperationRecord(orderOperationRecord));
}
/**
* 导出订单操作记录列表
*/
@RequiresPermissions("order:operate:export")
@Log(title = "订单操作记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(OrderOperationRecord orderOperationRecord)
{
List<OrderOperationRecord> list = orderOperationRecordService.selectOrderOperationRecordList(orderOperationRecord);
ExcelUtil<OrderOperationRecord> util = new ExcelUtil<OrderOperationRecord>(OrderOperationRecord.class);
return util.exportExcel(list, "订单操作记录数据");
}
/**
* 新增订单操作记录
*/
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
* 新增保存订单操作记录
*/
@RequiresPermissions("order:operate:add")
@Log(title = "订单操作记录", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(OrderOperationRecord orderOperationRecord)
{
return toAjax(orderOperationRecordService.insertOrderOperationRecord(orderOperationRecord));
}
/**
* 修改订单操作记录
*/
@RequiresPermissions("order:operate:edit")
@GetMapping("/edit/{id}")
public String edit(@PathVariable("id") Long id, ModelMap mmap)
{
OrderOperationRecord orderOperationRecord = orderOperationRecordService.selectOrderOperationRecordById(id);
mmap.put("orderOperationRecord", orderOperationRecord);
return prefix + "/edit";
}
/**
* 修改保存订单操作记录
*/
@RequiresPermissions("order:operate:edit")
@Log(title = "订单操作记录", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(OrderOperationRecord orderOperationRecord)
{
return toAjax(orderOperationRecordService.updateOrderOperationRecord(orderOperationRecord));
}
/**
* 删除订单操作记录
*/
@RequiresPermissions("order:operate:remove")
@Log(title = "订单操作记录", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(orderOperationRecordService.deleteOrderOperationRecordByIds(ids));
}
}

View File

@ -1,202 +0,0 @@
package com.ghy.web.controller.order;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.ghy.common.enums.WxMsgEnum;
import com.ghy.common.utils.WechatMsgUtils;
import com.ghy.customer.domain.Customer;
import com.ghy.customer.service.CustomerService;
import com.ghy.order.domain.OrderDetail;
import com.ghy.order.domain.OrderMaster;
import com.ghy.order.service.OrderDetailService;
import com.ghy.order.service.OrderMasterService;
import com.ghy.worker.domain.Worker;
import com.ghy.worker.service.WorkerService;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import com.ghy.common.annotation.Log;
import com.ghy.common.enums.BusinessType;
import com.ghy.order.domain.OrderWarnRecord;
import com.ghy.order.service.IOrderWarnRecordService;
import com.ghy.common.core.controller.BaseController;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.utils.poi.ExcelUtil;
import com.ghy.common.core.page.TableDataInfo;
import javax.annotation.Resource;
/**
* 订单急报记录Controller
*
* @author clunt
* @date 2024-02-18
*/
@Controller
@RequestMapping("/warn/record")
public class OrderWarnRecordController extends BaseController
{
private String prefix = "warn/record";
@Autowired
private IOrderWarnRecordService orderWarnRecordService;
@Resource
private OrderMasterService orderMasterService;
@Resource
private OrderDetailService orderDetailService;
@Resource
private WorkerService workerService;
@Resource
private CustomerService customerService;
@RequiresPermissions("warn:record:view")
@GetMapping()
public String record()
{
return prefix + "/record";
}
/**
* 查询订单急报记录列表
*/
@RequiresPermissions("warn:record:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(OrderWarnRecord orderWarnRecord)
{
startPage();
List<OrderWarnRecord> list = orderWarnRecordService.selectOrderWarnRecordList(orderWarnRecord);
return getDataTable(list);
}
/**
* App查询订单急报记录列表
*/
@ApiOperation("急报操作记录列表")
@PostMapping("/app/list")
@ResponseBody
public TableDataInfo appList(@RequestBody OrderWarnRecord orderWarnRecord)
{
startPage();
List<OrderWarnRecord> list = orderWarnRecordService.selectOrderWarnRecordList(orderWarnRecord);
return getDataTable(list);
}
@ApiOperation("新增急报记录(约单/催单)")
@PostMapping("/app/add")
@ResponseBody
public AjaxResult appAdd(@RequestBody OrderWarnRecord orderWarnRecord)
{
Worker worker;
Customer customer;
if("01".equals(orderWarnRecord.getOrderType())){
OrderMaster orderMaster = orderMasterService.selectById(orderWarnRecord.getOrderId());
worker = workerService.selectById(orderMaster.getWorkerId());
customer = customerService.selectByCustomerId(orderMaster.getCustomerId());
}else {
OrderDetail orderDetail = orderDetailService.selectById(orderWarnRecord.getOrderId());
worker = workerService.selectById(orderDetail.getWorkerId());
customer = customerService.selectByCustomerId(orderDetail.getCustomerId());
}
// 发送急报
// 推送公众号通知数据
try {
// 消息组装
Map<String, Object> params = new HashMap<>();
// 订单编号
params.put("thing3", customer.getName());
// 名称
params.put("thing2", orderWarnRecord.getContent());
// 反馈时间
params.put("time6", com.ghy.common.utils.DateUtils.parseDateToStr("yyyy年MM月dd日 HH:mm", new Date()));
// 消息推送
WechatMsgUtils.sendWeChatMsg(WechatMsgUtils.getToken(), worker.getWxOpenId(), WxMsgEnum.WARN_ORDER, params);
} catch (Exception e) {
// 暂时不做任何操作
logger.error(e.getMessage(), e);
}
return toAjax(orderWarnRecordService.insertOrderWarnRecord(orderWarnRecord));
}
/**
* 导出订单急报记录列表
*/
@RequiresPermissions("warn:record:export")
@Log(title = "订单急报记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(OrderWarnRecord orderWarnRecord)
{
List<OrderWarnRecord> list = orderWarnRecordService.selectOrderWarnRecordList(orderWarnRecord);
ExcelUtil<OrderWarnRecord> util = new ExcelUtil<OrderWarnRecord>(OrderWarnRecord.class);
return util.exportExcel(list, "订单急报记录数据");
}
/**
* 新增订单急报记录
*/
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
* 新增保存订单急报记录
*/
@RequiresPermissions("warn:record:add")
@Log(title = "订单急报记录", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(OrderWarnRecord orderWarnRecord)
{
return toAjax(orderWarnRecordService.insertOrderWarnRecord(orderWarnRecord));
}
/**
* 修改订单急报记录
*/
@RequiresPermissions("warn:record:edit")
@GetMapping("/edit/{id}")
public String edit(@PathVariable("id") Long id, ModelMap mmap)
{
OrderWarnRecord orderWarnRecord = orderWarnRecordService.selectOrderWarnRecordById(id);
mmap.put("orderWarnRecord", orderWarnRecord);
return prefix + "/edit";
}
/**
* 修改保存订单急报记录
*/
@RequiresPermissions("warn:record:edit")
@Log(title = "订单急报记录", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(OrderWarnRecord orderWarnRecord)
{
return toAjax(orderWarnRecordService.updateOrderWarnRecord(orderWarnRecord));
}
/**
* 删除订单急报记录
*/
@RequiresPermissions("warn:record:remove")
@Log(title = "订单急报记录", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(orderWarnRecordService.deleteOrderWarnRecordByIds(ids));
}
}

View File

@ -8,9 +8,7 @@ import com.huifu.adapay.core.AdapayCore;
import com.huifu.adapay.core.util.AdapaySign;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
@ -74,12 +72,6 @@ public class AdapayCallbackController extends BaseController {
return "NG";
}
@GetMapping("/adapay/callback")
@ResponseBody
public String test() {
return "NG";
}
/**
* 校验签名
*

View File

@ -1,6 +1,5 @@
package com.ghy.web.controller.pay;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.ghy.common.adapay.model.AdapayStatusEnum;
import com.ghy.common.adapay.model.PayParam;
@ -8,20 +7,15 @@ import com.ghy.common.core.controller.BaseController;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.enums.PayStatus;
import com.ghy.common.enums.PayTypeEnum;
import com.ghy.common.utils.MoneyUtil;
import com.ghy.order.domain.OrderAttachmentRecord;
import com.ghy.order.domain.OrderDetail;
import com.ghy.order.domain.OrderMaster;
import com.ghy.order.service.IOrderAttachmentRecordService;
import com.ghy.order.service.OrderDetailService;
import com.ghy.order.service.OrderMasterService;
import com.ghy.payment.domain.FinancialChangeRecord;
import com.ghy.payment.domain.FinancialMaster;
import com.ghy.payment.domain.PaymentRelation;
import com.ghy.payment.service.AdapayService;
import com.ghy.payment.service.FinancialChangeRecordService;
import com.ghy.payment.service.FinancialMasterService;
import com.ghy.payment.service.IPaymentRelationService;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@ -30,9 +24,7 @@ import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
@ -49,16 +41,13 @@ public class AlipayController extends BaseController {
@Resource
private OrderMasterService orderMasterService;
@Resource
private OrderDetailService orderDetailService;
@Resource
private FinancialMasterService financialMasterService;
@Resource
private IPaymentRelationService paymentRelationService;
private OrderDetailService orderDetailService;
@Resource
private FinancialChangeRecordService financialChangeRecordService;
@Resource
private IOrderAttachmentRecordService orderAttachmentRecordService;
/**
* 支付宝正扫支付
@ -73,104 +62,17 @@ public class AlipayController extends BaseController {
if (om.getPayStatus() == 1 || fm.getPayStatus() == 1) {
return AjaxResult.error("订单已支付,不要重复付款!");
}
String payMoney = MoneyUtil.toS(fm.getPayMoney());
Map<String, Object> map;
String payMoney = fm.getPayMoney().setScale(2, BigDecimal.ROUND_UNNECESSARY).toString();
// TODO 这里需要补充商品标题和商品描述信息
PayParam payParam = PayParam.delayPayParam(om.getCode() + "_" + System.currentTimeMillis(), payMoney, "商品标题", "商品描述信息");
try {
JSONObject response = adapayService.alipayQrPay(om.getDeptId(), payParam, null, null, null);
boolean status = AdapayStatusEnum.succeeded.code.equals(response.getString("status"));
if (!status) {
logger.error("创建支付失败: {}", response.toJSONString());
return AjaxResult.error("网络不佳 请稍后再试");
}
// 支付二维码创建成功 保存一下paymentId
String paymentId = response.getString("id");
// 更新财务主单的paymentId
FinancialMaster fm2update = new FinancialMaster();
fm2update.setId(fm.getId());
fm2update.setPaymentId(paymentId);
fm2update.setPayType(PayTypeEnum.ALIPAY_QR.getCode());
financialMasterService.updateFinancialMaster(fm2update);
// 保存支付ID与主财务单ID到关系表
PaymentRelation relation = new PaymentRelation(null, fm.getId(), PaymentRelation.FINANCIAL_MASTER, fm.getPayMoney());
relation.setPaymentId(paymentId);
paymentRelationService.insert(relation);
return AjaxResult.success(response);
map = adapayService.alipayQrPay(om.getDeptId(), payParam, null, null, null);
} catch (BaseAdaPayException e) {
logger.error("创建支付失败", e);
return AjaxResult.error("网络不佳 请稍后再试");
}
}
@PostMapping("/addMasterQr")
public AjaxResult addMasterQrPay(@RequestBody String orderId) {
orderId = orderId.replace("\"", "");
String [] orderIds = orderId.split(",");
List<String> orderIdList = Arrays.asList(orderIds);
ArrayList<PaymentRelation> relations = new ArrayList<>();
List<Long> fmList = new ArrayList<>();
BigDecimal payMoney = BigDecimal.ZERO;
for (String id : orderIdList){
// 不知道为啥参数可能会带上双引号 这里去掉再转Long
Long orderMasterId = Long.valueOf(id);
OrderMaster orderMaster = orderMasterService.selectById(orderMasterId);
if (orderMaster == null) {
return AjaxResult.error("主订单不存在!");
}
// 查询主单是否有未支付的付款单
FinancialMaster fm = financialMasterService.selectByOrderMasterId(orderMaster.getId());
if (fm == null) {
return AjaxResult.error("财务单不存在!");
}
// 主单是否付款 没付款的话一起付
boolean fmPaid = Objects.equals(PayStatus.WAIT_PAY.getCode(), fm.getPayStatus());
if (fmPaid) {
fmList.add(fm.getId());
payMoney = payMoney.add(fm.getPayMoney());
relations.add(new PaymentRelation(null, fm.getId(), PaymentRelation.FINANCIAL_MASTER, fm.getPayMoney()));
}else {
return AjaxResult.error("选择了不需要付款的订单!");
}
if (MoneyUtil.lte0(payMoney)) {
return AjaxResult.error("不需要支付");
}
}
// 以第一单为第三放的付款单号
OrderMaster orderMaster = orderMasterService.selectById(Long.valueOf(orderIdList.get(0)));
// 付款
PayParam payParam = PayParam.delayPayParam(orderMaster.getCode() + "_" + System.currentTimeMillis(),
MoneyUtil.toS(payMoney), "订单支付", "叮咚到家服务");
JSONObject response;
try {
response = adapayService.alipayQrPay(orderMaster.getDeptId(), payParam, null, null, null);
} catch (BaseAdaPayException e) {
logger.error("创建支付失败: " + e.getMessage(), e);
return AjaxResult.error("网络不佳 请稍后再试");
}
boolean status = AdapayStatusEnum.succeeded.code.equals(response.getString("status"));
if (!status) {
logger.error("创建支付失败: {}", response.toJSONString());
return AjaxResult.error("网络不佳 请稍后再试");
}
// 支付二维码创建成功 保存一下paymentId
String paymentId = response.getString("id");
for (Long id : fmList){
FinancialMaster fm2update = new FinancialMaster();
fm2update.setId(id);
fm2update.setPaymentId(paymentId);
fm2update.setPayType(PayTypeEnum.ALIPAY_QR.getCode());
financialMasterService.updateFinancialMaster(fm2update);
}
// 保存支付ID与订单ID到关系表
for (PaymentRelation relation : relations) {
relation.setPaymentId(paymentId);
paymentRelationService.insert(relation);
}
return AjaxResult.success(response);
return AjaxResult.success(map);
}
@PostMapping("/addQr")
@ -190,41 +92,29 @@ public class AlipayController extends BaseController {
if (fm == null) {
return AjaxResult.error("财务单不存在!");
}
ArrayList<PaymentRelation> relations = new ArrayList<>();
// 主单是否付款 没付款的话一起付
boolean fmPaid = Objects.equals(PayStatus.WAIT_PAY.getCode(), fm.getPayStatus());
if (fmPaid && !"01".equals(orderMaster.getConsultMode())) {
if (fmPaid) {
payMoney = payMoney.add(fm.getPayMoney());
relations.add(new PaymentRelation(null, fm.getId(), PaymentRelation.FINANCIAL_MASTER, fm.getPayMoney()));
}
// 查询关联的加价单
FinancialChangeRecord fcr = financialChangeRecordService.selectNotPayRecordByDetailId(orderDetailId);
if (fcr != null && !"01".equals(orderMaster.getConsultMode())) {
payMoney = payMoney.add(fcr.getChangeMoney());
relations.add(new PaymentRelation(null, fcr.getId(), PaymentRelation.FINANCIAL_CHANGE, fcr.getChangeMoney()));
}else if(fcr != null){
payMoney = payMoney.add(fcr.getChangeMoney());
relations.add(new PaymentRelation(null, fcr.getId(), PaymentRelation.CONSULT_ADD, fcr.getChangeMoney()));
FinancialChangeRecord financialChangeRecord = financialChangeRecordService.selectNotPayRecordByDetailId(orderDetailId);
if (financialChangeRecord != null) {
payMoney = payMoney.add(financialChangeRecord.getChangeMoney());
}
OrderAttachmentRecord param = new OrderAttachmentRecord();
param.setOrderDetailId(orderDetailId);
List<OrderAttachmentRecord> orderAttachmentRecordList = orderAttachmentRecordService.selectOrderAttachmentRecordList(param);
if(CollectionUtil.isNotEmpty(orderAttachmentRecordList)){
payMoney = payMoney.add(orderAttachmentRecordList.get(0).getAttachMoney());
relations.add(new PaymentRelation(null, orderAttachmentRecordList.get(0).getId(), PaymentRelation.ORDER_ATTACHMENT, orderAttachmentRecordList.get(0).getAttachMoney()));
}
if (MoneyUtil.lte0(payMoney)) {
if (BigDecimal.ZERO.compareTo(payMoney) > -1) {
return AjaxResult.error("不需要支付");
}
// 付款
PayParam payParam;
if (fcr == null) {
if (financialChangeRecord == null) {
payParam = PayParam.delayPayParam(orderMaster.getCode() + "_" + System.currentTimeMillis(),
payMoney.setScale(2, BigDecimal.ROUND_UNNECESSARY).toString(),
"订单支付", "叮咚到家服务");
} else {
payParam = PayParam.delayPayParam(orderMaster.getCode() + "_" + fcr.getId() + "_" + System.currentTimeMillis(),
payParam = PayParam.delayPayParam(orderMaster.getCode() + "_" + financialChangeRecord.getId() + "_" + System.currentTimeMillis(),
payMoney.setScale(2, BigDecimal.ROUND_UNNECESSARY).toString(),
"加价付款", "叮咚到家服务");
}
@ -250,23 +140,12 @@ public class AlipayController extends BaseController {
fm2update.setPayType(PayTypeEnum.ALIPAY_QR.getCode());
financialMasterService.updateFinancialMaster(fm2update);
}
if (fcr != null) {
if (financialChangeRecord != null) {
FinancialChangeRecord fcr2update = new FinancialChangeRecord();
fcr2update.setId(fcr.getId());
fcr2update.setId(financialChangeRecord.getId());
fcr2update.setPaymentId(paymentId);
financialChangeRecordService.update(fcr2update);
}
if(CollectionUtil.isNotEmpty(orderAttachmentRecordList)){
OrderAttachmentRecord oarUpdate = new OrderAttachmentRecord();
oarUpdate.setId(orderAttachmentRecordList.get(0).getId());
oarUpdate.setPaymentId(paymentId);
orderAttachmentRecordService.updateOrderAttachmentRecord(oarUpdate);
}
// 保存支付ID与订单ID到关系表
for (PaymentRelation relation : relations) {
relation.setPaymentId(paymentId);
paymentRelationService.insert(relation);
}
return AjaxResult.success(response);
}
}

View File

@ -1,12 +1,12 @@
package com.ghy.web.controller.pay;
import com.alibaba.fastjson.JSONObject;
import com.ghy.common.adapay.model.PayParam;
import com.ghy.common.adapay.model.WxpayExpend;
import com.ghy.common.config.WxConfig;
import com.ghy.common.core.controller.BaseController;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.enums.PayStatus;
import com.ghy.common.json.JSONObject;
import com.ghy.common.utils.StringUtils;
import com.ghy.order.domain.OrderDetail;
import com.ghy.order.domain.OrderMaster;
@ -14,11 +14,9 @@ import com.ghy.order.service.OrderDetailService;
import com.ghy.order.service.OrderMasterService;
import com.ghy.payment.domain.FinancialChangeRecord;
import com.ghy.payment.domain.FinancialMaster;
import com.ghy.payment.domain.PaymentRelation;
import com.ghy.payment.service.AdapayService;
import com.ghy.payment.service.FinancialChangeRecordService;
import com.ghy.payment.service.FinancialMasterService;
import com.ghy.payment.service.IPaymentRelationService;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
@ -32,6 +30,7 @@ import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Controller
@ -48,8 +47,7 @@ public class WxPayController extends BaseController {
private FinancialMasterService financialMasterService;
@Resource
private OrderDetailService orderDetailService;
@Resource
private IPaymentRelationService paymentRelationService;
@Resource
private FinancialChangeRecordService financialChangeRecordService;
@ -58,11 +56,11 @@ public class WxPayController extends BaseController {
public AjaxResult drawCash(@RequestBody JSONObject object) {
try {
Long deptId = object.getLong("deptId");
String orderNo = object.getString("orderNo");
String cashType = object.getString("cashType");
String cashAmt = object.getString("cashAmt");
String memberId = object.getString("memberId");
String remark = object.getString("remark");
String orderNo = object.getStr("orderNo");
String cashType = object.getStr("cashType");
String cashAmt = object.getStr("cashAmt");
String memberId = object.getStr("memberId");
String remark = object.getStr("remark");
adapayService.drawCash(deptId, orderNo, cashType, cashAmt, memberId, remark, null);
return AjaxResult.success("操作成功");
} catch (Exception e) {
@ -82,60 +80,33 @@ public class WxPayController extends BaseController {
Assert.notNull(orderMaster, "找不到对应的订单");
FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(orderMaster.getId());
BigDecimal payMoney = BigDecimal.ZERO;
ArrayList<PaymentRelation> relations = new ArrayList<>();
if(PayStatus.WAIT_PAY.getCode().equals(financialMaster.getPayStatus())){
payMoney = financialMaster.getPayMoney();
relations.add(new PaymentRelation(null, financialMaster.getId(), PaymentRelation.FINANCIAL_MASTER, financialMaster.getPayMoney()));
}
List<Long> idList = orderDetailService.selectByOrderMasterId(orderMaster.getId()).stream().map(OrderDetail::getId).collect(Collectors.toList());
List<FinancialChangeRecord> financialChangeRecords = financialChangeRecordService.selectByDetailIds(StringUtils.join(idList, ","));
List<Long> financialChangeRecordIds = new ArrayList<>();
for (FinancialChangeRecord fcr : financialChangeRecords) {
if (PayStatus.WAIT_PAY.getCode().equals(fcr.getPayStatus())) {
payMoney = payMoney.add(fcr.getChangeMoney());
financialChangeRecordIds.add(fcr.getId());
relations.add(new PaymentRelation(null, fcr.getId(), PaymentRelation.FINANCIAL_CHANGE, fcr.getChangeMoney()));
for (FinancialChangeRecord financialChangeRecord : financialChangeRecords) {
if (PayStatus.WAIT_PAY.getCode().equals(financialChangeRecord.getPayStatus())) {
payMoney = payMoney.add(financialChangeRecord.getChangeMoney());
financialChangeRecordIds.add(financialChangeRecord.getId());
}
}
//调用adapay微信公众号支付.
WxpayExpend expend = new WxpayExpend();
expend.setOpenId(openId);
Map<String, Object> map;
try {
// TODO 订单里需要补充支付金额tittle简要描述分账信息description
String changeRecordIdStr = financialChangeRecordIds.size() > 0 ? StringUtils.join(financialChangeRecordIds, ",") + "_" : "";
PayParam payParam = PayParam.delayPayParam(orderMaster.getCode() + "_" + changeRecordIdStr + System.currentTimeMillis(),
String.valueOf(payMoney), "工圈子居家设备", "工圈子居家设备购买付费");
JSONObject response = adapayService.wxLitePay(orderMaster.getDeptId(), payParam, expend, null, null);
String paymentId = response.getString("id");
// 更新财务主单的paymentId
if (PayStatus.WAIT_PAY.getCode().equals(financialMaster.getPayStatus())) {
FinancialMaster fm2update = new FinancialMaster();
fm2update.setId(financialMaster.getId());
fm2update.setPaymentId(paymentId);
financialMasterService.updateFinancialMaster(fm2update);
}
// 更新财务变更记录的paymentId
for (FinancialChangeRecord fcr : financialChangeRecords) {
if (PayStatus.WAIT_PAY.getCode().equals(fcr.getPayStatus())) {
FinancialChangeRecord fcr2update = new FinancialChangeRecord();
fcr2update.setId(fcr.getId());
fcr2update.setPaymentId(paymentId);
financialChangeRecordService.update(fcr2update);
}
}
// 保存支付ID与订单ID到关系表
for (PaymentRelation relation : relations) {
relation.setPaymentId(paymentId);
paymentRelationService.insert(relation);
}
return AjaxResult.success(response);
map = adapayService.wxLitePay(orderMaster.getDeptId(), payParam, expend, null, null);
} catch (BaseAdaPayException e) {
logger.error("获取微信用户信息失败", e);
return AjaxResult.error();
}
return AjaxResult.success(map);
}
// /**

View File

@ -9,8 +9,6 @@ import com.ghy.common.enums.BusinessType;
import com.ghy.common.utils.ExceptionUtil;
import com.ghy.common.utils.poi.ExcelUtil;
import com.ghy.payment.domain.FinancialDetail;
import com.ghy.payment.request.FinancialAccountBillReq;
import com.ghy.payment.response.FinancialAccountBillResp;
import com.ghy.payment.service.FinancialDetailService;
import com.ghy.web.pojo.vo.FinancialCountRequest;
import org.apache.shiro.authz.annotation.RequiresPermissions;
@ -70,14 +68,6 @@ public class FinancialDetailController extends BaseController {
return getDataTable(list);
}
@PostMapping("/app/listV2")
@ResponseBody
public TableDataInfo appListV2(@RequestBody FinancialAccountBillReq financialAccountBillReq) {
startPage();
List<FinancialAccountBillResp> list = financialDetailService.selectFinancialDetailListV2(financialAccountBillReq);
return getDataTable(list);
}
@Log(title = "财务细单管理", businessType = BusinessType.EXPORT)
@RequiresPermissions("financial:detail:export")
@PostMapping("/export")

View File

@ -5,7 +5,6 @@ import com.ghy.common.constant.UserConstants;
import com.ghy.common.core.controller.BaseController;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.enums.BusinessType;
import com.ghy.common.json.JSONObject;
import com.ghy.common.utils.ExceptionUtil;
import com.ghy.system.domain.SysArea;
import com.ghy.system.service.ISysAreaService;
@ -16,7 +15,6 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
@ -47,43 +45,6 @@ public class SysAreaController extends BaseController {
}
@PostMapping("/app/all")
@ResponseBody
public Object appAll(@RequestBody SysArea sysArea)
{
try {
// 第一层
List<SysArea> provinceAreas = sysAreaService.selectSysAreaList(sysArea);
for (SysArea provinceArea : provinceAreas) {
logger.info("进行中的省 : " + provinceArea.getAreaName());
SysArea param1 = new SysArea();
param1.setParentCode(provinceArea.getAreaCode());
// 第二层
List<SysArea> cityAreas = sysAreaService.selectSysAreaList(param1);
for (SysArea cityArea : cityAreas){
SysArea param2 = new SysArea();
param2.setParentCode(cityArea.getAreaCode());
// 第三层
List<SysArea> countryAreas = sysAreaService.selectSysAreaList(param2);
for (SysArea countryArea : countryAreas){
SysArea param3 = new SysArea();
param3.setParentCode(countryArea.getAreaCode());
// 第三层 街道
List<SysArea> streetAreas = sysAreaService.selectSysAreaList(param3);
countryArea.setChild(streetAreas);
}
cityArea.setChild(countryAreas);
}
provinceArea.setChild(cityAreas);
}
return provinceAreas;
}catch (Exception e){
logger.error(ExceptionUtil.getExceptionMessage(e));
return AjaxResult.error(e.getMessage());
}
}
@PostMapping("/app/list")
@ResponseBody
public AjaxResult appList(@RequestBody SysArea sysArea)

View File

@ -45,7 +45,7 @@ public class SysDeptController extends BaseController
return prefix + "/dept";
}
// @RequiresPermissions("system:dept:list")
@RequiresPermissions("system:dept:list")
@PostMapping("/list")
@ResponseBody
public List<SysDept> list(SysDept dept)

View File

@ -1,6 +1,5 @@
package com.ghy.web.controller.system;
import com.ghy.common.core.domain.dto.SysUserAddDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@ -13,8 +12,6 @@ import com.ghy.common.utils.StringUtils;
import com.ghy.framework.shiro.service.SysRegisterService;
import com.ghy.system.service.ISysConfigService;
import javax.validation.Valid;
/**
* 注册验证
*
@ -37,13 +34,13 @@ public class SysRegisterController extends BaseController
@PostMapping("/register")
@ResponseBody
public AjaxResult ajaxRegister(@Valid SysUserAddDTO userAddDTO)
public AjaxResult ajaxRegister(SysUser user)
{
if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser"))))
{
return error("当前系统没有开启注册功能!");
}
String msg = registerService.register(userAddDTO);
String msg = registerService.register(user);
return StringUtils.isEmpty(msg) ? success() : error(msg);
}
}

View File

@ -1,52 +0,0 @@
package com.ghy.web.controller.tool;
import cn.hutool.json.JSONUtil;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.utils.StringUtils;
import com.ghy.web.pojo.vo.CertNoTwoElementReq;
import com.ghy.web.service.AliCloudService;
import com.ghy.worker.domain.Worker;
import com.ghy.worker.service.WorkerService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Slf4j
@Tag(name = "阿里云Api接口")
@Controller
@RequestMapping("/tool/ali")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class AliCloudController {
private final AliCloudService aliCloudService;
private final WorkerService workerService;
@Operation(summary = "身份证二要素校验")
@PostMapping("/certNoTwoElementVerification")
@ResponseBody
public AjaxResult certNoTwoElementVerification(@RequestBody CertNoTwoElementReq certNoTwoElementReq){
try {
Worker worker = workerService.selectById(certNoTwoElementReq.getWorkerId());
if(StringUtils.isNotEmpty(worker.getRemark())){
return AjaxResult.success("操作成功!");
}else {
aliCloudService.certNoTwoElementVerification(certNoTwoElementReq);
worker.setRemark(JSONUtil.toJsonStr(certNoTwoElementReq));
workerService.updateWorker(worker);
return AjaxResult.success();
}
}catch (Exception e){
log.error("身份证二要素校验失败:{}", e.getMessage(), e);
return AjaxResult.success(e.getMessage(), "身份证二要素校验失败!");
}
}
}

View File

@ -17,9 +17,6 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
/**
* 百度地图逆解析
* @author clunt
@ -41,34 +38,12 @@ public class BaiduController extends BaseController {
JSONObject json = new JSONObject();
String location = jsonObject.getString("location");
// 解析经纬度
String[] coordinates = location.split(",");
if (coordinates.length != 2) {
return AjaxResult.error("location格式错误应为经度,纬度");
}
try {
double longitude = Double.parseDouble(coordinates[1]); // 经度
double latitude = Double.parseDouble(coordinates[0]); // 纬度
// 将经纬度添加到返回结果中
json.put("longitude", longitude);
json.put("latitude", latitude);
json.put("coordinates", coordinates);
logger.info("解析到的坐标 - 经度: {}, 纬度: {}", longitude, latitude);
} catch (NumberFormatException e) {
return AjaxResult.error("经纬度格式错误");
}
String url = baiduConfig.getUrl().replace("#AK#", baiduConfig.getAk()) + location;
String result = HttpUtils.sendGet(url);
result = result.replaceAll("\n", "").replaceAll("\t", "");
JSONObject resultJson = JSONObject.parseObject(result);
if("0".equals(resultJson.getString("status"))){
JSONObject addressJson = resultJson.getJSONObject("result").getJSONObject("addressComponent");
logger.info("百度地图获取到的地址 :" + addressJson);
String provinceName = addressJson.getString("province");
logger.info("provinceName :" + provinceName);
SysArea provinceArea = iSysAreaService.selectByName(provinceName, null);
@ -78,25 +53,9 @@ public class BaiduController extends BaseController {
String countryName = addressJson.getString("district");
logger.info("countryName :" + countryName);
SysArea countryArea = iSysAreaService.selectByName(countryName, cityArea.getAreaCode());
String streetName = addressJson.getString("town");
logger.info("streetName :" + streetName);
SysArea streetArea = iSysAreaService.selectByName(streetName, countryArea.getAreaCode());
// 添加地址信息
json.put("provinceArea", provinceArea);
json.put("cityArea", cityArea);
json.put("countryArea", countryArea);
json.put("streetArea", streetArea);
// 添加完整地址
String fullAddress = (provinceName != null ? provinceName : "") +
(cityName != null ? cityName : "") +
(countryName != null ? countryName : "") +
(streetName != null ? streetName : "");
json.put("fullAddress", fullAddress);
// 保留原有的location字段用于兼容
json.put("location", location);
}else {
return AjaxResult.error("Api服务异常!");
}
@ -108,56 +67,6 @@ public class BaiduController extends BaseController {
}
}
/**
* 百度地图正向地理编码地址 -> 经纬度
* 接收JSON{provinceName, cityName, countryName, streetName, address}
*/
@PostMapping("/geocode")
@ResponseBody
public AjaxResult geocode(@RequestBody JSONObject jsonObject) {
try {
String provinceName = jsonObject.getString("provinceName");
String cityName = jsonObject.getString("cityName");
String countryName = jsonObject.getString("countryName");
String streetName = jsonObject.getString("streetName");
String detailAddress = jsonObject.getString("address");
StringBuilder full = new StringBuilder();
if (provinceName != null) { full.append(provinceName); }
if (cityName != null) { full.append(cityName); }
if (countryName != null) { full.append(countryName); }
if (streetName != null) { full.append(streetName); }
if (detailAddress != null) { full.append(detailAddress); }
String address = full.toString();
if (address == null || address.trim().isEmpty()) {
return AjaxResult.error("地址不能为空");
}
String encoded = URLEncoder.encode(address, StandardCharsets.UTF_8.name());
// 使用百度正向地理编码API
String url = "https://api.map.baidu.com/geocoding/v3/?output=json&ak="
+ baiduConfig.getAk() + "&address=" + encoded;
String result = HttpUtils.sendGet(url);
result = result.replaceAll("\n", "").replaceAll("\t", "");
JSONObject resultJson = JSONObject.parseObject(result);
if ("0".equals(resultJson.getString("status"))) {
JSONObject location = resultJson.getJSONObject("result").getJSONObject("location");
JSONObject data = new JSONObject();
data.put("longitude", location.getBigDecimal("lng"));
data.put("latitude", location.getBigDecimal("lat"));
data.put("fullAddress", address);
return AjaxResult.success(data);
} else {
return AjaxResult.error("百度地理编码失败:" + resultJson.getString("msg"));
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
return AjaxResult.error(ExceptionUtil.getExceptionMessage(e));
}
}
public static void main(String[] args) {
String result = " {\"status\":0,\"result\":{\"location\":{\"lng\":113.29950224957551,\"lat\":23.019282373814027},\"formatted_address\":\"广东省广州市番禺区安平路\",\"business\":\"大石\",\"addressComponent\":{\"country\":\"中国\",\"country_code\":0,\"country_code_iso\":\"CHN\",\"country_code_iso2\":\"CN\",\"province\":\"广东省\",\"city\":\"广州市\",\"city_level\":2,\"district\":\"番禺区\",\"town\":\"\",\"town_code\":\"\",\"distance\":\"\",\"direction\":\"\",\"adcode\":\"440113\",\"street\":\"安平路\",\"street_number\":\"\"},\"pois\":[],\"roads\":[],\"poiRegions\":[],\"sematic_description\":\"\",\"cityCode\":257}}\n";

View File

@ -1,8 +1,5 @@
package com.ghy.web.controller.tool;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ghy.common.config.WxConfig;
import com.ghy.common.core.controller.BaseController;
@ -11,7 +8,6 @@ import com.ghy.common.enums.OrderStatus;
import com.ghy.common.exception.ServiceException;
import com.ghy.common.utils.ExceptionUtil;
import com.ghy.common.utils.StringUtils;
import com.ghy.common.utils.WechatMsgUtils;
import com.ghy.common.utils.WxUtils;
import com.ghy.common.utils.http.HttpUtils;
import com.ghy.customer.domain.Customer;
@ -32,9 +28,7 @@ import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author clunt
@ -190,205 +184,9 @@ public class WxController extends BaseController {
}
String data = HttpUtils.sendGet(url, null);
JSONObject result = JSONObject.parseObject(data);
// 如果是师傅端,需要调用公众号的获取用户列表接口 -- 遍历列表去找到unionId和openid关联并入库
// if(!"customer".equals(from)){
// String openid = result.getString("openid");
// String unionId = result.getString("unionid");
// // 查询openid是否入库已经入库则不管
// Worker param = new Worker();
// param.setOpenId(openid);
// Worker worker = workerService.selectByOpenId(param);
// if(worker != null && StringUtils.isEmpty(worker.getWxOpenId())){
// // 公众号token
// String wxToken = WechatMsgUtils.getToken();
// String wxUserOpenidList = HttpUtils.sendGet("https://api.weixin.qq.com/cgi-bin/user/get?access_token="+wxToken+"&next_openid=");
// logger.info("公众号获取的用户列表集合:{}", wxUserOpenidList);
// JSONObject wxOpenidJson = JSONObject.parseObject(wxUserOpenidList);
// JSONObject openIdListJson = wxOpenidJson.getJSONObject("data");
// List<String> openidList = openIdListJson.getObject("openid", ArrayList.class);
// JSONArray openidJsonArray = new JSONArray();
// openidList.forEach(model->{
// JSONObject openidJson = new JSONObject();
// openidJson.put("openid", model);
// openidJson.put("lang", "zh_CN");
// openidJsonArray.add(openidJson);
// });
// JSONObject jsonParam = new JSONObject();
// xw jsonParam.put("user_list", openidJsonArray);
// String unionUrl = "https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token="+WechatMsgUtils.getToken();;
// logger.info("调用获取用户信息,请求url:{}, 请求body:{}", unionUrl, jsonParam.toJSONString());
// String getUnionResult = HttpUtil.post(unionUrl, jsonParam.toJSONString());
// logger.info("获取公众号union列表:{}", getUnionResult);
// JSONObject unionJson = JSONObject.parseObject(getUnionResult);
// JSONArray unionJsonArray = unionJson.getJSONArray("user_info_list");
// for (int index = 0 ; index<unionJsonArray.size(); index ++){
// JSONObject json = unionJsonArray.getJSONObject(index);
// if(StringUtils.isEmpty(json.getString("unionid"))||StringUtils.isEmpty(unionId)){
// return AjaxResult.success(result);
// }
// if(json.getString("unionid").equals(unionId)){
// Worker updateWorker = new Worker();
// updateWorker.setWorkerId(worker.getWorkerId());
// updateWorker.setWxOpenId(json.getString("openid"));
// logger.info("关联后的worker信息:{}", worker);
// workerService.updateWorker(updateWorker);
// }
// }
// }
//
// }
return AjaxResult.success(result);
}
@GetMapping("/check")
@ResponseBody
public AjaxResult check(HttpServletRequest request) {
String url;
boolean flag = false;
String deptId = request.getHeader("deptId");
String from = request.getHeader("from");
SysDeptConfig sysDeptConfig = sysDeptConfigService.selectByDeptId(Long.parseLong(deptId));
String code = request.getHeader("code");
if("customer".equals(from)){
url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + sysDeptConfig.getWxAppId() + "&secret=" + sysDeptConfig.getWxSecret() + "&js_code=" + code + "&grant_type=authorization_code";
}else {
url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + sysDeptConfig.getServWxAppId() + "&secret=" + sysDeptConfig.getServWxSecret() + "&js_code=" + code + "&grant_type=authorization_code";
}
String data = HttpUtils.sendGet(url, null);
JSONObject result = JSONObject.parseObject(data);
// 如果是师傅端,需要调用公众号的获取用户列表接口 -- 遍历列表去找到unionId和openid关联并入库
if(!"customer".equals(from)){
String openid = result.getString("openid");
String unionId = result.getString("unionid");
// 查询openid是否入库已经入库则不管
Worker param = new Worker();
param.setOpenId(openid);
Worker worker = workerService.selectByOpenId(param);
if(worker != null){
// 公众号token
String wxToken = WechatMsgUtils.getToken();
String wxUserOpenidList = HttpUtils.sendGet("https://api.weixin.qq.com/cgi-bin/user/get?access_token="+wxToken+"&next_openid=");
logger.info("公众号获取的用户列表集合:{}", wxUserOpenidList);
JSONObject wxOpenidJson = JSONObject.parseObject(wxUserOpenidList);
JSONObject openIdListJson = wxOpenidJson.getJSONObject("data");
List<String> openidList = openIdListJson.getObject("openid", ArrayList.class);
List<List<String>> batchList = ListUtil.partition(openidList, 99);
for (List<String> childOpenidList : batchList) {
JSONArray openidJsonArray = new JSONArray();
childOpenidList.forEach(model->{
JSONObject openidJson = new JSONObject();
openidJson.put("openid", model);
openidJson.put("lang", "zh_CN");
openidJsonArray.add(openidJson);
});
JSONObject jsonParam = new JSONObject();
jsonParam.put("user_list", openidJsonArray);
String unionUrl = "https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token="+WechatMsgUtils.getToken();;
logger.info("调用获取用户信息,请求url:{}, 请求body:{}", unionUrl, jsonParam.toJSONString());
String getUnionResult = HttpUtil.post(unionUrl, jsonParam.toJSONString());
logger.info("获取公众号union列表:{}", getUnionResult);
JSONObject unionJson = JSONObject.parseObject(getUnionResult);
JSONArray unionJsonArray = unionJson.getJSONArray("user_info_list");
for (int index = 0 ; index<unionJsonArray.size(); index ++){
JSONObject json = unionJsonArray.getJSONObject(index);
if(StringUtils.isNotEmpty(json.getString("unionid") )&& StringUtils.isNotEmpty(unionId)){
if(json.getString("unionid").equals(unionId)){
Worker updateWorker = new Worker();
updateWorker.setWorkerId(worker.getWorkerId());
updateWorker.setWxOpenId(json.getString("openid"));
logger.info("关联后的worker信息:{}", worker);
workerService.updateWorker(updateWorker);
flag = true;
break;
}
}
}
if(flag){
break;
}
}
}
}
return AjaxResult.success(true);
}
@GetMapping("/neCheck")
@ResponseBody
public AjaxResult neCheck(HttpServletRequest request) {
try {
String url;
boolean flag = false;
String deptId = request.getHeader("deptId");
String from = request.getHeader("from");
SysDeptConfig sysDeptConfig = sysDeptConfigService.selectByDeptId(Long.parseLong(deptId));
String code = request.getHeader("code");
if("customer".equals(from)){
url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + sysDeptConfig.getWxAppId() + "&secret=" + sysDeptConfig.getWxSecret() + "&js_code=" + code + "&grant_type=authorization_code";
}else {
url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + sysDeptConfig.getServWxAppId() + "&secret=" + sysDeptConfig.getServWxSecret() + "&js_code=" + code + "&grant_type=authorization_code";
}
String data = HttpUtils.sendGet(url, null);
JSONObject result = JSONObject.parseObject(data);
// 如果是师傅端,需要调用公众号的获取用户列表接口 -- 遍历列表去找到unionId和openid关联并入库
if(!"customer".equals(from)){
String openid = result.getString("openid");
String unionId = result.getString("unionid");
// 查询openid是否入库已经入库则不管
Worker param = new Worker();
param.setOpenId(openid);
Worker worker = workerService.selectByOpenId(param);
if(worker != null){
// 公众号token
String wxToken = WechatMsgUtils.getToken();
String wxUserOpenidList = HttpUtils.sendGet("https://api.weixin.qq.com/cgi-bin/user/get?access_token="+wxToken+"&next_openid=");
logger.info("公众号获取的用户列表集合:{}", wxUserOpenidList);
JSONObject wxOpenidJson = JSONObject.parseObject(wxUserOpenidList);
JSONObject openIdListJson = wxOpenidJson.getJSONObject("data");
List<String> openidList = openIdListJson.getObject("openid", ArrayList.class);
List<List<String>> batchList = ListUtil.partition(openidList, 99);
for (List<String> childOpenidList : batchList) {
JSONArray openidJsonArray = new JSONArray();
childOpenidList.forEach(model->{
JSONObject openidJson = new JSONObject();
openidJson.put("openid", model);
openidJson.put("lang", "zh_CN");
openidJsonArray.add(openidJson);
});
JSONObject jsonParam = new JSONObject();
jsonParam.put("user_list", openidJsonArray);
String unionUrl = "https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token="+WechatMsgUtils.getToken();;
logger.info("调用获取用户信息,请求url:{}, 请求body:{}", unionUrl, jsonParam.toJSONString());
String getUnionResult = HttpUtil.post(unionUrl, jsonParam.toJSONString());
logger.info("获取公众号union列表:{}", getUnionResult);
JSONObject unionJson = JSONObject.parseObject(getUnionResult);
JSONArray unionJsonArray = unionJson.getJSONArray("user_info_list");
for (int index = 0 ; index<unionJsonArray.size(); index ++){
JSONObject json = unionJsonArray.getJSONObject(index);
if(StringUtils.isNotEmpty(json.getString("unionid") )&& StringUtils.isNotEmpty(unionId)){
if(json.getString("unionid").equals(unionId)){
Worker updateWorker = new Worker();
updateWorker.setWorkerId(worker.getWorkerId());
updateWorker.setWxOpenId(json.getString("openid"));
logger.info("关联后的worker信息:{}", worker);
workerService.updateWorker(updateWorker);
flag = true;
break;
}
}
}
if(flag){
break;
}
}
}
}
return AjaxResult.success(flag);
}catch (Exception e){
return AjaxResult.success(false);
}
}
@GetMapping("/openid")
@ResponseBody

View File

@ -1,10 +1,7 @@
package com.ghy.web.controller.worker;
import com.ghy.common.core.controller.BaseController;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.core.page.TableDataInfo;
import com.ghy.common.core.text.Convert;
import com.ghy.order.domain.OrderGoods;
import com.ghy.system.domain.SysArea;
import com.ghy.system.service.ISysAreaService;
import com.ghy.worker.domain.WorkerArea;
@ -14,7 +11,6 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
@ -30,7 +26,7 @@ import java.util.stream.Collectors;
@Slf4j
@Controller
@RequestMapping("worker/area")
public class WorkerAreaController extends BaseController {
public class WorkerAreaController {
@Resource
private WorkerAreaService workerAreaService;
@ -38,154 +34,42 @@ public class WorkerAreaController extends BaseController {
@Autowired
private ISysAreaService sysAreaService;
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(WorkerArea workerArea) {
startPage();
List<WorkerArea> list = workerAreaService.getWorkerAreaList(workerArea);
return getDataTable(list);
}
@GetMapping()
public String area(Long workerId, ModelMap mmap)
{
mmap.put("workerId", workerId);
return "worker/areaDetail";
}
/**
* 查询某个师傅的所有接单地区
*
* @param workerId 师傅ID
* @param serviceType 服务类型1=服务, 2=商品不传则查询所有
*/
@GetMapping("worker")
@ResponseBody
public AjaxResult getByWorker(Long workerId, Integer serviceType) {
if (serviceType != null) {
// 根据服务类型查询
return AjaxResult.success(workerAreaService.getByWorkerIdAndType(workerId, serviceType));
} else {
// 查询所有区域保持向后兼容
public AjaxResult getByWorker(Long workerId) {
return AjaxResult.success(workerAreaService.getByWorker(workerId));
}
}
/**
* 查询某个师傅的服务区域类型1
*
* @param workerId 师傅ID
*/
@GetMapping("worker/service")
@ResponseBody
public AjaxResult getServiceAreasByWorker(Long workerId) {
return AjaxResult.success(workerAreaService.getByWorkerIdAndType(workerId, 1));
}
/**
* 查询某个师傅的商品区域类型2
*
* @param workerId 师傅ID
*/
@GetMapping("worker/goods")
@ResponseBody
public AjaxResult getGoodsAreasByWorker(Long workerId) {
return AjaxResult.success(workerAreaService.getByWorkerIdAndType(workerId, 2));
}
@GetMapping("worker/edit")
@ResponseBody
public AjaxResult getEditWorker(Long workerId, Integer type){
public AjaxResult getEditWorker(Long workerId){
Map<Long, List<String>> countryMap = new HashMap<>();
// 需求1根据类型查询对应的区域数据
List<WorkerArea> byWorker;
if (Integer.valueOf(1).equals(type)) {
// 服务类型查询服务区域
byWorker = workerAreaService.getByWorkerIdAndType(workerId, 1);
} else if (Integer.valueOf(2).equals(type)) {
// 商品类型查询商品区域
byWorker = workerAreaService.getByWorkerIdAndType(workerId, 2);
} else {
// 不传类型查询所有区域
byWorker = workerAreaService.getByWorker(workerId);
}
// 收集只有cityId没有districtId的城市ID集合用于单独处理
Set<Long> cityOnlyIds = new HashSet<>();
// 按districtId分组收集cityIds
Map<Long, Set<Long>> districtCityMap = new HashMap<>();
List<WorkerArea> byWorker = workerAreaService.getByWorker(workerId);
for (WorkerArea area : byWorker){
Long districtId = area.getDistrictId();
// 如果有districtId按districtId分组处理
if (districtId != null) {
List<String> ids;
if(countryMap.containsKey(districtId)){
ids = countryMap.get(districtId);
if(countryMap.containsKey(area.getDistrictId())){
ids = countryMap.get(area.getDistrictId());
}else {
ids = new ArrayList<>();
}
// 收集该district下的城市ID
if (area.getCityId() != null) {
districtCityMap.computeIfAbsent(districtId, k -> new HashSet<>()).add(area.getCityId());
}
// 添加街道ID
if (area.getStreetId() != null) {
ids.add(String.valueOf(area.getStreetId()));
countryMap.put(area.getDistrictId(), ids);
}
countryMap.put(districtId, ids);
} else {
// 如果只有cityId没有districtId收集到cityOnlyIds
if (area.getCityId() != null) {
cityOnlyIds.add(area.getCityId());
}
}
}
List<WorkerArea> result = new ArrayList<>();
// 处理有districtId的情况正常流程
for (Map.Entry<Long, List<String>> longListEntry : countryMap.entrySet()) {
WorkerArea model = new WorkerArea();
Long districtId = longListEntry.getKey();
SysArea countryArea = sysAreaService.selectById(districtId);
SysArea countryArea = sysAreaService.selectById(longListEntry.getKey());
model.setDistrictArea(countryArea);
SysArea cityArea = sysAreaService.selectById(Long.valueOf(countryArea.getParentCode()));
model.setCityArea(cityArea);
SysArea provinceArea = sysAreaService.selectById(Long.valueOf(cityArea.getParentCode()));
model.setProvinceArea(provinceArea);
// 设置该district下的cityIds
Set<Long> districtCityIds = districtCityMap.getOrDefault(districtId, new HashSet<>());
List<Long> cityIdList = new ArrayList<>(districtCityIds);
model.setCityIds(cityIdList);
// 设置街道ID列表
model.setStreetIds(longListEntry.getValue());
result.add(model);
}
// 处理只有cityId没有districtId的情况只返回省市信息
for (Long cityId : cityOnlyIds) {
WorkerArea model = new WorkerArea();
SysArea cityArea = sysAreaService.selectById(cityId);
model.setCityArea(cityArea);
// 获取省份信息
SysArea provinceArea = sysAreaService.selectById(Long.valueOf(cityArea.getParentCode()));
model.setProvinceArea(provinceArea);
// 只设置城市ID列表
List<Long> cityIdList = new ArrayList<>();
cityIdList.add(cityId);
model.setCityIds(cityIdList);
// 不设置district和street信息
result.add(model);
}
return AjaxResult.success(result);

View File

@ -21,7 +21,6 @@ import com.huifu.adapay.core.exception.BaseAdaPayException;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@ -58,8 +57,6 @@ public class WorkerBankController extends BaseController {
return AjaxResult.error("师傅未通过审核,不能绑定银行卡");
}
Set<Merchant> merchants = AdapayConfig.getMerchants();
String phone = request.getPhone();
phone = StringUtils.trimAllWhitespace(phone);
for (Merchant merchant : merchants) {
String memberId = AdapayUtils.getWorkerMemberId(request.getWorkerId(), merchant.getDeptId());
@ -69,7 +66,7 @@ public class WorkerBankController extends BaseController {
logger.info("用户[memberId={}]已存在 跳过实名直接绑卡", memberId);
} else {
// 先在Adapay创建实名用户
Map<String, Object> result1 = adapayService.createMember(merchant.getDeptId(), memberId, phone,
Map<String, Object> result1 = adapayService.createMember(merchant.getDeptId(), memberId, request.getPhone(),
request.getName(), request.getCertId());
if (!AdapayStatusEnum.succeeded.code.equals(result1.get("status"))) {
logger.error("实名认证失败[{}]", JSON.toJSONString(result1));
@ -79,11 +76,11 @@ public class WorkerBankController extends BaseController {
// 开始创建结算账户
JSONObject result2 = adapayService.createSettleAccount(merchant.getDeptId(), memberId, request.getBankNum(), request.getName(),
"2", request.getCertId(), phone, null, null, null);
"2", request.getCertId(), request.getPhone(), null, null, null);
if (!AdapayStatusEnum.succeeded.code.equals(result2.get("status"))) {
if ("account_exists".equals(result2.get("error_code"))) {
logger.info("用户[memberId={}]结算账户已存在 跳过", memberId);
continue;
} else {
logger.error("创建结算账户失败[{}]", JSON.toJSONString(result2));
return AjaxResult.error("个人信息与银行卡不匹配或不支持信用卡绑定");
@ -96,7 +93,7 @@ public class WorkerBankController extends BaseController {
workerBank.setName(request.getName());
workerBank.setCertId(request.getCertId());
workerBank.setBankNum(request.getBankNum());
workerBank.setPhone(phone);
workerBank.setPhone(request.getPhone());
workerBank.setDeptId(merchant.getDeptId());
workerBank.setAdapayMemberId(memberId);
workerBank.setSettleAccount(1);
@ -159,10 +156,7 @@ public class WorkerBankController extends BaseController {
@ResponseBody
public AjaxResult getByWorkerId(@RequestBody WorkerBindBankCardRequest request) {
try {
if(request.getDeptId() == null){
request.setDeptId(101L);
}
return AjaxResult.success(workerBankService.getByWorkerId(request.getWorkerId(), request.getDeptId()));
return AjaxResult.success(workerBankService.getByWorkerId(request.getWorkerId()));
} catch (Exception e) {
return AjaxResult.error(ExceptionUtil.getExceptionMessage(e));

View File

@ -6,8 +6,11 @@ import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.core.page.TableDataInfo;
import com.ghy.common.enums.BusinessType;
import com.ghy.common.enums.WorkerCertifyStatus;
import com.ghy.common.enums.WorkerStatus;
import com.ghy.common.json.JSONObject;
import com.ghy.common.utils.ExceptionUtil;
import com.ghy.common.utils.ObjectUtils;
import com.ghy.common.utils.StringUtils;
import com.ghy.common.utils.poi.ExcelUtil;
import com.ghy.goods.domain.DeptGoodsCategory;
import com.ghy.goods.service.DeptGoodsCategoryService;
@ -27,6 +30,7 @@ import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@ -77,13 +81,7 @@ public class WorkerCertificationController extends BaseController
public TableDataInfo list(WorkerCertification workerCertification)
{
startPage();
if(this.getSysUser().getDept().getParentId() != 101){
workerCertification.setDeptId(this.getSysUser().getDept().getParentId());
}
List<WorkerCertification> list = workerCertificationService.selectWorkerCertificationList(workerCertification);
list.forEach(worker->{
worker.setName(worker.getSurname() + worker.getName());
});
return getDataTable(list);
}
@ -162,8 +160,6 @@ public class WorkerCertificationController extends BaseController
@ResponseBody
@Transactional(rollbackFor = Exception.class)
public AjaxResult appAddCertify(@RequestBody WorkerCertification request) {
Worker worker = workerService.selectById(request.getWorkerId());
request.setWorkerPhone(worker != null ? worker.getPhone() : null);
// 将师傅状态设置为冻结
// Worker worker = new Worker();
// worker.setWorkerId(request.getWorkerId());
@ -226,7 +222,7 @@ public class WorkerCertificationController extends BaseController
for (String id : idArray){
WorkerCertification workerCertification = workerCertificationService.selectWorkerCertificationByWorkerCertificationId(id);
// 是否绑定了银行卡
WorkerBank workerBank = workerBankService.getByWorkerId(workerCertification.getWorkerId(), 101L);
WorkerBank workerBank = workerBankService.getByWorkerId(workerCertification.getWorkerId());
// 没有绑定了银行卡的用户
if(ObjectUtils.isEmpty(workerBank)){
return AjaxResult.success("操作成功!");

View File

@ -10,7 +10,6 @@ import com.ghy.common.enums.WorkerStatus;
import com.ghy.common.enums.WorkerType;
import com.ghy.common.utils.CacheUtils;
import com.ghy.common.utils.ExceptionUtil;
import com.ghy.common.utils.StringUtils;
import com.ghy.goods.domain.Goods;
import com.ghy.goods.domain.GoodsCategory;
import com.ghy.goods.service.GoodsCategoryService;
@ -25,7 +24,6 @@ import com.ghy.worker.domain.WorkerArea;
import com.ghy.worker.domain.WorkerBank;
import com.ghy.worker.domain.WorkerGoodsCategory;
import com.ghy.worker.service.*;
import com.github.pagehelper.PageInfo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.util.Assert;
@ -83,18 +81,9 @@ public class WorkerController extends BaseController {
public AjaxResult login(@RequestBody Worker worker){
try {
Assert.notNull(worker.getPhone(), "手机号码为空");
List<Worker> workerList = workerService.getWorkByPhoneAndPwd(worker);
List<Worker> workerList = workerService.getWorkList(worker);
if(workerList.size() > 0){
Worker loginWorker = workerList.get(0);
// 检查师傅状态0=生效,1=冻结,2=删除
if(loginWorker.getStatus() == WorkerStatus.DELETED.getCode()){
return AjaxResult.error("账户已被删除,无法登录!");
}
// 检查登录状态0=允许登录,1=禁止登录
if(loginWorker.getLoginStatus() != null && loginWorker.getLoginStatus() == 1){
return AjaxResult.error("账户登录已被禁用,无法登录!");
}
return AjaxResult.success(loginWorker);
return AjaxResult.success(workerList.get(0));
}else {
return AjaxResult.error("用户名或密码错误!");
}
@ -109,13 +98,11 @@ public class WorkerController extends BaseController {
@ResponseBody
public AjaxResult register(@RequestBody Worker request){
try {
logger.info("注册师傅信息:{}", request);
if (CacheUtils.get(request.getPhone()) == null){
return AjaxResult.error("验证码无效!");
}
// 验证码校验正确
if(CacheUtils.get(request.getPhone()).toString().equals(request.getRegisterCode())){
logger.info("验证码信息:{}", CacheUtils.get(request.getPhone()));
int result = workerService.updateWorker(request);
if(result > 0){
CacheUtils.remove(request.getPhone());
@ -142,108 +129,28 @@ public class WorkerController extends BaseController {
try {
// 查询满足区域条件的师傅区域记录
List<Long> workerIdsByArea = new ArrayList<>();
if(workerListRequest.getAreaId() != null){
WorkerArea workerArea = new WorkerArea();
workerArea.setDistrictId(workerListRequest.getAreaId());
// 如果有省市区的查询条件,需要构建完整的区域查询条件
boolean flag = StringUtils.isNotEmpty(workerListRequest.getDistrictId()) || StringUtils.isNotEmpty(workerListRequest.getProvinceId())
|| StringUtils.isNotEmpty(workerListRequest.getCityId()) || StringUtils.isNotEmpty(workerListRequest.getStreetId());
if(flag){
workerArea.setDistrictId(null);
}
if(StringUtils.isNotEmpty(workerListRequest.getDistrictId())){
workerArea.setDistrictId(Long.valueOf(workerListRequest.getDistrictId()));
}
if(StringUtils.isNotEmpty(workerListRequest.getProvinceId())) {
workerArea.setProvinceId(Long.valueOf(workerListRequest.getProvinceId()));
}
if(StringUtils.isNotEmpty(workerListRequest.getCityId())) {
workerArea.setCityId(Long.valueOf(workerListRequest.getCityId()));
}
if(StringUtils.isNotEmpty(workerListRequest.getStreetId())) {
workerArea.setStreetId(Long.valueOf(workerListRequest.getStreetId()));
}
List<WorkerArea> workerAreaList = workerAreaService.getWorkerAreaList(workerArea);
workerIdsByArea = workerAreaList.stream()
.map(WorkerArea::getWorkerId)
.collect(Collectors.toList());
}
List<Long> workerIdsByArea = workerAreaList.stream().map(WorkerArea::getWorkerId).collect(Collectors.toList());
// 查询满足技能条件的师傅技能记录
List<Long> workerIdsByCategory = new ArrayList<>();
WorkerGoodsCategory workerGoodsCategory = new WorkerGoodsCategory();
if(workerListRequest.getGoodsCategoryId() != null){
workerGoodsCategory.setGoodsCategoryId(workerListRequest.getGoodsCategoryId());
}
// 如果选择了上级类目但未选择最终类目,则查询该类目下所有子类目
if(StringUtils.isNotEmpty(workerListRequest.getCategoryLevel1())
&& StringUtils.isEmpty(workerListRequest.getCategoryLevel2()) && workerListRequest.getGoodsCategoryId() == null) {
// 1. 先查找二级类目
GoodsCategory param = new GoodsCategory();
param.setParentCategoryId(Long.valueOf(workerListRequest.getCategoryLevel1()));
List<GoodsCategory> secondCategories = goodsCategoryService.selectGoodsCategoryList(param);
// 2. 用二级类目查找三级类目
List<String> categoryIds = new ArrayList<>();
for (GoodsCategory secondCategory : secondCategories) {
param.setParentCategoryId(secondCategory.getGoodsCategoryId());
List<GoodsCategory> thirdCategories = goodsCategoryService.selectGoodsCategoryList(param);
categoryIds.addAll(thirdCategories.stream()
.map(x->x.getGoodsCategoryId().toString())
.collect(Collectors.toList()));
}
workerGoodsCategory.setCategoryIds(categoryIds);
}
// 如果选择了二级类目但未选择三级类目
else if(StringUtils.isNotEmpty(workerListRequest.getCategoryLevel2())
&& workerListRequest.getGoodsCategoryId() == null) {
GoodsCategory param = new GoodsCategory();
param.setParentCategoryId(Long.valueOf(workerListRequest.getCategoryLevel2()));
List<GoodsCategory> subCategories = goodsCategoryService.selectGoodsCategoryList(param);
List<String> categoryIds = subCategories.stream()
.map(x->x.getGoodsCategoryId().toString())
.collect(Collectors.toList());
workerGoodsCategory.setCategoryIds(categoryIds);
}
if(CollectionUtils.isNotEmpty(workerGoodsCategory.getCategoryIds()) || workerGoodsCategory.getGoodsCategoryId() != null){
List<WorkerGoodsCategory> workerGoodsCategoryList = workerGoodsCategoryService.getWorkerGoodsCategory(workerGoodsCategory);
workerIdsByCategory = workerGoodsCategoryList.stream()
.map(WorkerGoodsCategory::getWorkerId)
.collect(Collectors.toList());
}
List<Long> workerIdsByCategory = workerGoodsCategoryList.stream().map(WorkerGoodsCategory::getWorkerId).collect(Collectors.toList());
// 两个list中的workerid取交集
List<Long> resWorkerIds = new ArrayList<>();
if(!workerIdsByArea.isEmpty() && !workerIdsByCategory.isEmpty()) {
resWorkerIds.addAll(CollectionUtils.intersection(workerIdsByArea, workerIdsByCategory));
} else if(!workerIdsByArea.isEmpty()) {
resWorkerIds.addAll(workerIdsByArea);
} else if(!workerIdsByCategory.isEmpty()) {
resWorkerIds.addAll(workerIdsByCategory);
}
List<Long> resWorkerIds = new ArrayList<>(CollectionUtils.intersection(workerIdsByArea, workerIdsByCategory));
if (!resWorkerIds.isEmpty() ||
workerListRequest.getAreaId() != null ||
workerListRequest.getGoodsCategoryId() != null) {
// 有查询条件但无匹配结果时直接返回空列表
if(resWorkerIds.isEmpty()) {
if (CollectionUtils.isEmpty(resWorkerIds)) {
// 交集不存在的情况直接返回空list
return getDataTable(resList);
}
}
startPage();
Worker worker = new Worker();
worker.setWorkerIds(CollectionUtils.isNotEmpty(resWorkerIds) ? resWorkerIds : null);
worker.setKeyWords(workerListRequest.getWorkerName());
if(StringUtils.isNotEmpty(workerListRequest.getWorkerPhone())){
worker.setPhone(workerListRequest.getWorkerPhone());
}
if(this.getSysUser().getDept().getParentId() != 101){
worker.setDeptId(this.getSysUser().getDept().getParentId());
}
worker.setName(workerListRequest.getWorkerName());
List<Worker> list = workerService.getWorkList(worker);
TableDataInfo dataTable = getDataTable(list);
list.forEach(w -> {
Goods goods = new Goods();
goods.setWorkerId(w.getWorkerId());
@ -254,18 +161,13 @@ public class WorkerController extends BaseController {
workerListResponse.setGoodsCategories(workerGoodsCategoryService.getByWorker(w.getWorkerId()));
workerListResponse.setSpecialSkills(specialSkillService.getByWorker(w.getWorkerId()));
resList.add(workerListResponse);
});
TableDataInfo rspData = new TableDataInfo();
rspData.setCode(0);
rspData.setRows(resList);
rspData.setTotal(dataTable.getTotal());
return rspData;
} catch (Exception e) {
e.printStackTrace();
logger.error(ExceptionUtil.getExceptionMessage(e));
return getDataTable(new ArrayList<>());
}
return getDataTable(resList);
}
@PostMapping("/app/list")
@ -336,7 +238,6 @@ public class WorkerController extends BaseController {
startPage();
// worker.setWorkerIds(CollectionUtils.isNotEmpty(resWorkerIds) ? resWorkerIds : null);
worker.setName(workerListRequest.getWorkerName());
worker.setStatus(0);
List<Worker> list = workerService.getWorkList(worker);
list.forEach(w -> {
Goods goods = new Goods();
@ -351,12 +252,7 @@ public class WorkerController extends BaseController {
setDistrictIds(worker.getDistrictIds());
}}));
} else {
List<WorkerArea> workerAreas = workerAreaService.getByWorker(w.getWorkerId());
if(workerAreas.size() > 10){
workerListResponse.setWorkerAreas(workerAreas.subList(0,10));
}else {
workerListResponse.setWorkerAreas(workerAreas);
}
workerListResponse.setWorkerAreas(workerAreaService.getByWorker(w.getWorkerId()));
}
workerListResponse.setGoodsCategories(workerGoodsCategoryService.getByWorker(w.getWorkerId()));
workerListResponse.setSpecialSkills(specialSkillService.getByWorker(w.getWorkerId()));
@ -421,106 +317,19 @@ public class WorkerController extends BaseController {
}
}
@PostMapping("/changeLoginStatus")
@ResponseBody
public AjaxResult changeLoginStatus(Worker worker){
try {
workerService.updateWorker(worker);
return AjaxResult.success("登录状态修改成功");
}catch (Exception e){
logger.error(ExceptionUtil.getExceptionMessage(e));
return AjaxResult.error(e.getMessage());
}
}
@PostMapping("/settled")
@ResponseBody
@Transactional(rollbackFor = Exception.class)
public AjaxResult settled(@RequestBody WorkerSettledRequest request) {
// 入驻服务区域信息持久化类型1
workerAreaService.updateWorkerAreaByType(request.getWorkerId(), request.getWorkerAreas(), 1);
// 入驻商品区域信息持久化类型2
workerAreaService.updateWorkerAreaByType(request.getWorkerId(), request.getWorkerGoodsAreas(), 2);
// 入驻服务类目信息持久化类型1
if (request.getServiceCategories() != null && !request.getServiceCategories().isEmpty()) {
// 使用对象数组方式
workerGoodsCategoryService.updateWorkerGoodsCategoryByType(request.getWorkerId(), request.getServiceCategories(), 1);
} else if (request.getServiceCategoryIds() != null && !request.getServiceCategoryIds().isEmpty()) {
// 使用ID数组方式兼容旧版本
List<WorkerGoodsCategory> serviceCategories = request.getServiceCategoryIds().stream()
.map(id -> {
WorkerGoodsCategory category = new WorkerGoodsCategory();
category.setGoodsCategoryId(id);
return category;
}).collect(Collectors.toList());
workerGoodsCategoryService.updateWorkerGoodsCategoryByType(request.getWorkerId(), serviceCategories, 1);
}
// 入驻商品类目信息持久化类型2
if (request.getGoodsCategories() != null && !request.getGoodsCategories().isEmpty()) {
// 使用对象数组方式
workerGoodsCategoryService.updateWorkerGoodsCategoryByType(request.getWorkerId(), request.getGoodsCategories(), 2);
} else if (request.getGoodsCategoryIds() != null && !request.getGoodsCategoryIds().isEmpty()) {
// 使用ID数组方式兼容旧版本
List<WorkerGoodsCategory> goodsCategories = request.getGoodsCategoryIds().stream()
.map(id -> {
WorkerGoodsCategory category = new WorkerGoodsCategory();
category.setGoodsCategoryId(id);
return category;
}).collect(Collectors.toList());
workerGoodsCategoryService.updateWorkerGoodsCategoryByType(request.getWorkerId(), goodsCategories, 2);
}
// 入驻区域信息持久化
workerAreaService.updateWorkerServArea(request.getWorkerId(), request.getWorkerAreas());
// 入驻服务品类信息持久化
workerGoodsCategoryService.updateWorkerGoodsCategory(request.getWorkerId(), request.getGoodsCategories());
// 更新师傅入驻类型为服务商
Worker worker = new Worker();
worker.setWorkerId(request.getWorkerId());
worker.setType(WorkerType.SP.getCode());
workerService.updateWorker(worker);
return AjaxResult.success("保存成功");
}
/**
* 通过师傅ID获取师傅详情
* @param workerId 师傅ID
* @return 师傅实体对象
*/
@GetMapping("/detail/{workerId}")
@ResponseBody
public AjaxResult getWorkerDetailById(@PathVariable("workerId") Long workerId) {
try {
// 参数校验
if (workerId == null) {
return AjaxResult.error("师傅ID不能为空");
}
// 查询师傅基本信息
Worker worker = workerService.selectById(workerId);
if (worker == null) {
return AjaxResult.error("师傅不存在");
}
return AjaxResult.success(worker);
} catch (Exception e) {
logger.error("获取师傅详情失败: " + ExceptionUtil.getExceptionMessage(e));
return AjaxResult.error("获取师傅详情失败: " + e.getMessage());
}
}
/**
* 删除师傅软删除
*/
@RequiresPermissions("worker:worker:remove")
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids) {
try {
return toAjax(workerService.deleteWorkerByIds(ids));
} catch (Exception e) {
logger.error(ExceptionUtil.getExceptionMessage(e));
return AjaxResult.error("删除失败: " + e.getMessage());
}
}
}

View File

@ -1,14 +1,11 @@
package com.ghy.web.controller.worker;
import com.ghy.common.constant.Constants;
import com.ghy.common.core.controller.BaseController;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.core.page.TableDataInfo;
import com.ghy.common.core.text.Convert;
import com.ghy.common.utils.StringUtils;
import com.ghy.goods.domain.GoodsCategory;
import com.ghy.goods.service.GoodsCategoryService;
import com.ghy.worker.domain.WorkerArea;
import com.ghy.worker.domain.WorkerGoodsCategory;
import com.ghy.worker.request.WorkerGoodsCategorySaveRequest;
import com.ghy.worker.service.WorkerGoodsCategoryService;
@ -16,7 +13,6 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
@ -32,7 +28,7 @@ import java.util.stream.Collectors;
@Slf4j
@Controller
@RequestMapping("worker/goods/category")
public class WorkerGoodsCategoryController extends BaseController {
public class WorkerGoodsCategoryController {
@Resource
private WorkerGoodsCategoryService workerGoodsCategoryService;
@ -40,51 +36,15 @@ public class WorkerGoodsCategoryController extends BaseController {
@Autowired
private GoodsCategoryService goodsCategoryService;
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(WorkerGoodsCategory workerGoodsCategory) {
startPage();
List<WorkerGoodsCategory> list = workerGoodsCategoryService.getByWorker(workerGoodsCategory.getWorkerId());
for (WorkerGoodsCategory item: list) {
List<String> nameList = new ArrayList<String>();
// 查询所有父级服务类目拼接服务名称
GoodsCategory goodsCategory = goodsCategoryService.selectById(item.getGoodsCategoryId());
while (goodsCategory.getParentCategoryId() != null) {
nameList.add(goodsCategory.getGoodsCategoryName());
goodsCategory = goodsCategoryService.selectById(goodsCategory.getParentCategoryId());
}
Collections.reverse(nameList);
item.setMergeName(StringUtils.join(nameList, Constants.JOIN_SYMBOL));
}
return getDataTable(list);
}
@GetMapping()
public String category(Long workerId, ModelMap mmap)
{
mmap.put("workerId", workerId);
return "worker/categoryDetail";
}
/**
* 查询某个师傅的所有服务类目
*
* @param workerId 师傅ID
* @param serviceType 服务类型1=服务, 2=商品不传则查询所有
*/
@GetMapping("worker")
@ResponseBody
public AjaxResult getByWorker(Long workerId, Integer serviceType) {
List<WorkerGoodsCategory> list;
if (serviceType != null) {
// 根据服务类型查询
list = workerGoodsCategoryService.getByWorkerIdAndType(workerId, serviceType);
} else {
// 查询所有类目保持向后兼容
list = workerGoodsCategoryService.getByWorker(workerId);
}
public AjaxResult getByWorker(Long workerId) {
List<WorkerGoodsCategory> list = workerGoodsCategoryService.getByWorker(workerId);
for (WorkerGoodsCategory item: list) {
List<String> nameList = new ArrayList<String>();
// 查询所有父级服务类目拼接服务名称
@ -98,75 +58,14 @@ public class WorkerGoodsCategoryController extends BaseController {
}
return AjaxResult.success(list);
}
/**
* 查询某个师傅的服务类目类型1
*
* @param workerId 师傅ID
*/
@GetMapping("worker/service")
@ResponseBody
public AjaxResult getServiceCategoriesByWorker(Long workerId) {
List<WorkerGoodsCategory> list = workerGoodsCategoryService.getByWorkerIdAndType(workerId, 1);
for (WorkerGoodsCategory item: list) {
List<String> nameList = new ArrayList<String>();
// 查询所有父级服务类目拼接服务名称
GoodsCategory goodsCategory = goodsCategoryService.selectById(item.getGoodsCategoryId());
while (goodsCategory.getParentCategoryId() != null) {
nameList.add(goodsCategory.getGoodsCategoryName());
goodsCategory = goodsCategoryService.selectById(goodsCategory.getParentCategoryId());
}
Collections.reverse(nameList);
item.setMergeName(StringUtils.join(nameList, Constants.JOIN_SYMBOL));
}
return AjaxResult.success(list);
}
/**
* 查询某个师傅的商品类目类型2
*
* @param workerId 师傅ID
*/
@GetMapping("worker/goods")
@ResponseBody
public AjaxResult getGoodsCategoriesByWorker(Long workerId) {
List<WorkerGoodsCategory> list = workerGoodsCategoryService.getByWorkerIdAndType(workerId, 2);
for (WorkerGoodsCategory item: list) {
List<String> nameList = new ArrayList<String>();
// 查询所有父级服务类目拼接服务名称
GoodsCategory goodsCategory = goodsCategoryService.selectById(item.getGoodsCategoryId());
while (goodsCategory.getParentCategoryId() != null) {
nameList.add(goodsCategory.getGoodsCategoryName());
goodsCategory = goodsCategoryService.selectById(goodsCategory.getParentCategoryId());
}
Collections.reverse(nameList);
item.setMergeName(StringUtils.join(nameList, Constants.JOIN_SYMBOL));
}
return AjaxResult.success(list);
}
@GetMapping("worker/edit")
@ResponseBody
public AjaxResult getEditWorker(Long workerId, Integer type) {
public AjaxResult getEditWorker(Long workerId) {
Map<Long, List<String>> twoMap = new HashMap<>();
// 根据类型查询对应的商品分类数据
List<WorkerGoodsCategory> list;
if (Integer.valueOf(1).equals(type)) {
// 服务类型查询服务商品分类
list = workerGoodsCategoryService.getByWorkerIdAndType(workerId, 1);
} else if (Integer.valueOf(2).equals(type)) {
// 商品类型查询商品分类
list = workerGoodsCategoryService.getByWorkerIdAndType(workerId, 2);
} else {
// 不传类型查询所有商品分类
list = workerGoodsCategoryService.getByWorker(workerId);
}
List<WorkerGoodsCategory> list = workerGoodsCategoryService.getByWorker(workerId);
if(CollectionUtils.isEmpty(list)){
return AjaxResult.success();
}
for (WorkerGoodsCategory item: list) {
List<String> ids;
GoodsCategory goodsCategory = goodsCategoryService.selectById(item.getGoodsCategoryId());
@ -178,7 +77,6 @@ public class WorkerGoodsCategoryController extends BaseController {
ids.add(String.valueOf(goodsCategory.getGoodsCategoryId()));
twoMap.put(goodsCategory.getParentCategoryId(), ids);
}
List<WorkerGoodsCategory> result = new ArrayList<>();
for (Map.Entry<Long, List<String>> longListEntry : twoMap.entrySet()) {
WorkerGoodsCategory model = new WorkerGoodsCategory();

View File

@ -1,38 +0,0 @@
package com.ghy.web.core.config;
import com.aliyun.dytnsapi20200217.Client;
import com.aliyun.teaopenapi.models.Config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
public class AliApiConfig {
@Value("${aliyun.accessKey}")
private String accessKey;
@Value("${aliyun.accessSecret}")
private String accessSecret;
@Value("${aliyun.endpoint}")
private String endpoint;
@Value("${aliyun.authCode}")
private String authCode;
@Bean
public Client createClient() throws Exception {
// 建议使用更安全的 STS 方式更多鉴权访问方式请参见https://help.aliyun.com/document_detail/378657.html
Config config = new Config()
// 必填请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID
.setAccessKeyId(accessKey)
// 必填请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET
.setAccessKeySecret(accessSecret)
.setEndpoint(endpoint);
return new Client(config);
}
}

View File

@ -41,7 +41,7 @@ public class SwaggerConfig
// 扫描所有有注解的api用这种方式更灵活
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
// 扫描指定包中的swagger注解
.apis(RequestHandlerSelectors.basePackage("com.ghy.web.controller.order"))
.apis(RequestHandlerSelectors.basePackage("com.ghy.web.controller.tool"))
// 扫描所有 .apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();

View File

@ -1,14 +0,0 @@
package com.ghy.web.pojo.vo;
import lombok.Data;
@Data
public class CertNoTwoElementReq {
private Long workerId;
private String certNo;
private String certName;
}

View File

@ -1,23 +0,0 @@
package com.ghy.web.pojo.vo;
import lombok.Data;
@Data
public class InsuranceOrderEditReq {
private String requestNo;
private String channelCode = "NNDD0806QH";
private String sign;
private String orderNumber;
private String workName;
private String workerID;
private String shangmenTime;
private String shangmenNum;
}

View File

@ -1,36 +0,0 @@
package com.ghy.web.pojo.vo;
import lombok.Data;
import java.util.Date;
@Data
public class InsuranceOrderReq {
private String requestNo;
private String channelCode = "NNDD0806QH";
private String sign;
private String orderNumber;
private String orderProductType = "0002";
private String orderStatus = "1";
private String orderStartat;
private String orderEndat;
private String customerAddress;
private String customerPhone;
private String workName;
private String workerID;
}

View File

@ -8,7 +8,6 @@ import java.math.BigDecimal;
/**
* 改价请求实体
*
* @author clunt
*/
@Data
@ -22,10 +21,4 @@ public class OrderChangePriceRequest implements Serializable {
private Integer type;
private String remark;
private String urls;
private String fileNames;
private String reason;
}

View File

@ -29,13 +29,4 @@ public class OrderListRequest {
private Integer shelveStatus;
private Integer allSelfAssigned;
/**
* 是否超时 1= 0=
*/
private Integer timeout;
private Boolean needImgs = true;
private Integer orderType;
}

View File

@ -2,15 +2,10 @@ package com.ghy.web.pojo.vo;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ghy.common.annotation.Excel;
import com.ghy.goods.domain.Goods;
import com.ghy.goods.domain.GoodsArea;
import com.ghy.goods.domain.InsuranceManager;
import com.ghy.order.domain.AfterServiceRecord;
import com.ghy.payment.domain.FinancialChangeRecord;
import com.ghy.payment.domain.OrderTimeoutRecord;
import com.ghy.shop.domain.Shop;
import lombok.Data;
import java.math.BigDecimal;
@ -20,29 +15,16 @@ import java.util.List;
@Data
public class OrderListResponse {
// 商品品牌 -- 后台发单才有
private String goodsBrand;
// 商品规格 -- 后台发单才有
private String goodsSpecification;
private String totalName;
private String isCall;
private Long orderMasterId;
private String orderMasterCode;
private String originalOrderMasterCode;
private Long orderDetailId;
private String orderDetailCode;
private Long workerId;
private Long masterWorkerId;
private String workerName;
private String workerPhone;
@ -53,8 +35,6 @@ public class OrderListResponse {
private String masterCompanyName;
private String masterCompanyPhone;
private String customerName;
private String customerPhone;
@ -87,23 +67,14 @@ public class OrderListResponse {
private Integer orderStatus;
private String orderStatusName;
private Integer payStatus;
/**
* 退款支付状态0=未支付1=已支付
*/
private Integer refundPayStatus;
private Integer payType;
private BigDecimal totalMoney;
private BigDecimal payMoney;
private BigDecimal payAddMoney;
private BigDecimal finalRecvMoney;
private BigDecimal changeMoney;
@ -166,174 +137,4 @@ public class OrderListResponse {
* 提现到账时间 arrival_time
*/
private Date arrivalTime;
/**
* 是否超时 1= 0=
*/
private Integer timeout;
/**
* 超时扣款次数
*/
private Integer timeoutFineTimes;
/**
* 超时时间用于排序
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date timeoutTime;
private Integer afterTimeout;
private String orderMode;
/*是否合约订单*/
private String consultMode;
private Goods goods;
/*是否有保险id*/
private Long insuranceId;
private InsuranceManager insuranceManager;
private Long cityId;
/*街道id*/
private Long streetId;
private Long provinceId;
private String name;
private String phone;
private String provinceName;
private String cityName;
private String countryName;
private String streetName;
private Long countryId;
/**
* 是否为监控但
* */
private Boolean isMonitoredOrder;
private BigDecimal addMoney;
private String addMoneyRemark;
private BigDecimal paymentMoney;
/**
* 是否已派发服务订单0=未派发1=已派发
*/
private Integer hasServiceOrder;
/**
* 下单图片
*/
@Excel(name = "下单图片", cellType = Excel.ColumnType.STRING)
private String orderImages;
/**
* 是否发货到服务店0=1=
*/
@Excel(name = "是否发货到服务店", cellType = Excel.ColumnType.NUMERIC)
private Integer isDeliveryToStore;
/**
* 是否已开票0=1=
*/
@Excel(name = "是否已开票", cellType = Excel.ColumnType.NUMERIC, readConverterExp = "0=是,1=否")
private Integer isInvoiced;
/**
* 是否需要开票0=不需要1=需要
*/
@Excel(name = "是否需要开票", cellType = Excel.ColumnType.NUMERIC, readConverterExp = "0=不需要,1=需要")
private Integer isNeedBill;
/**
* 原师傅id转单前的师傅
*/
@Excel(name = "原师傅id", cellType = Excel.ColumnType.NUMERIC)
private Long originalWorkerId;
private Long serverGoodsId;
/**
* 服务店铺ID
*/
private Long serviceShopId;
private Date confirmStartTime;
private Integer deliveryType;
private Long goodsId;
/**
* 发货备注
*/
@Excel(name = "发货备注", cellType = Excel.ColumnType.STRING)
private String deliveryRemark;
/**
* 发货图片
*/
@Excel(name = "发货图片", cellType = Excel.ColumnType.STRING)
private String deliveryImages;
@Excel(name = "交货图片", cellType = Excel.ColumnType.STRING)
private String handoverImages;
@Excel(name = "交货备注", cellType = Excel.ColumnType.STRING)
private String handoverRemark;
/**
* 快递单号
*/
private String trackingNumber;
/**
* 分账倒计时结束时间
*/
@Excel(name = "分账倒计时结束时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date shareAccountCountdownEndTime;
/**
* 分账倒计时时长小时
*/
@Excel(name = "分账倒计时时长(小时)")
private Integer shareAccountCountdownDuration;
private Shop shop;
private Shop serviceShop;
private Long goodsOrderMasterId;
/**
* 是否已撤销服务主单0=未撤销1=已撤销
*/
@Excel(name = "是否已撤销服务主单", cellType = Excel.ColumnType.NUMERIC, readConverterExp = "0=未撤销,1=已撤销")
private Integer serviceCancelled;
/**
* 是否显示售后记录0=不显示1=显示
*/
private Integer showAfterServiceRecord = 0;
@Excel(name = "是否显示在监控单", cellType = Excel.ColumnType.NUMERIC, readConverterExp = "0=不显示,1=显示在监控单")
private Integer showInMonitor;
@Excel(name = "售后状态0-无售后1-售后纠纷,2-售后已完成,3-售后已取消")
private Integer afterPlatformServiceStatus;
}

View File

@ -55,83 +55,4 @@ public class OrderStandardDetail {
private Boolean isOverTime;
private BigDecimal serverMoney;
/**
* draw_cash_status
* 0 未分账
* 1 已分账
* 2 已到账
* -1 提现失败
*/
private Integer drawCashStatus;
/**
* 发起提现时间 draw_cash_time
*/
private Date drawCashTime;
/**
* 是否超时 1= 0=
*/
private Integer timeout;
/**
* 超时扣款次数
*/
private Integer timeoutFineTimes;
private Integer afterTimeout;
private BigDecimal addMoney;
/**
* 退单原因
*/
private String returnReason;
/**
* 退单原因详情
*/
private String returnReasonDetail;
/**
* 退单图片
*/
private String returnImages;
/**
* 发货类型 - 订单的发货方式
*/
private Integer deliveryType;
/**
* 发货备注 - 发货相关备注信息
*/
private String deliveryRemark;
/**
* 发货图片 - 发货凭证图片
*/
private String deliveryImages;
/**
* 快递单号 - 物流跟踪单号
*/
private String trackingNumber;
private String handoverImages;
private String handoverRemark;
private String orderImages;
//= "售后状态0-无售后1-售后纠纷,2-售后已完成,3-售后已取消"
private Integer afterPlatformServiceStatus;
private Integer payStatus;
private Integer refundPayStatus;
}

View File

@ -11,8 +11,4 @@ import lombok.Data;
@Data
public class OrderStatisticsRequest {
private Long workerId;
private Long deptId;
private Integer orderType;
}

View File

@ -1,54 +0,0 @@
package com.ghy.web.pojo.vo;
import com.ghy.system.domain.SysGlobalConfig;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.Accessors;
import org.springframework.beans.BeanUtils;
/**
* @Author 但星霖
* @Date 2023-03-20 203716
* 说明系统配置返回vo
*/
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@Schema(description = "系统配置请求返回vo")
public class SysGlobalConfigRequestVO {
@Schema(description = "配置项主键ID")
private Long id;
@Schema(description = "配置项名称")
private String name;
@Schema(description = "配置项内容json串")
private String content;
@Schema(description = "排序号")
private Integer sort;
@Schema(description = "描述")
private String describe;
@Schema(description = "配置类型")
private Integer type;
@Schema(description = "数据内容类型")
private Integer dataType;
@Schema(description = "单位")
private String configUnit;
public static SysGlobalConfig toModel(SysGlobalConfigRequestVO vo){
SysGlobalConfig sysConfig = new SysGlobalConfig();
BeanUtils.copyProperties(vo, sysConfig);
return sysConfig;
}
}

View File

@ -1,116 +0,0 @@
package com.ghy.web.pojo.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.ghy.common.annotation.SysConstants;
import com.ghy.common.enums.SysGlobalConfigDataTypeEnum;
import com.ghy.common.enums.SysGlobalConfigEnum;
import com.ghy.common.utils.ObjectVerifyUtils;
import com.ghy.system.domain.SysGlobalConfig;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.Accessors;
import org.springframework.beans.BeanUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @Author 但星霖
* @Date 2023-03-20 203716
* 说明系统配置返回vo
*/
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@Schema(description = "系统配置返回vo")
public class SysGlobalConfigResponseVO {
@Schema(description = "配置项主键ID")
private Long id;
@Schema(description = "配置项名称")
private String name;
@Schema(description = "配置项内容json串")
private String content;
@Schema(description = "排序号")
private Integer sort;
@Schema(description = "描述")
private String describe;
@Schema(description = "配置类型")
private Integer type;
@Schema(description = "配置类型枚举")
private SysGlobalConfigEnum typeEnum;
@Schema(description = "配置类型Desc")
private String typeEnumDesc;
@Schema(description = "数据内容类型")
private Integer dataType;
@Schema(description = "数据内容类型")
private SysGlobalConfigDataTypeEnum dataTypeEnum;
@Schema(description = "数据内容类型")
private String dataTypeEnumDesc;
@Schema(description = "单位")
private String configUnit;
@JsonInclude(value = JsonInclude.Include.NON_NULL)
@JsonFormat(pattern = SysConstants.DATE_TIME_FORMAT, locale = "zh", timezone = "GMT+8")
@Schema(description = "创建时间")
private Date createTime;
@JsonInclude(value = JsonInclude.Include.NON_NULL)
@JsonFormat(pattern = SysConstants.DATE_TIME_FORMAT, locale = "zh", timezone = "GMT+8")
@Schema(description = "更新时间")
private Date updateTime;
public static SysGlobalConfigResponseVO toVo(SysGlobalConfig model) {
if (ObjectVerifyUtils.isNull(model)) {
return null;
}
SysGlobalConfigResponseVO vo = new SysGlobalConfigResponseVO();
BeanUtils.copyProperties(model, vo);
// 配置类型
if (ObjectVerifyUtils.isNotNull(model.getType())) {
SysGlobalConfigEnum configEnum = SysGlobalConfigEnum.parse(model.getType());
if (ObjectVerifyUtils.isNotNull(configEnum)) {
vo.setTypeEnum(configEnum);
vo.setTypeEnumDesc(configEnum.desc());
}
}
// 配置类型数据类型
if (ObjectVerifyUtils.isNotNull(model.getDataType())) {
SysGlobalConfigDataTypeEnum sysConfigDataTypeEnum = SysGlobalConfigDataTypeEnum.parse(model.getDataType());
if (ObjectVerifyUtils.isNotNull(sysConfigDataTypeEnum)) {
vo.setDataTypeEnum(sysConfigDataTypeEnum);
vo.setDataTypeEnumDesc(sysConfigDataTypeEnum.desc());
}
}
// 时间类单独处理
vo.setCreateTime(ObjectVerifyUtils.isNotNull(model.getCreateTime()) ? new Date(model.getCreateTime()) : null);
vo.setUpdateTime(ObjectVerifyUtils.isNotNull(model.getUpdateTime()) ? new Date(model.getUpdateTime()) : null);
return vo;
}
public static List<SysGlobalConfigResponseVO> toVoList(List<SysGlobalConfig> sysConfigList) {
List<SysGlobalConfigResponseVO> voList = new ArrayList<>();
if (ObjectVerifyUtils.isNotEmpty(sysConfigList)) {
sysConfigList.forEach(sysConfig -> voList.add(toVo(sysConfig)));
}
return voList;
}
}

View File

@ -1,77 +0,0 @@
package com.ghy.web.pojo.vo;
import com.ghy.common.annotation.Excel;
import lombok.Data;
@Data
public class SysOrderRequest {
@Excel(name = "seq")
private String seq;
@Excel(name = "category")
private String category;
@Excel(name = "lastCategory")
private String lastCategory;
@Excel(name = "brand")
private String brand;
@Excel(name = "date")
private String date;
@Excel(name = "time")
private String time;
@Excel(name = "mode")
private String mode;
@Excel(name = "num")
private String num;
@Excel(name = "price")
private String price;
@Excel(name = "name")
private String name;
@Excel(name = "phone")
private String phone;
@Excel(name = "address")
private String address;
@Excel(name = "remark")
private String remark;
@Excel(name = "money")
private String money;
@Excel(name = "award")
private String award;
@Excel(name = "infoMoney")
private String infoMoney;
@Excel(name = "url")
private String url;
@Excel(name = "logistics")
private String logistics;
@Excel(name = "needHll")
private String needHll;
@Excel(name = "bh")
private String bh;
@Excel(name = "floor")
private String floor;
@Excel(name = "floorUp")
private String floorUp;
@Excel(name = "bhry")
private String bhry;
}

View File

@ -1,6 +1,5 @@
package com.ghy.web.pojo.vo;
import com.ghy.common.core.domain.BaseEntity;
import com.ghy.worker.domain.Worker;
import lombok.Data;
@ -11,7 +10,7 @@ import java.util.List;
* @date : 2022-06-24 17:38
*/
@Data
public class WorkerListRequest extends BaseEntity {
public class WorkerListRequest {
private Long areaId;
private List<Long> areaIds;
@ -20,25 +19,9 @@ public class WorkerListRequest extends BaseEntity {
private String workerName;
private String workerPhone;
private Long workerId;
private Long exceptParentAreaId;
private boolean justShowCurWorkerArea;
private String keyWords;
private String provinceId;
private String cityId;
private String districtId;
private String streetId;
private String categoryLevel1;
private String categoryLevel2;
}

View File

@ -21,21 +21,9 @@ public class WorkerSettledRequest {
// 入驻区域
private List<WorkerArea> workerAreas;
// 入驻商品区域
private List<WorkerArea> workerGoodsAreas;
// 入驻服务类目
private List<WorkerGoodsCategory> serviceCategories;
// 入驻商品类目
// 服务品类
private List<WorkerGoodsCategory> goodsCategories;
// 入驻服务类目ID列表兼容旧版本
private List<Long> serviceCategoryIds;
// 入驻商品类目ID列表兼容旧版本
private List<Long> goodsCategoryIds;
// 特殊技能
// private List<WorkerSpecialSkill> specialSkills;
}

View File

@ -1,14 +0,0 @@
package com.ghy.web.service;
import com.ghy.web.pojo.vo.CertNoTwoElementReq;
import org.springframework.web.bind.annotation.RequestBody;
/**
* <p>阿里云api合集,二次包装在服务内</p>
* @author clunt
*/
public interface AliCloudService {
void certNoTwoElementVerification(@RequestBody CertNoTwoElementReq certNoTwoElementReq) throws Exception;
}

View File

@ -1,13 +0,0 @@
package com.ghy.web.service;
import com.ghy.order.domain.OrderDetailInsuranceUser;
public interface InsuranceService {
void clockInsurance(Long orderDetailId) throws Exception;
void orderInsurance(String orderCode) throws Exception;
void editInsurance(OrderDetailInsuranceUser orderDetailInsuranceUser) throws Exception ;
}

View File

@ -1,38 +0,0 @@
package com.ghy.web.service.impl;
import cn.hutool.core.lang.Assert;
import cn.hutool.json.JSONUtil;
import com.aliyun.dytnsapi20200217.Client;
import com.aliyun.dytnsapi20200217.models.CertNoTwoElementVerificationRequest;
import com.aliyun.dytnsapi20200217.models.CertNoTwoElementVerificationResponse;
import com.ghy.web.core.config.AliApiConfig;
import com.ghy.web.pojo.vo.CertNoTwoElementReq;
import com.ghy.web.service.AliCloudService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class AliCloudServiceImpl implements AliCloudService {
private final AliApiConfig aliApiConfig;
@Override
public void certNoTwoElementVerification(CertNoTwoElementReq certNoTwoElementReq) throws Exception{
// 校验是否是历史记录
Client client = aliApiConfig.createClient();
CertNoTwoElementVerificationRequest request = new CertNoTwoElementVerificationRequest();
request.setAuthCode(aliApiConfig.getAuthCode());
request.setCertNo(certNoTwoElementReq.getCertNo());
request.setCertName(certNoTwoElementReq.getCertName());
log.info("调用身份证二要素校验接口,入参:{}", certNoTwoElementReq);
CertNoTwoElementVerificationResponse response =client.certNoTwoElementVerification(request);
log.info("调用身份证二要素校验接口,响应:{}", JSONUtil.toJsonStr(response.getBody()));
Assert.isTrue("OK".equals(response.getBody().getCode()), Exception::new);
Assert.isTrue("1".equals(response.getBody().getData().getIsConsistent()), "身份二要素验证失败!");
}
}

View File

@ -1,153 +0,0 @@
package com.ghy.web.service.impl;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.ghy.common.utils.security.Md5Utils;
import com.ghy.customer.domain.CustomerAddress;
import com.ghy.customer.service.CustomerAddressService;
import com.ghy.order.domain.OrderDetail;
import com.ghy.order.domain.OrderDetailInsuranceUser;
import com.ghy.order.domain.OrderMaster;
import com.ghy.order.service.IOrderDetailInsuranceUserService;
import com.ghy.order.service.OrderDetailService;
import com.ghy.order.service.OrderMasterService;
import com.ghy.web.pojo.vo.CertNoTwoElementReq;
import com.ghy.web.pojo.vo.InsuranceOrderEditReq;
import com.ghy.web.pojo.vo.InsuranceOrderReq;
import com.ghy.web.service.InsuranceService;
import com.ghy.worker.domain.Worker;
import com.ghy.worker.domain.WorkerCertification;
import com.ghy.worker.service.IWorkerCertificationService;
import com.ghy.worker.service.WorkerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.Date;
import java.util.List;
@Slf4j
@Service
public class InsuranceServiceImpl implements InsuranceService {
private final static String Key = "96ndsd26k25jm";
private final static String baseUrl = "https://pre-hbhp-xianding.hzins.com/api/external/";
@Autowired
private OrderMasterService orderMasterService;
@Autowired
private CustomerAddressService customerAddressService;
@Autowired
private WorkerService workerService;
@Autowired
private OrderDetailService orderDetailService;
@Autowired
private IOrderDetailInsuranceUserService orderDetailInsuranceUserService;
@Override
public void orderInsurance(String orderCode) throws Exception{
InsuranceOrderReq req = new InsuranceOrderReq();
OrderMaster master = orderMasterService.selectByCode(orderCode);
if(master.getInsuranceId() == null){
return;
}
req.setOrderNumber(master.getCode());
req.setRequestNo(master.getCode() + System.currentTimeMillis());
req.setSign(Md5Utils.hash(req.getRequestNo() + req.getChannelCode() + Key));
// 查询客户地址信息
CustomerAddress customerAddress = customerAddressService.selectByCustomerAddressId(master.getAddressId());
req.setCustomerAddress(customerAddress.getAddress());
req.setCustomerPhone(customerAddress.getPhone());
// 查师傅信息
Worker worker = workerService.selectById(master.getWorkerId());
CertNoTwoElementReq certNoTwoElementReq = JSONUtil.toBean(worker.getRemark(), CertNoTwoElementReq.class);
req.setWorkerID(certNoTwoElementReq.getCertNo());
req.setWorkName(certNoTwoElementReq.getCertName());
req.setOrderStartat(DateUtil.format(DateUtil.offset(new Date(), DateField.SECOND, 30), DatePattern.NORM_DATETIME_PATTERN));
req.setOrderEndat(DateUtil.format(DateUtil.offset(new Date(), DateField.DAY_OF_YEAR, 30),DatePattern.NORM_DATETIME_PATTERN));
log.info("调用保险请求url:{},内容:{}", baseUrl+"/platInterface/order", JSONUtil.toJsonStr(req));
String result = HttpUtil.post(baseUrl+"/platInterface/order", JSONUtil.toJsonStr(req));
log.info("调用保险返回内容:{}", result);
if(!"1".equals(JSONObject.parseObject(result).getString("code")) && !JSONObject.parseObject(result).getString("msg").contains("已存在该工单")){
throw new Exception(JSONObject.parseObject(result).getString("msg"));
}
}
@Override
public void editInsurance(OrderDetailInsuranceUser orderDetailInsuranceUser) throws Exception {
// 查询子单
OrderDetail detail = orderDetailService.selectById(orderDetailInsuranceUser.getOrderDetailId());
// 查询主单
OrderMaster master = orderMasterService.selectById(detail.getOrderMasterId());
// 查师傅信息
Worker worker = workerService.selectById(master.getWorkerId());
CertNoTwoElementReq certNoTwoElementReq = JSONUtil.toBean(worker.getRemark(), CertNoTwoElementReq.class);
// 查询主单下的所有子单
List<OrderDetail> detailList = orderDetailService.selectByOrderMasterId(detail.getOrderMasterId());
StringBuilder workerName = new StringBuilder();
StringBuilder workerId = new StringBuilder();
// 拼上主单信息
workerName.append(certNoTwoElementReq.getCertName());
workerId.append(certNoTwoElementReq.getCertNo());
detailList.forEach(model->{
OrderDetailInsuranceUser param = new OrderDetailInsuranceUser();
param.setOrderDetailId(model.getId());
List<OrderDetailInsuranceUser> users = orderDetailInsuranceUserService.selectOrderDetailInsuranceUserList(param);
if(!CollectionUtils.isEmpty(users)){
users.forEach(user->{
workerName.append(",").append(user.getName());
workerId.append(",").append(user.getIdCardNum());
});
}
});
// 再拼上 现在要加入的师傅的信息
workerName.append(",").append(orderDetailInsuranceUser.getName());
workerId.append(",").append(orderDetailInsuranceUser.getIdCardNum());
InsuranceOrderEditReq editReq = new InsuranceOrderEditReq();
editReq.setOrderNumber(master.getCode());
editReq.setRequestNo(master.getCode() + System.currentTimeMillis());
editReq.setSign(Md5Utils.hash(editReq.getRequestNo() + editReq.getChannelCode() + Key));
editReq.setOrderNumber(master.getCode());
editReq.setWorkName(workerName.toString());
editReq.setWorkerID(workerId.toString());
log.info("调用保险请求url:{},内容:{}", baseUrl+"/platInterface/updateOrder", JSONUtil.toJsonStr(editReq));
String result = HttpUtil.post(baseUrl+"/platInterface/updateOrder", JSONUtil.toJsonStr(editReq));
log.info("调用保险返回内容:{}", result);
if(!"1".equals(JSONObject.parseObject(result).getString("code"))){
throw new Exception(JSONObject.parseObject(result).getString("msg"));
}
}
@Override
public void clockInsurance(Long orderDetailId) throws Exception {
// 查询子单
OrderDetail detail = orderDetailService.selectById(orderDetailId);
// 查询主单
OrderMaster master = orderMasterService.selectById(detail.getOrderMasterId());
if(master.getInsuranceId() != null){
InsuranceOrderEditReq editReq = new InsuranceOrderEditReq();
editReq.setOrderNumber(master.getCode());
editReq.setRequestNo(master.getCode() + System.currentTimeMillis());
editReq.setSign(Md5Utils.hash(editReq.getRequestNo() + editReq.getChannelCode() + Key));
editReq.setOrderNumber(master.getCode());
editReq.setShangmenTime(DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN));
editReq.setShangmenNum("1");
log.info("调用保险请求url:{},内容:{}", baseUrl+"/platInterface/service", JSONUtil.toJsonStr(editReq));
String result = HttpUtil.post(baseUrl+"/platInterface/service", JSONUtil.toJsonStr(editReq));
log.info("调用保险返回内容:{}", result);
if(!"1".equals(JSONObject.parseObject(result).getString("code"))){
throw new Exception(JSONObject.parseObject(result).getString("msg"));
}
}
}
}

View File

@ -3,16 +3,10 @@ package com.ghy.web.timer;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ghy.common.adapay.model.AdapayStatusEnum;
import com.ghy.common.enums.AdapayOrderType;
import com.ghy.common.utils.AdapayUtils;
import com.ghy.customer.domain.CustomerBank;
import com.ghy.customer.service.CustomerBankService;
import com.ghy.order.service.OrderDetailService;
import com.ghy.payment.domain.DrawCashRecord;
import com.ghy.payment.mapper.DrawCashRecordMapper;
import com.ghy.payment.service.AdapayService;
import com.ghy.worker.domain.WorkerBank;
import com.ghy.worker.service.WorkerBankService;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@ -23,7 +17,6 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
@ -39,82 +32,10 @@ public class AdapaySyncTimer {
@Resource
private AdapayService adapayService;
@Resource
private WorkerBankService workerBankService;
@Resource
private CustomerBankService customerBankService;
@Resource
private OrderDetailService orderDetailService;
@Resource
private DrawCashRecordMapper drawCashRecordMapper;
/**
* 补偿提现定时器
* 某些订单分账成功但是提现失败需要在这里为它重新发起提现
*/
@Scheduled(fixedRate = 5 * 60 * 1000L)
public void autoDrawCash() {
List<WorkerBank> workerBanks = workerBankService.select(new WorkerBank());
for (WorkerBank workerBank : workerBanks) {
Long deptId = workerBank.getDeptId();
String memberId = workerBank.getAdapayMemberId();
String settleAccountId = workerBank.getSettleAccountId();
if (deptId == null || StringUtils.isBlank(memberId) || StringUtils.isBlank(settleAccountId)) {
continue;
}
try {
JSONObject accountBalance = adapayService.queryAccountBalance(deptId, memberId, settleAccountId, "01");
if (AdapayStatusEnum.succeeded.code.equals(accountBalance.getString("status"))) {
// 可提现金额
String avlBalance = accountBalance.getString("avl_balance");
if (BigDecimal.ZERO.compareTo(new BigDecimal(avlBalance)) > -1) {
continue;
}
// 提现
log.info("Worker[{},{}]开始提现: avlBalance={}", workerBank.getWorkerId(), workerBank.getName(), avlBalance);
String orderNo = AdapayUtils.createOrderNo(AdapayOrderType.DRAW_CASH);
JSONObject drawCash = adapayService.drawCash(deptId, orderNo, "T1", avlBalance, memberId, "提现", null);
log.info("Worker[{},{}]提现结果: {}", workerBank.getWorkerId(), workerBank.getName(), drawCash.toJSONString());
} else {
log.error("Worker[{},{}]查询账户余额失败: {}", workerBank.getWorkerId(), workerBank.getName(), accountBalance.toJSONString());
}
} catch (BaseAdaPayException e) {
log.error(e.getMessage(), e);
}
}
List<CustomerBank> customerBanks = customerBankService.getCustomerBankList(new CustomerBank());
for (CustomerBank customer : customerBanks) {
Long deptId = customer.getDeptId();
String memberId = customer.getAdapayMemberId();
String settleAccountId = customer.getSettleAccountId();
if (deptId == null || StringUtils.isBlank(memberId) || StringUtils.isBlank(settleAccountId)) {
continue;
}
try {
JSONObject accountBalance = adapayService.queryAccountBalance(deptId, memberId, settleAccountId, "01");
if (AdapayStatusEnum.succeeded.code.equals(accountBalance.getString("status"))) {
// 可提现金额
String avlBalance = accountBalance.getString("avl_balance");
if (BigDecimal.ZERO.compareTo(new BigDecimal(avlBalance)) > -1) {
continue;
}
// 提现
log.info("Customer[{},{}]开始提现: avlBalance={}", customer.getCustomerId(), customer.getName(), avlBalance);
String orderNo = AdapayUtils.createOrderNo(AdapayOrderType.DRAW_CASH);
JSONObject drawCash = adapayService.drawCash(deptId, orderNo, "T1", avlBalance, memberId, "提现", null);
log.info("Customer[{},{}]提现结果: {}", customer.getCustomerId(), customer.getName(), drawCash.toJSONString());
} else {
log.error("Customer[{},{}]查询账户余额失败: {}", customer.getCustomerId(), customer.getName(), accountBalance.toJSONString());
}
} catch (BaseAdaPayException e) {
log.error(e.getMessage(), e);
}
}
}
/**
* 定时同步提现状态
*/
@Scheduled(fixedRate = 5 * 60 * 1000L)
public void syncDrawCash() {
List<DrawCashRecord> records = drawCashRecordMapper.selectByStatus("pending");
@ -154,7 +75,7 @@ public class AdapaySyncTimer {
// 更新提现记录表状态
drawCashRecordMapper.updateStatus(record.getId(), "succeeded");
// 更新子订单表状态
orderDetailService.updateDrawCashStatus(record.getId(), 2, null, new Date());
orderDetailService.updateDrawCashStatus(record.getId(), 2, new Date());
break;
// 提现失败
case "F":
@ -162,7 +83,7 @@ public class AdapaySyncTimer {
// 更新提现记录表状态
drawCashRecordMapper.updateStatus(record.getId(), "failed");
// 更新子订单表状态
orderDetailService.updateDrawCashStatus(record.getId(), -1, null, null);
orderDetailService.updateDrawCashStatus(record.getId(), -1, null);
break;
default:
break;

View File

@ -24,7 +24,7 @@ shiro:
cipherKey:
session:
# Session超时时间-1代表永不过期默认30分钟
expireTime: 720
expireTime: 30
# 同步session到数据库的周期默认1分钟
dbSyncPeriod: 1
# 相隔多久检查一次session的有效性默认就是10分钟
@ -45,9 +45,9 @@ spring:
druid:
# 主库数据源
master:
url: jdbc:mysql://8.138.169.236:3306/gqz?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
username: root
password: clunt@12345
url: jdbc:mysql://121.4.113.60:3306/gqz?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: admin
password: Clunt@12345
# 从库数据源
slave:
# 从数据源开关/默认关闭
@ -58,9 +58,9 @@ spring:
# 初始连接数
initialSize: 5
# 最小连接池数量
minIdle: 5
minIdle: 10
# 最大连接池数量
maxActive: 10
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒

View File

@ -7,7 +7,7 @@ ruoyi:
# 版权年份
copyrightYear: 2021
# 实例演示开关
demoEnabled: false
demoEnabled: true
# 文件路径 示例( Windows配置D:/ruoyi/uploadPathLinux配置 /home/ruoyi/uploadPath
profile: /home/ruoyi/uploadPath
# 获取ip地址开关
@ -16,7 +16,7 @@ ruoyi:
# 开发环境配置
server:
# 服务器的HTTP端口默认为80
port: 19001
port: 80
servlet:
# 应用的访问路径
context-path: /
@ -59,7 +59,7 @@ spring:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
profiles:
active: druid
active: dev
# 文件上传
servlet:
multipart:
@ -116,12 +116,12 @@ qiniu:
accessKey: 'QTNOppkvtufxTxLjt1V7YZwvzV2Rc6WLD5yXLBVY'
secretKey: 'V8SM9nkbO-dft4JmG7UaCH6RYxXdqzrvQ0zWO2W3'
bucketName: 'gqz'
mediaUrl: 'https://gqz.opsoul.com/'
mediaUrl: 'http://gqz.opsoul.com/'
adapay:
debug: true
prod-mode: true
notifyUrl: 'https://gmhl.gmjlb.com/adapay/callback'
notifyUrl: 'https://www.opsoul.com:8881/adapay/callback'
jim:
appKey: '110e8830290152d76e2f1d97'
@ -130,7 +130,7 @@ jim:
# 百度地图应用api
baidu:
ak: 'i0sdnIsMmJVik7vJhfqMHA6DmS6d0fMB'
ak: 'ZQTgMW7W0GTuE7Ripb0HDp5TqRaOI6PZ'
url: 'https://api.map.baidu.com/reverse_geocoding/v3/?ak=#AK#&output=json&coordtype=wgs84ll&location='
sms:
@ -138,31 +138,3 @@ sms:
account: '8a216da85f008800015f0eb223620557'
appId: '8a216da85f008800015f0eb224db055d'
token: '3cef1bc80d814637a236d93004e7ffa5'
# 阿里云api接口, 这里是身份证二要素的
aliyun:
accessKey: LTAI5tDmv3T3Ze1Mt9wi5Be6
accessSecret: EV4dzWRfKTQaPRjf3tFziMuVBCsThU
endpoint: dytnsapi.aliyuncs.com
authCode: od2FgE9a9g
# 物流API配置
# logistics:
# kdniao:
# # 快递鸟 API配置
# appId: '1889454' # 快递鸟应用ID需要到快递鸟官网申请
# appKey: 'b2483529-807d-49af-b0e1-1ed218baa4db' # 快递鸟API密钥需要到快递鸟官网申请
# url: 'https://api.kdniao.com/api/dist' # 快递鸟即时查询接口地址
# 快递鸟支持两种接口:
# 1. 即时查询接口https://api.kdniao.com/api/dist
# 2. 物流跟踪接口https://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx
logistics:
# 阿里云快递查询API配置
aliyun:
# 阿里云API网关AppCode需要在阿里云市场购买快递查询服务后获取
appCode: "78064b8aaa294f64ab07a285f129aea6"
# API主机地址
host: "https://kzexpress.market.alicloudapi.com"
# API路径
path: "/api-mall/api/express/query"

View File

@ -273,7 +273,8 @@
var _defaultRootFlag = item[options.parentCode] == '0' ||
item[options.parentCode] == 0 ||
item[options.parentCode] == null ||
item[options.parentCode] == '';
item[options.parentCode] == '' ||
$.inArray(item[options.code], parentCodes) > 0 && !rootFlag;
if (!item[options.parentCode] || (_root ? (item[options.parentCode] == options.rootIdValue) : _defaultRootFlag)) {
rootFlag = true;
if (!target.data_list["_root_"]) {

View File

@ -1,164 +0,0 @@
* {
list-style: none;
margin: 0;
padding: 0;
}
html, body {
height: 100%;
}
body {
padding: 100px;
box-sizing: border-box;
}
.cascader-wrap {
min-height: 40px;
border: 1px solid #dcdfe6;
box-sizing: border-box;
border-radius: 4px;
position: relative;
z-index: 100;
}
.cascader-wrap:after {
/*opacity: 1;*/
content: "展开";
padding: 5px 10px;
background-color: #1d85c6;
color: #feffff;
border-radius: 4px;
text-align: center;
position: absolute;
top: 12%;
right: 5px;
/*border-color: transparent transparent #888 transparent;*/
/*border-style: solid;*/
/*height: 0;*/
/*margin-top: -2px;*/
/*position: absolute;*/
/*top: 50%;*/
/*right: 10px;*/
/*width: 0;*/
/*border-width: 0 4px 5px 4px;*/
/*transform: rotate(180deg);*/
transition: all 0.1s;
}
.cascader-wrap.is-show:after {
/*transform: rotate(0deg);*/
content: "收起";
background-color: #e82d2d;
color: #feffff;
}
.cascader-wrap.is-show .eo-cascader-panel {
display: block;
display: flex;
}
.cascader-wrap .eo-clear-btn {
display: none;
}
.cascader-wrap.is-clear .eo-clear-btn {
font-style: normal;
position: absolute;
right: 7px;
top: 50%;
margin-top: -7px;
font-size: 12px;
width: 12px;
height: 12px;
border: 1px solid #c0c4cc;
border-radius: 50%;
text-align: center;
line-height: 9px;
color: #c0c4cc;
display: block;
cursor: pointer;
z-index: 9;
}
.cascader-wrap.is-clear:after {
/*opacity: 0;*/
}
.eo-cascader-panel {
display: flex;
position: absolute;
background: #fff;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
top: 40px;
left: 0;
overflow: hidden;
display: none;
}
.eo-cascader-menu {
min-width: 200px;
box-sizing: border-box;
color: #606266;
border-right: 1px solid #e4e7ed;
position: relative;
padding: 6px 0;
max-height: 350px;
overflow-y: auto;
}
.eo-cascader-menu:last-child {
border-right: none;
}
.eo-cascader-menu li {
line-height: 30px;
cursor: pointer;
padding: 0 15px;
position: relative;
}
.eo-cascader-menu li.has-child:after {
content: '>';
position: absolute;
right: 10px;
top: -2px;
transform: scaleY(1.8);
font-size: 12px;
color: #606266;
}
.eo-cascader-menu li:hover {
background: #f5f7fa;
}
.eo-cascader-menu li span {
margin-left: 6px;
}
.eo-checked-wrap {
padding: 5px;
position: relative;
width: 90%;
}
.eo-checked-wrap li {
display: flex;
font-size: 12px;
color: #909399;
line-height: 24px;
margin: 2px 0 2px 0px;
background: #f0f2f5;
padding: 0 10px;
height: 24px;
border-radius: 4px;
box-sizing: border-box;
align-items: center;
}
.eo-checked-wrap li i {
font-style: normal;
margin-left: 10px;
cursor: pointer;
width: 12px;
height: 12px;
background: #c0c4cc;
border-radius: 50%;
text-align: center;
line-height: 9px;
color: #fff;
}
.eo-checked-wrap li p {
margin: 0;
}
input[type="checkbox"].is-indeterminate {
width: 13px;
height: 13px;
background-color: #dfedff;
-webkit-appearance: none;
border: 1px solid #61aaff;
border-radius: 2px;
outline: none;
}

File diff suppressed because one or more lines are too long

View File

@ -1,28 +0,0 @@
(function(r){r.fn.qrcode=function(h){var s;function u(a){this.mode=s;this.data=a}function o(a,c){this.typeNumber=a;this.errorCorrectLevel=c;this.modules=null;this.moduleCount=0;this.dataCache=null;this.dataList=[]}function q(a,c){if(void 0==a.length)throw Error(a.length+"/"+c);for(var d=0;d<a.length&&0==a[d];)d++;this.num=Array(a.length-d+c);for(var b=0;b<a.length-d;b++)this.num[b]=a[b+d]}function p(a,c){this.totalCount=a;this.dataCount=c}function t(){this.buffer=[];this.length=0}u.prototype={getLength:function(){return this.data.length},
write:function(a){for(var c=0;c<this.data.length;c++)a.put(this.data.charCodeAt(c),8)}};o.prototype={addData:function(a){this.dataList.push(new u(a));this.dataCache=null},isDark:function(a,c){if(0>a||this.moduleCount<=a||0>c||this.moduleCount<=c)throw Error(a+","+c);return this.modules[a][c]},getModuleCount:function(){return this.moduleCount},make:function(){if(1>this.typeNumber){for(var a=1,a=1;40>a;a++){for(var c=p.getRSBlocks(a,this.errorCorrectLevel),d=new t,b=0,e=0;e<c.length;e++)b+=c[e].dataCount;
for(e=0;e<this.dataList.length;e++)c=this.dataList[e],d.put(c.mode,4),d.put(c.getLength(),j.getLengthInBits(c.mode,a)),c.write(d);if(d.getLengthInBits()<=8*b)break}this.typeNumber=a}this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17;this.modules=Array(this.moduleCount);for(var d=0;d<this.moduleCount;d++){this.modules[d]=Array(this.moduleCount);for(var b=0;b<this.moduleCount;b++)this.modules[d][b]=null}this.setupPositionProbePattern(0,0);this.setupPositionProbePattern(this.moduleCount-
7,0);this.setupPositionProbePattern(0,this.moduleCount-7);this.setupPositionAdjustPattern();this.setupTimingPattern();this.setupTypeInfo(a,c);7<=this.typeNumber&&this.setupTypeNumber(a);null==this.dataCache&&(this.dataCache=o.createData(this.typeNumber,this.errorCorrectLevel,this.dataList));this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,c){for(var d=-1;7>=d;d++)if(!(-1>=a+d||this.moduleCount<=a+d))for(var b=-1;7>=b;b++)-1>=c+b||this.moduleCount<=c+b||(this.modules[a+d][c+b]=
0<=d&&6>=d&&(0==b||6==b)||0<=b&&6>=b&&(0==d||6==d)||2<=d&&4>=d&&2<=b&&4>=b?!0:!1)},getBestMaskPattern:function(){for(var a=0,c=0,d=0;8>d;d++){this.makeImpl(!0,d);var b=j.getLostPoint(this);if(0==d||a>b)a=b,c=d}return c},createMovieClip:function(a,c,d){a=a.createEmptyMovieClip(c,d);this.make();for(c=0;c<this.modules.length;c++)for(var d=1*c,b=0;b<this.modules[c].length;b++){var e=1*b;this.modules[c][b]&&(a.beginFill(0,100),a.moveTo(e,d),a.lineTo(e+1,d),a.lineTo(e+1,d+1),a.lineTo(e,d+1),a.endFill())}return a},
setupTimingPattern:function(){for(var a=8;a<this.moduleCount-8;a++)null==this.modules[a][6]&&(this.modules[a][6]=0==a%2);for(a=8;a<this.moduleCount-8;a++)null==this.modules[6][a]&&(this.modules[6][a]=0==a%2)},setupPositionAdjustPattern:function(){for(var a=j.getPatternPosition(this.typeNumber),c=0;c<a.length;c++)for(var d=0;d<a.length;d++){var b=a[c],e=a[d];if(null==this.modules[b][e])for(var f=-2;2>=f;f++)for(var i=-2;2>=i;i++)this.modules[b+f][e+i]=-2==f||2==f||-2==i||2==i||0==f&&0==i?!0:!1}},setupTypeNumber:function(a){for(var c=
j.getBCHTypeNumber(this.typeNumber),d=0;18>d;d++){var b=!a&&1==(c>>d&1);this.modules[Math.floor(d/3)][d%3+this.moduleCount-8-3]=b}for(d=0;18>d;d++)b=!a&&1==(c>>d&1),this.modules[d%3+this.moduleCount-8-3][Math.floor(d/3)]=b},setupTypeInfo:function(a,c){for(var d=j.getBCHTypeInfo(this.errorCorrectLevel<<3|c),b=0;15>b;b++){var e=!a&&1==(d>>b&1);6>b?this.modules[b][8]=e:8>b?this.modules[b+1][8]=e:this.modules[this.moduleCount-15+b][8]=e}for(b=0;15>b;b++)e=!a&&1==(d>>b&1),8>b?this.modules[8][this.moduleCount-
b-1]=e:9>b?this.modules[8][15-b-1+1]=e:this.modules[8][15-b-1]=e;this.modules[this.moduleCount-8][8]=!a},mapData:function(a,c){for(var d=-1,b=this.moduleCount-1,e=7,f=0,i=this.moduleCount-1;0<i;i-=2)for(6==i&&i--;;){for(var g=0;2>g;g++)if(null==this.modules[b][i-g]){var n=!1;f<a.length&&(n=1==(a[f]>>>e&1));j.getMask(c,b,i-g)&&(n=!n);this.modules[b][i-g]=n;e--; -1==e&&(f++,e=7)}b+=d;if(0>b||this.moduleCount<=b){b-=d;d=-d;break}}}};o.PAD0=236;o.PAD1=17;o.createData=function(a,c,d){for(var c=p.getRSBlocks(a,
c),b=new t,e=0;e<d.length;e++){var f=d[e];b.put(f.mode,4);b.put(f.getLength(),j.getLengthInBits(f.mode,a));f.write(b)}for(e=a=0;e<c.length;e++)a+=c[e].dataCount;if(b.getLengthInBits()>8*a)throw Error("code length overflow. ("+b.getLengthInBits()+">"+8*a+")");for(b.getLengthInBits()+4<=8*a&&b.put(0,4);0!=b.getLengthInBits()%8;)b.putBit(!1);for(;!(b.getLengthInBits()>=8*a);){b.put(o.PAD0,8);if(b.getLengthInBits()>=8*a)break;b.put(o.PAD1,8)}return o.createBytes(b,c)};o.createBytes=function(a,c){for(var d=
0,b=0,e=0,f=Array(c.length),i=Array(c.length),g=0;g<c.length;g++){var n=c[g].dataCount,h=c[g].totalCount-n,b=Math.max(b,n),e=Math.max(e,h);f[g]=Array(n);for(var k=0;k<f[g].length;k++)f[g][k]=255&a.buffer[k+d];d+=n;k=j.getErrorCorrectPolynomial(h);n=(new q(f[g],k.getLength()-1)).mod(k);i[g]=Array(k.getLength()-1);for(k=0;k<i[g].length;k++)h=k+n.getLength()-i[g].length,i[g][k]=0<=h?n.get(h):0}for(k=g=0;k<c.length;k++)g+=c[k].totalCount;d=Array(g);for(k=n=0;k<b;k++)for(g=0;g<c.length;g++)k<f[g].length&&
(d[n++]=f[g][k]);for(k=0;k<e;k++)for(g=0;g<c.length;g++)k<i[g].length&&(d[n++]=i[g][k]);return d};s=4;for(var j={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,
78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:1335,G18:7973,G15_MASK:21522,getBCHTypeInfo:function(a){for(var c=a<<10;0<=j.getBCHDigit(c)-j.getBCHDigit(j.G15);)c^=j.G15<<j.getBCHDigit(c)-j.getBCHDigit(j.G15);return(a<<10|c)^j.G15_MASK},getBCHTypeNumber:function(a){for(var c=a<<12;0<=j.getBCHDigit(c)-
j.getBCHDigit(j.G18);)c^=j.G18<<j.getBCHDigit(c)-j.getBCHDigit(j.G18);return a<<12|c},getBCHDigit:function(a){for(var c=0;0!=a;)c++,a>>>=1;return c},getPatternPosition:function(a){return j.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,c,d){switch(a){case 0:return 0==(c+d)%2;case 1:return 0==c%2;case 2:return 0==d%3;case 3:return 0==(c+d)%3;case 4:return 0==(Math.floor(c/2)+Math.floor(d/3))%2;case 5:return 0==c*d%2+c*d%3;case 6:return 0==(c*d%2+c*d%3)%2;case 7:return 0==(c*d%3+(c+d)%2)%2;default:throw Error("bad maskPattern:"+
a);}},getErrorCorrectPolynomial:function(a){for(var c=new q([1],0),d=0;d<a;d++)c=c.multiply(new q([1,l.gexp(d)],0));return c},getLengthInBits:function(a,c){if(1<=c&&10>c)switch(a){case 1:return 10;case 2:return 9;case s:return 8;case 8:return 8;default:throw Error("mode:"+a);}else if(27>c)switch(a){case 1:return 12;case 2:return 11;case s:return 16;case 8:return 10;default:throw Error("mode:"+a);}else if(41>c)switch(a){case 1:return 14;case 2:return 13;case s:return 16;case 8:return 12;default:throw Error("mode:"+
a);}else throw Error("type:"+c);},getLostPoint:function(a){for(var c=a.getModuleCount(),d=0,b=0;b<c;b++)for(var e=0;e<c;e++){for(var f=0,i=a.isDark(b,e),g=-1;1>=g;g++)if(!(0>b+g||c<=b+g))for(var h=-1;1>=h;h++)0>e+h||c<=e+h||0==g&&0==h||i==a.isDark(b+g,e+h)&&f++;5<f&&(d+=3+f-5)}for(b=0;b<c-1;b++)for(e=0;e<c-1;e++)if(f=0,a.isDark(b,e)&&f++,a.isDark(b+1,e)&&f++,a.isDark(b,e+1)&&f++,a.isDark(b+1,e+1)&&f++,0==f||4==f)d+=3;for(b=0;b<c;b++)for(e=0;e<c-6;e++)a.isDark(b,e)&&!a.isDark(b,e+1)&&a.isDark(b,e+
2)&&a.isDark(b,e+3)&&a.isDark(b,e+4)&&!a.isDark(b,e+5)&&a.isDark(b,e+6)&&(d+=40);for(e=0;e<c;e++)for(b=0;b<c-6;b++)a.isDark(b,e)&&!a.isDark(b+1,e)&&a.isDark(b+2,e)&&a.isDark(b+3,e)&&a.isDark(b+4,e)&&!a.isDark(b+5,e)&&a.isDark(b+6,e)&&(d+=40);for(e=f=0;e<c;e++)for(b=0;b<c;b++)a.isDark(b,e)&&f++;a=Math.abs(100*f/c/c-50)/5;return d+10*a}},l={glog:function(a){if(1>a)throw Error("glog("+a+")");return l.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;256<=a;)a-=255;return l.EXP_TABLE[a]},EXP_TABLE:Array(256),
LOG_TABLE:Array(256)},m=0;8>m;m++)l.EXP_TABLE[m]=1<<m;for(m=8;256>m;m++)l.EXP_TABLE[m]=l.EXP_TABLE[m-4]^l.EXP_TABLE[m-5]^l.EXP_TABLE[m-6]^l.EXP_TABLE[m-8];for(m=0;255>m;m++)l.LOG_TABLE[l.EXP_TABLE[m]]=m;q.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var c=Array(this.getLength()+a.getLength()-1),d=0;d<this.getLength();d++)for(var b=0;b<a.getLength();b++)c[d+b]^=l.gexp(l.glog(this.get(d))+l.glog(a.get(b)));return new q(c,0)},mod:function(a){if(0>
this.getLength()-a.getLength())return this;for(var c=l.glog(this.get(0))-l.glog(a.get(0)),d=Array(this.getLength()),b=0;b<this.getLength();b++)d[b]=this.get(b);for(b=0;b<a.getLength();b++)d[b]^=l.gexp(l.glog(a.get(b))+c);return(new q(d,0)).mod(a)}};p.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],
[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,
116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,
43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,
3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,
55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,
45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];p.getRSBlocks=function(a,c){var d=p.getRsBlockTable(a,c);if(void 0==d)throw Error("bad rs block @ typeNumber:"+a+"/errorCorrectLevel:"+c);for(var b=d.length/3,e=[],f=0;f<b;f++)for(var h=d[3*f+0],g=d[3*f+1],j=d[3*f+2],l=0;l<h;l++)e.push(new p(g,j));return e};p.getRsBlockTable=function(a,c){switch(c){case 1:return p.RS_BLOCK_TABLE[4*(a-1)+0];case 0:return p.RS_BLOCK_TABLE[4*(a-1)+1];case 3:return p.RS_BLOCK_TABLE[4*
(a-1)+2];case 2:return p.RS_BLOCK_TABLE[4*(a-1)+3]}};t.prototype={get:function(a){return 1==(this.buffer[Math.floor(a/8)]>>>7-a%8&1)},put:function(a,c){for(var d=0;d<c;d++)this.putBit(1==(a>>>c-d-1&1))},getLengthInBits:function(){return this.length},putBit:function(a){var c=Math.floor(this.length/8);this.buffer.length<=c&&this.buffer.push(0);a&&(this.buffer[c]|=128>>>this.length%8);this.length++}};"string"===typeof h&&(h={text:h});h=r.extend({},{render:"canvas",width:256,height:256,typeNumber:-1,
correctLevel:2,background:"#ffffff",foreground:"#000000"},h);return this.each(function(){var a;if("canvas"==h.render){a=new o(h.typeNumber,h.correctLevel);a.addData(h.text);a.make();var c=document.createElement("canvas");c.width=h.width;c.height=h.height;for(var d=c.getContext("2d"),b=h.width/a.getModuleCount(),e=h.height/a.getModuleCount(),f=0;f<a.getModuleCount();f++)for(var i=0;i<a.getModuleCount();i++){d.fillStyle=a.isDark(f,i)?h.foreground:h.background;var g=Math.ceil((i+1)*b)-Math.floor(i*b),
j=Math.ceil((f+1)*b)-Math.floor(f*b);d.fillRect(Math.round(i*b),Math.round(f*e),g,j)}}else{a=new o(h.typeNumber,h.correctLevel);a.addData(h.text);a.make();c=r("<table></table>").css("width",h.width+"px").css("height",h.height+"px").css("border","0px").css("border-collapse","collapse").css("background-color",h.background);d=h.width/a.getModuleCount();b=h.height/a.getModuleCount();for(e=0;e<a.getModuleCount();e++){f=r("<tr></tr>").css("height",b+"px").appendTo(c);for(i=0;i<a.getModuleCount();i++)r("<td></td>").css("width",
d+"px").css("background-color",a.isDark(e,i)?h.foreground:h.background).appendTo(f)}}a=c;jQuery(a).appendTo(this)})}})(jQuery);

View File

@ -1,596 +0,0 @@
/**
* Name: 级联选择器控件
* Version: 2020-06-16
* Author: 王海峰 <wanghaifeng@iyiou.com>
* Function List:
* 1. 级联面板 - 支持多选 - 单选
* 2. 支持回显已选中数据的完整路径 父级-父级-子级(可通过配置项 separator 自定义分隔符)
* 3. 支持删除单个选中的数据项
* 4. 支持一键删除所有选中数据项(可通过配置项 clearable 是否启用改功能)
* 5. 接口: 一键获取所选中的所有文本数组
* 6. 接口: 一键获取所选中的所有ID数组
*/
(function() {
/**
* cascader_node 适配器模式
* 将用户传入的数据通过该适配器进行处理
* 数据驱动的思路一个 CascaderNode 实例对应一个数据项不管是子级还是父级
*/
var cascader_node = function () {
/**
* @param {Object} data 数据
* @param {Object} config 配置项
* @param {Object} parentNode 父级 递归时传入
*/
function CascaderNode(data, config, parentNode) {
this.data = data // 原始数据
this.config = config // 配置项
this.indeterminate = false // 该父级下的子级是否全选,用于控制父级显示状态(只有子级全选,父级才全选)
this.parent = parentNode || null // 该项的父级
this.level = !this.parent ? 1 : this.parent.level + 1 // 等级序列号
this.uid = data[config.value] // 数据ID
// 因是数据驱动的方式一个数据项对应一个DOMDOM选中与否
this.checked = false // 该项数据是否选中
this.initState()
this.initChildren()
}
/**
* 初始化数据
*/
CascaderNode.prototype.initState = function initState() {
var _config = this.config,
valueKey = _config.value,
labelKey = _config.label
this.value = this.data[valueKey]
this.label = this.data[labelKey]
this.pathNodes = this.calculatePathNodes()
this.path = this.pathNodes.map(function (node) {
return node.value
})
this.pathLabels = this.pathNodes.map(function (node) {
return node.label
})
}
/**
* 初始化该数据下的子级
* 内部通过递归生成 CascaderNode 实例即子级
*/
CascaderNode.prototype.initChildren = function initChildren() {
var _this = this
var config = this.config
var childrenKey = config.children
var childrenData = this.data[childrenKey]
this.hasChildren = Array.isArray(childrenData)
this.children = (childrenData || []).map(function (child) {
return new CascaderNode(child, config, _this)
})
}
/**
* 计算路径
*/
CascaderNode.prototype.calculatePathNodes = function calculatePathNodes() {
var nodes = [this]
var parent = this.parent
while (parent) {
nodes.unshift(parent)
parent = parent.parent
}
return nodes
}
/**
* 获取该项的路径包含父级+
*/
CascaderNode.prototype.getPath = function getPath() {
return this.path
}
/**
* 获取该项的路径不包含父级
*/
CascaderNode.prototype.getValue = function getPath() {
return this.value
}
/**
* 多选 - 父级选中操作让所有子级选中
* @param {Boolean} checked
*/
CascaderNode.prototype.onParentCheck = function onParentCheck(checked) {
var child = this.children.length ? this.children : this
this.checked = checked
this.indeterminate = false
this.doAllCheck(child, checked)
}
/**
* 多选 - 父级选中时子级全选
* @param {Array} child
* @param {Boolean} checked
*/
CascaderNode.prototype.doAllCheck = function doAllCheck(child, checked) {
var _this = this
if (Array.isArray(child) && child.length) {
child.forEach(function (c) {
c.checked = checked
c.indeterminate = false
_this.doAllCheck(c.children, checked)
})
}
}
/**
* 多选 - 子级选中操作父级
* @param {*} checked
*/
CascaderNode.prototype.onChildCheck = function onChildCheck(checked) {
this.checked = checked
var parent = this.parent
var isChecked = parent.children.every(function (child) {
return child.checked
})
this.setCheckState(this.parent, isChecked);
}
/**
* 设置父级相应的状态
* 当该项有同级且都没有选中父级为 无选中 状态
* 当该项有同级且同级的所有数据都为选中时父级为 选中 状态
* 当该项有同级但同级中有且只有一项没有被选中父级为 半选中 状态 -
* @param {Object} parent
* @param {Boolean} isChecked
*/
CascaderNode.prototype.setCheckState = function setCheckState(parent, isChecked) {
parent.checked = isChecked
var totalNum = parent.children.length;
var checkedNum = parent.children.reduce(function (c, p) {
var num = p.checked ? 1 : p.indeterminate ? 0.5 : 0;
return c + num;
}, 0);
parent.indeterminate = checkedNum !== totalNum && checkedNum > 0;
parent.parent && this.setCheckState(parent.parent, isChecked)
}
return CascaderNode
}()
/**
* eo_cascader 生成级联选择器
* 绑定相关事件操作数据渲染选择器 回显选中列表
*/
var eo_cascader = function () {
// 默认配置
var defaultConfig = {
disabled: 'disabled',
emitPath: true,
value: 'id',
label: 'label',
children: 'children'
}
/**
* 级联选择器构造函数
* @param {Array} data
* @param {Object} config
*/
function EoCascader(data, config) {
this.config = Object.assign(defaultConfig, config) || null
this.multiple = config.multiple // 是否多选
this.separator = config.separator // 自定义数据之间分隔符
this.data = data // 原始数据
this.clearable = config.clearable // 是否可一键清空
this.panelShowState = false // 控制级联选择器显示
this.storageChecked = {} // 存储已选中的数据项
this.checkedText = [] // 选中的文本
this.checkedID = [] // 选中的ID
this.ele = document.getElementById(config.elementID) // DOM容器
this.panelWrap = this.initPanel() // 级联选择器DOM容器
this.checkedWrap = this.initCheckedWrap() // 回显选中列表DOM容器
this.checkedCallback = config.checkedCallback || (() => {});
this.initNodes(data)
this.initEvents()
}
/**
* 事件绑定
*/
EoCascader.prototype.initEvents = function initEvents(e) {
this.ele.addEventListener('click', this.bindCascaderClick.bind(this))
document.body.addEventListener('click', this.bindBodyClick.bind(this), true)
if(this.clearable) {
this.ele.addEventListener('mouseover', this.bindCascaderHover.bind(this))
this.ele.addEventListener('mouseout', this.bindCascaderOut.bind(this))
}
}
/**
* body点击隐藏级联面板
*/
EoCascader.prototype.bindBodyClick = function bindCascaderClick(e) {
if(e.target.tagName !== 'BODY') return
this.panelShowState = false
this.ele.className = 'cascader-wrap'
}
/**
* 点击容器控制切换级联面板显示
*/
EoCascader.prototype.bindCascaderClick = function bindCascaderClick(e) {
e.stopPropagation();
if(e.target.id !== this.ele.id ) return
this.panelShowState = !this.panelShowState
this.ele.className = this.panelShowState? 'cascader-wrap is-show': 'cascader-wrap'
}
/**
* 当且仅当 clearable true 时绑定
* 鼠标移入容器显示一键清空按钮
*/
EoCascader.prototype.bindCascaderHover = function bindCascaderHover(e) {
e.stopPropagation();
if(e.target.id !== this.ele.id && e.target.className !== 'eo-clear-btn' ) return
if(JSON.stringify(this.storageChecked) !== '{}') {
this.ele.className = this.panelShowState? 'cascader-wrap is-show is-clear': 'cascader-wrap is-clear'
}
}
/**
* 当且仅当 clearable true 时绑定
* 鼠标移出容器隐藏一键清空按钮
*/
EoCascader.prototype.bindCascaderOut = function bindCascaderOut(e) {
e.stopPropagation();
if(e.target.id !== this.ele.id) return
this.ele.className = this.panelShowState? 'cascader-wrap is-show': 'cascader-wrap'
}
/**
* 动态生成级联面板DOM容器
*/
EoCascader.prototype.initPanel = function initPanel() {
var panel = document.createElement('div')
panel.className = 'eo-cascader-panel'
return panel
}
/**
* 动态生成回显选中列表DOM容器
*/
EoCascader.prototype.initCheckedWrap = function initCheckedWrap() {
var checkedWrap = document.createElement('div')
checkedWrap.className = 'eo-checked-wrap'
return checkedWrap
}
/**
* 动态生成一键清空按钮
*/
EoCascader.prototype.initClearDom = function initClearDom() {
var clearBtn = document.createElement('i')
clearBtn.className = 'eo-clear-btn'
clearBtn.innerHTML = 'x'
var _this = this
// 绑定事件,初始化所有数据,重新渲染级联面板
clearBtn.addEventListener('click', function(e) {
e.stopPropagation();
_this.storageChecked = {}
_this.checkedCallback();
_this.config.checkedValue = null
_this.checkedText = []
_this.checkedID = []
_this.initNodes(_this.data)
_this.initCheckedLi()
_this.panelWrap.style.top = _this.ele.offsetHeight + 2 + 'px'
})
return clearBtn
}
/**
* 通过 CascaderNode 适配器对原始数据进行改造并赋值给当前构造函数的 nodes 对象
* @param {Array} data 用户传入的原始数据
*/
EoCascader.prototype.initNodes = function initNodes(data) {
var _this = this
this.nodes = data.map(function (nodeData) {
// 访问适配器
return new cascader_node(nodeData, _this.config)
})
// 级联面板
this.menus = [this.nodes]
// 当为编辑页面时,往往需要回显上次提交的数据,即,
// 如果存在 checkedValue
// 那么调用 findChecked 方法,通过传入的已选 ID渲染级联面板、回显列表
// 反之,根据初始数据正常渲染即可
this.config.checkedValue ? this.findChecked(this.config.checkedValue) : this.createNodes(this.menus)
// 如果可一键清空,动态添加清空按钮
this.clearable && this.ele.appendChild(this.initClearDom())
}
/**
* @param {Object} currentMenu 级联面板中当前的点击项
* 点击同级项时通过操作 menus使对应的子级进行渲染
*/
EoCascader.prototype.renderNodes = function (currentMenu) {
// 操作 menus
var menus = this.menus.slice(0, currentMenu.level)
currentMenu.children.length && menus.push(currentMenu.children)
this.menus = menus
var wrap = this.panelWrap
var wrapChild = wrap.children
// 操作DOM
for (let j = currentMenu.level; j < wrap.children.length; j++) {
wrap.removeChild(wrapChild[j])
j = j - 1
}
return menus
}
/**
* 数据驱动的方式通过 menus 渲染DOM
* 每次操作 menus增删都需要修改 menus进而再次调用改方法进行渲染
* @param {Array} menus 级联面板数据
*/
EoCascader.prototype.createNodes = function (menus) {
var wrap = this.panelWrap
wrap.innerHTML = ''
var _this = this
for (let i = 0; i < menus.length; i++) {
var menu = document.createElement('div')
menu.className = 'eo-cascader-menu'
var ul = document.createElement('ul')
var menusList = menus[i];
for (let k = 0; k < menusList.length; k++) {
var li = document.createElement('li')
if(menusList[k].children.length) li.className = 'has-child'
// 当且仅当多选时 创建 label checkbox
if(_this.multiple) {
var label = document.createElement('label')
var checkbox = document.createElement('input')
checkbox.type = 'checkbox'
checkbox.checked = menusList[k].checked
checkbox.setAttribute('uid', menusList[k].uid)
checkbox.className = menusList[k].indeterminate ? 'is-indeterminate' : ''
checkbox.addEventListener('click', _this.bindClickEvent.bind(checkbox,
_this, _this.handleCheckCb)
)
label.appendChild(checkbox)
li.appendChild(label)
}
// 创建文本
var span = document.createElement('span')
span.innerHTML = menusList[k]['label']
span.setAttribute('uid', menusList[k].uid)
li.addEventListener('click', _this.bindClickEvent.bind(span, _this, _this.handleDanxuanCb))
// 将 label 及 文本追加到 li
li.appendChild(span)
ul.appendChild(li)
}
menu.appendChild(ul)
wrap.appendChild(menu)
wrap.style.top = _this.ele.offsetHeight + 2 + 'px'
}
this.ele.appendChild(wrap)
}
/**
* 点击 checkbox 文本回调函数
* @param {this} _this 当前实例
* @param {Function} cb 回调函数
* 当且仅当点击 checkbox 传入 cb
*/
EoCascader.prototype.bindClickEvent = function bindClickEvent(_this, cb) {
var uid = this.getAttribute('uid')
var _thisMenu = _this.menus.flat(Infinity).filter(function (menu) {
return menu.uid == uid
})
typeof cb === 'function' && cb.call(this, _thisMenu, _this, this.checked)
_this.createNodes(_this.renderNodes(_thisMenu[0]))
}
EoCascader.prototype.handleDanxuanCb = function handleDanxuanCb(currentMenu, _this) {
if(_this.multiple) return
var child = currentMenu[0].children
if(!child.length) {
_this.storageChecked = {};
_this.storageChecked[currentMenu[0].uid] = {};
_this.storageChecked[currentMenu[0].uid].pathLabels = currentMenu[0].pathLabels
_this.storageChecked[currentMenu[0].uid].path = currentMenu[0].path
_this.checkedWrap.innerHTML = ''
// 渲染回显列表
_this.initCheckedLi()
_this.checkedCallback();
}
}
/**
* 点击 checkbox 触发回调
* 内部对父级子级选中状态进行修改
* 同时对选中的数据进行存储调用渲染回显列表函数
* @param {Array} currentMenu 当前点击的面板项
* @param {this} _this
* @param {Boolean} isChecked
*/
EoCascader.prototype.handleCheckCb = function handleCheckCb(currentMenu, _this, isChecked) {
// 如果当前点击项为第一级,那么让所有子级都选中
// 如果当前项有父级,设置父级选中状态
if (currentMenu[0].level !== 1) {
currentMenu[0].onChildCheck(isChecked)
}
currentMenu[0].onParentCheck(isChecked)
// 存储当前选中状态
currentMenu[0].children.length ?
_this.showReviewCheckedOb(currentMenu[0]) :
_this.handleReviewCheckedOb(currentMenu[0])
_this.checkedWrap.innerHTML = ''
// 渲染回显列表
_this.initCheckedLi()
}
EoCascader.prototype.initCheckedLi = function () {
var ul = document.createElement('ul')
var _this = this
if(JSON.stringify(this.storageChecked) === '{}') {
return this.checkedWrap.innerHTML = ''
}
for (const key in this.storageChecked) {
if (this.storageChecked.hasOwnProperty(key)) {
var li = document.createElement('li')
var p = document.createElement('p')
var i = document.createElement('i')
li.setAttribute('uid', key)
p.innerHTML = this.storageChecked[key].pathLabels.join(_this.separator)
i.innerHTML = 'x'
i.addEventListener('click', function () {
var uidd = this.parentElement.getAttribute('uid')
delete _this.storageChecked[uidd]
var fn = function (parent) {
for (let i = 0; i < parent.length; i++) {
if (parent[i].children.length) {
fn(parent[i].children)
} else {
if (parent[i].uid == uidd) {
_this.handleCheckCb([parent[i]], _this, false)
_this.createNodes(_this.menus)
}
}
}
}
fn(_this.nodes)
})
li.appendChild(p)
li.appendChild(i)
ul.appendChild(li)
_this.checkedWrap.appendChild(ul)
}
}
this.ele.appendChild(this.checkedWrap)
}
/**
* 根据编辑页面传入的已选ID数组修改面板数据 menus
* @param {Array} uidArr
*/
EoCascader.prototype.findChecked = function (uidArr) {
var _this = this
// 获取上次已经提交过的三级标签
var checkedNodesMatch = []
var nodes = this.nodes
var recursionFn = function (parent) {
for (let i = 0; i < parent.length; i++) {
if (parent[i].children.length) {
recursionFn(parent[i].children)
} else {
if (uidArr.includes(parent[i].uid)) {
parent[i].checked = true
_this.handleCheckCb([parent[i]], _this, true)
checkedNodesMatch.push(parent[i])
}
}
}
}
recursionFn(nodes)
var menus = []
var getMenusMatch = function (menu) {
if (menu.parent) {
menus.push(menu.parent.children)
return getMenusMatch(menu.parent)
}
}
getMenusMatch(checkedNodesMatch[0])
menus.reverse().forEach(function (m) {
_this.menus.push(m)
})
_this.createNodes(this.menus)
}
/**
* 递归的找到当前 node 下最后一个子级并将其存入 storageChecked
* @param {Object} node
*/
EoCascader.prototype.showReviewCheckedOb = function (node) {
if (!node.children.length) {
this.handleReviewCheckedOb(node)
} else {
for (let k = 0; k < node.children.length; k++) {
this.showReviewCheckedOb(node.children[k])
}
}
}
/**
* 如果当前 node 已选中存入 storageChecked 反之删除 storageChecked 中的当前 node
* @param {Object} node
*/
EoCascader.prototype.handleReviewCheckedOb = function (node) {
if (node.checked) {
this.storageChecked[node.uid] = {};
this.storageChecked[node.uid].pathLabels = node.pathLabels;
this.storageChecked[node.uid].path = node.path;
} else {
delete this.storageChecked[node.uid]
}
this.checkedCallback();
}
/**
* 接口获取所有选中的文本
*/
EoCascader.prototype.getCheckedByText = function () {
this.checkedText = []
for (const key in this.storageChecked) {
if (this.storageChecked.hasOwnProperty(key)) {
this.checkedText.push(this.storageChecked[key].pathLabels.join(this.separator))
}
}
return this.checkedText
}
/**
* 接口获取所有选中的ID
*/
EoCascader.prototype.getCheckedByID = function () {
this.checkedID = []
for (const key in this.storageChecked) {
if (this.storageChecked.hasOwnProperty(key)) {
this.checkedID.push(key - 0)
}
}
return this.checkedID
}
/**
* 接口获取所有层级id
*/
EoCascader.prototype.getCheckedPaths = function () {
this.checkedPaths = []
for (const key in this.storageChecked) {
if (this.storageChecked.hasOwnProperty(key)) {
this.checkedPaths.push(this.storageChecked[key].path)
}
}
return this.checkedPaths
}
return EoCascader
}()
window.eo_cascader = eo_cascader
}(window))

View File

@ -391,7 +391,7 @@ var table = {
importTemplate: function() {
$.get(activeWindow().table.options.importTemplateUrl, function(result) {
if (result.code == web_status.SUCCESS) {
window.location.href = "http://gqz.opsoul.com/%E6%89%B9%E9%87%8F%E4%B8%8B%E5%8D%95%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF.xls";
window.location.href = ctx + "common/download?fileName=" + encodeURI(result.msg) + "&delete=" + true;
} else if (result.code == web_status.WARNING) {
$.modal.alertWarning(result.msg)
} else {

View File

@ -5,41 +5,6 @@ $(function() {
var url = ctx + "captcha/captchaImage?type=" + captchaType + "&s=" + Math.random();
$(".imgcode").attr("src", url);
});
$.ajax({
type: "POST",
dataType:"json",
url: ctx + "system/dept/list",
data: { parentId: 100 },
success: function (data) {
$.each(data, function (index, value) {
$('#deptId').append("<option value=" + value.deptId + ">" + value.deptName + "</option>");
});
}
})
// $('#deptId').select2({
// placeholder: '请选择公司编码',
// minimumResultsForSearch: -1,
// ajax: {
// type: "POST",
// dataType:"json",
// url: ctx + "system/dept/list",
// data: { parentId: 100 },
// processResults: function (data) {
// var processedData = [];
// $.each(data, function (index, value) {
// processedData.push({
// id: value.deptId,
// text: value.deptName
// })
// });
// return {
// results: processedData
// };
// },
// cache: true
// }
// });
});
$.validator.setDefaults({
@ -51,8 +16,6 @@ $.validator.setDefaults({
function register() {
$.modal.loading($("#btnSubmit").data("loading"));
var username = $.common.trim($("input[name='username']").val());
var phonenumber = $.common.trim($("input[name='phonenumber']").val());
var deptId = $.common.trim($('#deptId').val());
var password = $.common.trim($("input[name='password']").val());
var validateCode = $("input[name='validateCode']").val();
$.ajax({
@ -60,8 +23,6 @@ function register() {
url: ctx + "register",
data: {
"loginName": username,
"phonenumber": phonenumber,
"deptId": deptId,
"password": password,
"validateCode": validateCode
},
@ -88,23 +49,15 @@ function register() {
function validateRule() {
var icon = "<i class='fa fa-times-circle'></i> ";
$.validator.addMethod("checkPhone",function(value,element,params){
var regex = /^1[345678]\d{9}$/;
return regex.test(value);
}, "请输入正确的手机号码");
$("#registerForm").validate({
rules: {
username: {
required: true,
rangelength: [2,20]
},
phonenumber: {
required: true,
checkPhone: true
minlength: 2
},
password: {
required: true,
rangelength: [5,20]
minlength: 5
},
confirmPassword: {
required: true,
@ -113,18 +66,15 @@ function validateRule() {
},
messages: {
username: {
required: icon + "请输入用户名",
rangelength: icon + "账户长度必须在2到20个字符之间"
},
phonenumber: {
required: icon + "请输入手机号码"
required: icon + "请输入您的用户名",
minlength: icon + "用户名不能小于2个字符"
},
password: {
required: icon + "请输入密码",
rangelength: icon + "密码长度必须在5到20个字符之间"
required: icon + "请输入您的密码",
minlength: icon + "密码不能小于5个字符",
},
confirmPassword: {
required: icon + "请再次输入密码",
required: icon + "请再次输入您的密码",
equalTo: icon + "两次密码输入不一致"
}
}

View File

@ -1,49 +0,0 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('新增发单加价记录')" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-record-add">
<div class="form-group">
<label class="col-sm-3 control-label is-required">订单id</label>
<div class="col-sm-8">
<input name="orderId" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">申请师傅:</label>
<div class="col-sm-8">
<input name="workerId" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">报价金额:</label>
<div class="col-sm-8">
<input name="addMoney" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">备注:</label>
<div class="col-sm-8">
<input name="remark" class="form-control" type="text">
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var prefix = ctx + "worker/record"
$("#form-record-add").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/add", $('#form-record-add').serialize());
}
}
</script>
</body>
</html>

View File

@ -1,50 +0,0 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('修改发单加价记录')" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-record-edit" th:object="${orderAddRecord}">
<input name="id" th:field="*{id}" type="hidden">
<div class="form-group">
<label class="col-sm-3 control-label is-required">订单id</label>
<div class="col-sm-8">
<input name="orderId" th:field="*{orderId}" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">申请师傅:</label>
<div class="col-sm-8">
<input name="workerId" th:field="*{workerId}" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">报价金额:</label>
<div class="col-sm-8">
<input name="addMoney" th:field="*{addMoney}" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">备注:</label>
<div class="col-sm-8">
<input name="remark" th:field="*{remark}" class="form-control" type="text">
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var prefix = ctx + "worker/record";
$("#form-record-edit").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/edit", $('#form-record-edit').serialize());
}
}
</script>
</body>
</html>

View File

@ -1,110 +0,0 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('发单加价记录列表')" />
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="formId">
<div class="select-list">
<ul>
<li>
<label>订单id</label>
<input type="text" name="orderId"/>
</li>
<li>
<label>申请师傅:</label>
<input type="text" name="workerId"/>
</li>
<li>
<label>报价金额:</label>
<input type="text" name="addMoney"/>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i>&nbsp;重置</a>
</li>
</ul>
</div>
</form>
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="worker:record:add">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="worker:record:edit">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="worker:record:remove">
<i class="fa fa-remove"></i> 删除
</a>
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="worker:record:export">
<i class="fa fa-download"></i> 导出
</a>
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('worker:record:edit')}]];
var removeFlag = [[${@permission.hasPermi('worker:record:remove')}]];
var prefix = ctx + "worker/record";
$(function() {
var options = {
url: prefix + "/list",
createUrl: prefix + "/add",
updateUrl: prefix + "/edit/{id}",
removeUrl: prefix + "/remove",
exportUrl: prefix + "/export",
modalName: "发单加价记录",
columns: [{
checkbox: true
},
{
field: 'id',
title: '主键',
visible: false
},
{
field: 'orderId',
title: '订单id'
},
{
field: 'workerId',
title: '申请师傅'
},
{
field: 'addMoney',
title: '报价金额'
},
{
field: 'status',
title: '状态 01初始 02选中'
},
{
field: 'remark',
title: '备注'
},
{
title: '操作',
align: 'center',
formatter: function(value, row, index) {
var actions = [];
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.id + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.id + '\')"><i class="fa fa-remove"></i>删除</a>');
return actions.join('');
}
}]
};
$.table.init(options);
});
</script>
</body>
</html>

View File

@ -1,139 +0,0 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<th:block th:include="include :: header('')"/>
<th:block th:include="include :: select2-css"/>
</head>
<body>
<div class="main-content">
<form id="form-goods-add" class="form-horizontal">
<h4 class="form-header h4">基本信息</h4>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label class="col-sm-4 control-label is-required">主订单已发布更新提示音:</label>
<div class="col-sm-8">
<input name="orderMasterHaveReleasedUrl" id="orderMasterHaveReleasedUrl" placeholder="主订单已发布更新提示音" class="form-control" type="text"
required>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label class="col-sm-4 control-label is-required">主订单新订单更新提示音:</label>
<div class="col-sm-8">
<input name="orderMasterNewOrderUrl" id="orderMasterNewOrderUrl" placeholder="主订单新订单更新提示音" class="form-control" type="text"
required>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label class="col-sm-4 control-label is-required">子订单售后更新提示音:</label>
<div class="col-sm-8">
<input name="orderDetailsAfterUrl" id="orderDetailsAfterUrl" placeholder="子订单售后更新提示音" class="form-control" type="text"
required>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label class="col-sm-4 control-label is-required">子订单售后纠纷更新提示音:</label>
<div class="col-sm-8">
<input name="orderDetailsAfterSalesDisputeUrl" id="orderDetailsAfterSalesDisputeUrl" placeholder="子订单售后纠纷更新提示音" class="form-control" type="text"
required>
</div>
</div>
</div>
</div>
<a class="btn btn-primary btn-rounded btn-sm" onclick="tijiao()">提交</a>
</form>
</div>
<th:block th:include="include :: footer"/>
<th:block th:include="include :: select2-js"/>
<script>
var prefix = ctx + "goods/goods";
var id = "";
var name = "";
var sort = "";
var describe = "";
var type = "";
var dataType = "";
var configUnit = "";
//请求接口加载页面输入框值
function globalConfiginit(){
$.ajax({
type: "GET",
dataType:"json",
url: "/config/globalConfig/search/type/1001",
data: { },
success: function (data) {
id = data.data.id;
name = data.data.name;
sort = data.data.sort;
describe = data.data.describe;
type = data.data.type;
dataType = data.data.dataType;
configUnit = data.data.configUnit;
//alert(data.data.content);
var response = JSON.parse(data.data.content);
$('#orderMasterHaveReleasedUrl').val(response.orderMasterHaveReleasedUrl);
$('#orderMasterNewOrderUrl').val(response.orderMasterNewOrderUrl);
$('#orderDetailsAfterUrl').val(response.orderDetailsAfterUrl);
$('#orderDetailsAfterSalesDisputeUrl').val(response.orderDetailsAfterSalesDisputeUrl);
}
})
}
//页面加载
window.onload = function () {
//请求接口加载页面输入框值
globalConfiginit();
}
//提交按钮
function tijiao(){
$.ajax({
type: "PUT",
dataType:"json",
contentType: 'application/json',
url: "/config/globalConfig/update",
data: JSON.stringify({
id: id,
name: name,
content: JSON.stringify({
"orderMasterHaveReleasedUrl":$('#orderMasterHaveReleasedUrl').val(),
"orderMasterNewOrderUrl":$('#orderMasterNewOrderUrl').val(),
"orderDetailsAfterUrl":$('#orderDetailsAfterUrl').val(),
"orderDetailsAfterSalesDisputeUrl":$('#orderDetailsAfterSalesDisputeUrl').val()
}),
sort: sort,
describe: describe,
type: type,
dataType: dataType,
unit: configUnit
}),
success: function (data) {
if(data.code == 0){
//请求接口加载页面输入框值
globalConfiginit();
alert("成功");
}else {
alert("失败");
}
}
})
}
</script>
</body>
</html>

View File

@ -1,30 +0,0 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('修改上级分销')" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-change-insurance">
<input name="customerId" type="hidden" th:value="${customerId}" />
<div class="form-group">
<label class="col-sm-3 control-label">上级分销:</label>
<div class="col-sm-8">
<select id="customerPlace" name="customerPlace" class="form-control control-label" required>
<option th:each="customerPlace:${customerPlaces}" th:value="${customerPlace.customerId}" th:text="${customerPlace.phone} + ${customerPlace.placeName}" ></option>
</select>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script type="text/javascript">
function submitHandler() {
if ($.validate.form()) {
$.operate.save(ctx + "customer/changePlace", $('#form-change-insurance').serialize());
}
}
</script>
</body>
</html>

View File

@ -118,22 +118,6 @@
field: 'phone',
title: '手机号'
},
{
field: 'customerPlaceName',
title: '上级分销'
},
{
field: 'customerPlacePhone',
title: '上级手机号'
},
{
field: 'parentCustomerPlaceName',
title: '最上级分销'
},
{
field: 'parentCustomerPlacePhone',
title: '最上级手机号'
},
{
field: 'openId',
title: '微信唯一id',
@ -146,8 +130,7 @@
var actions = [];
actions.push('<img class="img-circle" src="' + row.customerLogoUrl + '" alt="消费者头像" />');
return actions.join('');
},
visible: false
}
},
{
visible: editFlag == 'hidden' ? false : true,
@ -168,7 +151,6 @@
formatter: function(value, row, index) {
if (row.customerId != 1) {
var actions = [];
actions.push('<a class="btn btn-success btn-xs " href="javascript:void(0)" onclick="changePlace(\'' + row.customerId + '\')"></i>修改上级分销</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.customerId + '\')"><i class="fa fa-remove"></i>删除</a> ');
return actions.join('');
} else {
@ -180,11 +162,6 @@
$.table.init(options);
}
function changePlace(customerId) {
var url = ctx + "customer/changePlace/" + customerId;
$.modal.open("修改上级分销", url, '600', '300');
}
/* 用户管理-重置密码 */
function resetPwd(customerId) {

View File

@ -42,9 +42,9 @@
<a class="btn btn-danger multiple disabled" onclick="auditStatus(1)" shiro:hasPermission="customer:place:remove">
<i class="fa fa-remove"></i> 拒绝
</a>
<!-- <a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="customer:place:edit">-->
<!-- <i class="fa fa-edit"></i> 修改-->
<!-- </a>-->
<a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="customer:place:edit">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="customer:place:export">
<i class="fa fa-download"></i> 导出
</a>
@ -79,33 +79,17 @@
field: 'name',
title: '名字'
},
// {
// field: 'customerId',
// title: '关联消费者id'
// },
{
field: 'customerId',
title: '关联消费者id'
},
{
field: 'phone',
title: '注册手机号'
},
{
field: 'customerPlaceName',
title: '上级分销'
},
{
field: 'customerPlacePhone',
title: '上级手机号'
},
{
field: 'parentCustomerPlaceName',
title: '最上级分销'
},
{
field: 'parentCustomerPlacePhone',
title: '最上级手机号'
},
{
field: 'cityName',
title: '城市名'
field: 'city',
title: '城市id'
},
{
field: 'status',
@ -123,7 +107,7 @@
align: 'center',
formatter: function(value, row, index) {
var actions = [];
// actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.id + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.id + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.id + '\')"><i class="fa fa-remove"></i>删除</a>');
return actions.join('');
}

View File

@ -46,18 +46,6 @@
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<label class="col-xs-2 control-label">保险设定:</label>
<div class="col-xs-10">
<label th:each="insurance:${insurances}" class="check-box">
<input name="insurance" type="checkbox" th:value="${insurance.id}" th:text="${insurance.companyName}">
</label>
</div>
</div>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
@ -99,39 +87,10 @@
function submitHandler() {
if ($.validate.form()) {
// 方法一使用saveModal新增成功后不刷新表格只显示提示信息
//$.operate.saveModal(prefix + "/add", $('#form-dept-add').serialize());
// 方法二使用自定义Ajax保存如果需要更多控制
customSave();
$.operate.save(prefix + "/add", $('#form-dept-add').serialize());
}
}
// 自定义保存方法(可选)
function customSave() {
$.ajax({
url: prefix + "/add",
type: "post",
dataType: "json",
data: $('#form-dept-add').serialize(),
beforeSend: function () {
$.modal.loading("正在处理中,请稍候...");
},
success: function(result) {
$.modal.closeLoading();
if (result.code == web_status.SUCCESS) {
$.modal.alertSuccess(result.msg);
// 如果需要关闭窗口,取消注释下面这行
$.modal.close();
} else if (result.code == web_status.WARNING) {
$.modal.alertWarning(result.msg);
} else {
$.modal.alertError(result.msg);
}
}
});
}
/*部门管理-新增-选择父部门树*/
function selectDeptTree() {
var treeId = $("#treeId").val();

View File

@ -124,29 +124,8 @@
function remove(id) {
$.modal.confirm("确认要删除吗", function () {
customRemove(id);
});
}
function customRemove(id) {
$.ajax({
url: prefix + '/remove/' + id,
type: "post",
dataType: "json",
beforeSend: function () {
$.modal.loading("正在处理中,请稍候...");
},
success: function(result) {
$.modal.closeLoading();
if (result.code == web_status.SUCCESS) {
$.modal.alertSuccess(result.msg);
} else if (result.code == web_status.WARNING) {
$.modal.alertWarning(result.msg);
} else {
$.modal.alertError(result.msg);
}
}
});
$.operate.post(prefix + '/remove/' + id);
})
}
</script>
</body>

View File

@ -17,15 +17,15 @@
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="form-group">-->
<!-- <label class="col-sm-3 control-label is-required">上级类目:</label>-->
<!-- <div class="col-sm-8">-->
<!-- <div class="input-group">-->
<!-- <input class="form-control" type="text" onclick="selectDeptTree()" id="treeName" readonly="true" th:value="${goodsCategoryName}" required>-->
<!-- <span class="input-group-addon"><i class="fa fa-search"></i></span>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<div class="form-group">
<label class="col-sm-3 control-label is-required">上级类目:</label>
<div class="col-sm-8">
<div class="input-group">
<input class="form-control" type="text" onclick="selectDeptTree()" id="treeName" readonly="true" th:value="${goodsCategoryName}" required>
<span class="input-group-addon"><i class="fa fa-search"></i></span>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">类别名称:</label>
<div class="col-sm-8">
@ -48,8 +48,7 @@
<label class="col-sm-3 control-label">类目类别:</label>
<div class="col-sm-8">
<div class="radio-box" th:each="dict : ${@dict.getType('goods_category_type')}">
<input type="radio" th:id="${dict.dictCode}" name="type" th:value="${dict.dictValue}"
th:checked="${goodsCategory.type != null ? goodsCategory.type.toString() == dict.dictValue : dict.default}">
<input type="radio" th:id="${dict.dictCode}" name="type" th:value="${dict.dictValue}" th:checked="${dict.default}">
<label th:for="${dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
@ -63,18 +62,6 @@
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<label class="col-xs-2 control-label">保险设定:</label>
<div class="col-xs-10">
<label th:each="insurance:${insurances}" class="check-box">
<input name="insurance" type="checkbox" th:value="${insurance.id}" th:text="${insurance.companyName}" th:checked="${insurance.flag}">
</label>
</div>
</div>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
@ -116,39 +103,10 @@
function submitHandler() {
if ($.validate.form()) {
var data = $("#form-dept-edit").serializeArray();
var insuranceIds = $.form.selectCheckeds("insurance");
data.push({"name": "insuranceIds", "value": insuranceIds});
// 自定义保存,不刷新表格
customEditSave(data);
$.operate.save(prefix + "/edit", $('#form-dept-edit').serialize());
}
}
// 自定义编辑保存方法
function customEditSave(data) {
$.ajax({
url: prefix + "/edit",
type: "post",
dataType: "json",
data: data,
beforeSend: function () {
$.modal.loading("正在处理中,请稍候...");
},
success: function(result) {
$.modal.closeLoading();
if (result.code == web_status.SUCCESS) {
$.modal.alertSuccess(result.msg);
$.modal.close();
} else if (result.code == web_status.WARNING) {
$.modal.alertWarning(result.msg);
} else {
$.modal.alertError(result.msg);
}
}
});
}
/*部门管理-修改-选择部门树*/
function selectDeptTree() {
var treeId = $("#treeId").val();

View File

@ -1,69 +0,0 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<th:block th:include="include :: header('选择服务类目')" />
<th:block th:include="include :: ztree-css" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-tree">
<div class="form-group">
<label class="col-sm-3 control-label">服务类目:</label>
<div class="col-sm-8">
<div class="input-group">
<input class="form-control" type="text" id="treeName" readonly="true">
<input type="hidden" id="treeId">
<span class="input-group-addon"><i class="fa fa-search"></i></span>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-8">
<div id="tree" class="ztree"></div>
</div>
</div>
<!-- <div class="form-group">
<div class="form-control-static col-sm-offset-9">
<button type="button" class="btn btn-sm btn-primary" onclick="submitHandler()"><i class="fa fa-check"></i>保 存</button>&nbsp;
<button type="button" class="btn btn-sm btn-danger" onclick="closeItem()"><i class="fa fa-reply-all"></i>关 闭</button>
</div>
</div> -->
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: ztree-js" />
<script type="text/javascript">
$(function() {
var url = ctx + "goods/category/serviceTreeData";
var options = {
url: url,
expandLevel: 2,
onClick : zOnClick
};
$.tree.init(options);
});
function zOnClick(event, treeId, treeNode) {
$("#treeId").val(treeNode.id);
$("#treeName").val(treeNode.name);
}
function submitHandler() {
var treeId = $("#treeId").val();
var treeName = $("#treeName").val();
if (treeId == "" || treeName == "") {
$.modal.alertWarning("请选择服务类目");
return;
}
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
}
function closeItem() {
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
}
</script>
</body>
</html>

View File

@ -145,7 +145,9 @@
formatter: function (value, row, index) {
if (row.parentId !== 0) {
var actions = [];
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.deptGoodsCategoryId + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.editTab(\'' + row.deptGoodsCategoryId + '\')"><i class="fa fa-edit"></i>编辑</a> ');
// actions.push('<a class="btn btn-info btn-xs ' + addFlag + '" href="javascript:void(0)" onclick="$.operate.add(\'' + row.deptGoodsCategoryId + '\')"><i class="fa fa-plus"></i>新增</a> ');
// actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="remove(\'' + row.deptGoodsCategoryId + '\')"><i class="fa fa-trash"></i>删除</a>');
return actions.join('');
} else {
return "";

View File

@ -11,7 +11,6 @@
<div class="main-content">
<form class="form-horizontal" id="form-deptGoodsCategory-edit" th:object="${deptGoodsCategory}">
<input id="deptGoodsCategoryId" name="deptGoodsCategoryId" type="hidden" th:field="*{deptGoodsCategoryId}"/>
<input id="type" name="type" type="hidden" th:field="*{type}"/>
<div class="row">
<div class="col-sm-6">
@ -24,21 +23,6 @@
</div>
</div>
</div>
<div class="col-sm-6" th:if="*{type != 1}">
<div class="form-group">
<label class="col-sm-6 control-label">服务类目:</label>
<div class="col-sm-6">
<div class="input-group">
<input class="form-control" type="text" onclick="selectServiceCategoryTree()" id="treeName" readonly="true" th:value="*{serviceCategoryName}">
<input type="hidden" id="treeId" name="serviceCategoryId" th:value="*{serviceCategoryId}">
<input type="hidden" id="serviceCategoryName" name="serviceCategoryName" th:value="*{serviceCategoryName}">
<span class="input-group-addon"><i class="fa fa-search"></i></span>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label class="col-sm-6 control-label is-required">一级分销扣点比例:</label>
@ -49,16 +33,6 @@
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label class="col-sm-6 control-label is-required">PC一级分销扣点比例</label>
<div class="col-sm-6">
<input name="pcOneRate" placeholder="请输入PC一级分销扣点比例" class="form-control" type="text" maxlength="12"
th:field="*{pcOneRate}"
required>
</div>
</div>
</div>
</div>
<div class="row">
@ -72,18 +46,6 @@
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label class="col-sm-6 control-label is-required">PC二级分销扣点比例</label>
<div class="col-sm-6">
<input name="pcTwoRate" placeholder="请输入PC二级分销扣点比例" class="form-control" type="text"
th:field="*{pcTwoRate}"
maxlength="12" required>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label class="col-sm-6 control-label is-required">三级分销扣点比例:</label>
@ -94,16 +56,6 @@
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label class="col-sm-6 control-label is-required">PC三级分销扣点比例</label>
<div class="col-sm-6">
<input name="pcThreeRate" placeholder="PC请输入三级分销扣点比例" class="form-control" type="text" maxlength="12"
th:field="*{pcThreeRate}"
required>
</div>
</div>
</div>
</div>
<div class="row">
@ -117,19 +69,6 @@
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label class="col-sm-6 control-label is-required">PC平台扣点比例</label>
<div class="col-sm-6">
<input name="pcDeptRate" placeholder="请输入PC平台扣点比例" class="form-control" type="text"
th:field="*{pcDeptRate}"
maxlength="12" required>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label class="col-sm-6 control-label is-required">平台固定扣金额:</label>
@ -140,16 +79,6 @@
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label class="col-sm-6 control-label is-required">PC平台固定扣金额</label>
<div class="col-sm-6">
<input name="pcDeptMoney" placeholder="请输入PC平台固定扣金额" class="form-control" type="text" maxlength="12"
th:field="*{pcDeptMoney}"
required>
</div>
</div>
</div>
</div>
<div class="row">
@ -163,19 +92,6 @@
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label class="col-sm-6 control-label is-required">PC截留扣点</label>
<div class="col-sm-6">
<input name="pcRetainRate" placeholder="请输入PC截留扣点" class="form-control" type="text"
th:field="*{pcRetainRate}"
maxlength="12" required>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label class="col-sm-6 control-label is-required">截留金额:</label>
@ -186,16 +102,6 @@
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label class="col-sm-6 control-label is-required">PC截留金额</label>
<div class="col-sm-6">
<input name="pcRetainMoney" placeholder="请输入PC截留金额" class="form-control" type="text" maxlength="12"
th:field="*{pcRetainMoney}"
required>
</div>
</div>
</div>
</div>
<div class="row">
@ -254,38 +160,12 @@
</div>
<div class="col-sm-6">
<div class="form-group">
<label class="col-sm-6 control-label">倒计时小时数</label>
<label class="col-sm-6 control-label">是否需要保险</label>
<div class="col-sm-6">
<input name="countdownHours" placeholder="请输入倒计时小时数" class="form-control" type="number" min="1" max="168"
th:field="*{countdownHours}">
</div>
</div>
</div>
</div>
<div class="row">
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<label class="col-xs-3 control-label">PC保险设定</label>
<div class="col-xs-9">
<label th:each="insurance:${pcInsurances}" class="check-box">
<input name="pcInsurance" type="checkbox" th:value="${insurance.id}" th:text="${insurance.insuranceName}" th:checked="${insurance.flag}">
</label>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<label class="col-xs-3 control-label">商城保险设定:</label>
<div class="col-xs-9">
<label th:each="insurance:${shopInsurances}" class="check-box">
<input name="shopInsurance" type="checkbox" th:value="${insurance.id}" th:text="${insurance.insuranceName}" th:checked="${insurance.flag}">
</label>
</div>
<select name="isSure" class="form-control m-b" th:field="*{isSure}" th:with="type=${@dict.getType('sys_user_sex')}">
<option th:text="否" th:value="0"/>
<option th:text="是" th:value="1"/>
</select>
</div>
</div>
</div>
@ -333,10 +213,6 @@
function submitHandler() {
if ($.validate.form()) {
var data = $("#form-deptGoodsCategory-edit").serializeArray();
var pcInsuranceIds = $.form.selectCheckeds("pcInsurance");
var shopInsuranceIds = $.form.selectCheckeds("shopInsurance");
data.push({"name": "pcInsuranceIds", "value": pcInsuranceIds});
data.push({"name": "shopInsuranceIds", "value": shopInsuranceIds});
$.operate.saveTab(prefix + "/edit", data);
$.modal.close();
}
@ -398,26 +274,6 @@
}
});
/*选择服务类目树*/
function selectServiceCategoryTree() {
var treeId = $("#treeId").val();
var options = {
title: '服务类目选择',
width: "380",
url: ctx + "goods/category/selectServiceCategoryTree",
callBack: doSubmit
};
$.modal.openOptions(options);
}
function doSubmit(index, layero) {
var body = $.modal.getChildFrame(index);
$("#treeId").val(body.find('#treeId').val());
$("#treeName").val(body.find('#treeName').val());
$("#serviceCategoryName").val(body.find('#treeName').val());
$.modal.close(index);
}
</script>
</body>
</html>

View File

@ -1,55 +0,0 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('新增保险管理')" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-manager-add">
<div class="form-group">
<label class="col-sm-3 control-label">保险公司名称:</label>
<div class="col-sm-8">
<input name="companyName" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">保险项目名称:</label>
<div class="col-sm-8">
<input name="insuranceName" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">保险费用:</label>
<div class="col-sm-8">
<input name="insuranceAmount" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">保险条例url</label>
<div class="col-sm-8">
<textarea name="insuranceUrl" class="form-control"></textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">备注:</label>
<div class="col-sm-8">
<input name="remark" class="form-control" type="text">
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var prefix = ctx + "goods/manager"
$("#form-manager-add").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/add", $('#form-manager-add').serialize());
}
}
</script>
</body>
</html>

View File

@ -1,56 +0,0 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('修改保险管理')" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-manager-edit" th:object="${insuranceManager}">
<input name="id" th:field="*{id}" type="hidden">
<div class="form-group">
<label class="col-sm-3 control-label">保险公司名称:</label>
<div class="col-sm-8">
<input name="companyName" th:field="*{companyName}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">保险项目名称:</label>
<div class="col-sm-8">
<input name="insuranceName" th:field="*{insuranceName}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">保险费用:</label>
<div class="col-sm-8">
<input name="insuranceAmount" th:field="*{insuranceAmount}" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">保险条例url</label>
<div class="col-sm-8">
<textarea name="insuranceUrl" class="form-control">[[*{insuranceUrl}]]</textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">备注:</label>
<div class="col-sm-8">
<input name="remark" th:field="*{remark}" class="form-control" type="text">
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var prefix = ctx + "goods/manager";
$("#form-manager-edit").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/edit", $('#form-manager-edit').serialize());
}
}
</script>
</body>
</html>

View File

@ -1,110 +0,0 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('保险管理列表')" />
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="formId">
<div class="select-list">
<ul>
<li>
<label>保险公司名称:</label>
<input type="text" name="companyName"/>
</li>
<li>
<label>保险项目名称:</label>
<input type="text" name="insuranceName"/>
</li>
<li>
<label>保险费用:</label>
<input type="text" name="insuranceAmount"/>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i>&nbsp;重置</a>
</li>
</ul>
</div>
</form>
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="goods:manager:add">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="goods:manager:edit">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="goods:manager:remove">
<i class="fa fa-remove"></i> 删除
</a>
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="goods:manager:export">
<i class="fa fa-download"></i> 导出
</a>
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('goods:manager:edit')}]];
var removeFlag = [[${@permission.hasPermi('goods:manager:remove')}]];
var prefix = ctx + "goods/manager";
$(function() {
var options = {
url: prefix + "/list",
createUrl: prefix + "/add",
updateUrl: prefix + "/edit/{id}",
removeUrl: prefix + "/remove",
exportUrl: prefix + "/export",
modalName: "保险管理",
columns: [{
checkbox: true
},
{
field: 'id',
title: '主键',
visible: false
},
{
field: 'companyName',
title: '保险公司名称'
},
{
field: 'insuranceName',
title: '保险项目名称'
},
{
field: 'insuranceAmount',
title: '保险费用'
},
{
field: 'insuranceUrl',
title: '保险条例url'
},
{
field: 'remark',
title: '备注'
},
{
title: '操作',
align: 'center',
formatter: function(value, row, index) {
var actions = [];
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.id + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.id + '\')"><i class="fa fa-remove"></i>删除</a>');
return actions.join('');
}
}]
};
$.table.init(options);
});
</script>
</body>
</html>

View File

@ -2,14 +2,8 @@
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<th:block th:include="include :: header('模板新增')"/>
<th:block th:include="include :: layout-latest-css"/>
<th:block th:include="include :: bootstrap-fileinput-css"/>
<style>
body {
padding: 0 !important;
}
.pane1 {
padding-bottom: 0;
}
@ -20,7 +14,6 @@
.template-div {
display: inline-block;
margin-right: 10px;
}
.template-body {
@ -74,44 +67,9 @@
color: red;
font-size: large;
}
.multiply-symbol {
font-size: large;
text-align: center;
}
.goodsNumList {
padding: 5px 8px 14px 5px;
min-height: 40px;
border: 1px solid #dcdfe6;
box-sizing: border-box;
border-radius: 4px;
}
.oneGoodsNumList {
padding: 5px 8px 5px 5px;
min-height: 40px;
border: 1px solid #dcdfe6;
box-sizing: border-box;
border-radius: 4px;
}
.goodsNum {
margin: 2px 0;
height: 24px;
}
#categoryCxSelect {
z-index: 101
}
#categoryCxSelect .eo-cascader-menu:nth-child(-n+3) .has-child label {
display: none;
}
</style>
<th:block th:include="include :: datetimepicker-css" />
<link rel="stylesheet" href="../../../static/css/cascader.css" th:href="@{/css/cascader.css}">
</head>
<body class="gray-bg">
<form id="addTemplateForm">
@ -131,24 +89,22 @@
<div class="form-horizontal m">
<div class="form-group">
<label class="col-sm-2 control-label is-required">服务类目:</label>
<div class="col-sm-6" style="padding-right: 0">
<div id="categoryCxSelect" class="cascader-wrap">
<!-- <div class="col-sm-3">-->
<!-- <select class="category1 form-control m-b" name="category1" required></select>-->
<!-- </div>-->
<!-- <div class="col-sm-3">-->
<!-- <select class="category2 form-control m-b" name="category2" required></select>-->
<!-- </div>-->
<!-- <div class="col-sm-3">-->
<!-- <select class="category3 form-control m-b" name="category3" required></select>-->
<!-- </div>-->
<!-- <div class="col-sm-3">-->
<!-- <select class="category4 form-control m-b" name="category4" required></select>-->
<!-- </div>-->
<div id="categoryCxSelect" class="col-sm-6 row">
<div class="col-sm-3">
<select class="category1 form-control m-b" name="category1" required></select>
</div>
<div class="col-sm-3">
<select class="category2 form-control m-b" name="category2" required></select>
</div>
<div class="col-sm-3">
<select class="category3 form-control m-b" name="category3" required></select>
</div>
<div class="col-sm-3">
<select class="category4 form-control m-b" name="category4" required></select>
</div>
</div>
<div class="col-sm-1 multiply-symbol">×</div>
<div id="goodsNumList" class="col-sm-1 oneGoodsNumList">
<div class="col-sm-1">×</div>
<div class="col-sm-1">
<input type="number" name="goodsNum" class="form-control" required>
</div>
</div>
@ -175,17 +131,20 @@
<div class="col-sm-4">
<div class="input-group date">
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
<input type="text" class="form-control" id="servDate" name="servDate" required readonly style="background: white;">
<input type="text" class="form-control" id="servDate" name="servDate" required>
</div>
</div>
<div class="col-sm-4">
<select class="form-control" name="servTime" required>
<option value="08:00-10:00">08:00-10:00</option>
<option value="10:00-12:00">10:00-12:00</option>
<option value="12:00-14:00">12:00-14:00</option>
<option value="14:00-16:00">14:00-16:00</option>
<option value="16:00-18:00">16:00-18:00</option>
<option value="18:00-20:00">18:00-20:00</option>
<option value="8:00-12:00">8:00-12:00</option>
<option value="8:00-12:00">12:00-16:00</option>
<option value="8:00-12:00">16:00-20:00</option>
<option value="8:00-12:00">8:00-10:00</option>
<option value="8:00-12:00">10:00-12:00</option>
<option value="8:00-12:00">12:00-14:00</option>
<option value="8:00-12:00">14:00-16:00</option>
<option value="8:00-12:00">16:00-18:00</option>
<option value="8:00-12:00">18:00-20:00</option>
</select>
</div>
</div>
@ -200,27 +159,26 @@
<div class="form-group">
<label class="col-sm-2 control-label is-required">图片上传:</label>
<div class="col-sm-8">
<input type="text" name="imageUrl" value="" hidden>
<input type="file" name="imageUrlStr" id="imageUrlStr" multiple class="file" />
<div class="file-loading">
<input id="multipleFile" name="files" type="file" multiple>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label is-required">服务地址:</label>
<div class="col-sm-6">
<div id="areaCxSelect" class="cascader-wrap">
<!-- <div class="col-sm-3">-->
<!-- <select class="province form-control m-b" name="province" id="province" required onchange="selectRegion('province', 'city')"></select>-->
<!-- </div>-->
<!-- <div class="col-sm-3">-->
<!-- <select class="city form-control m-b" name="city" id="city" required onchange="selectRegion('city', 'district')"></select>-->
<!-- </div>-->
<!-- <div class="col-sm-3">-->
<!-- <select class="district form-control m-b" name="district" id="district" required onchange="selectRegion('district', 'street')"></select>-->
<!-- </div>-->
<!-- <div class="col-sm-3">-->
<!-- <select class="street form-control m-b" name="streetId" id="streetId" required></select>-->
<!-- </div>-->
<div id="areaCxSelect" class="col-sm-6 row">
<div class="col-sm-3">
<select class="province form-control m-b" name="province" id="province" required onchange="selectRegion('province', 'city')"></select>
</div>
<div class="col-sm-3">
<select class="city form-control m-b" name="city" id="city" required onchange="selectRegion('city', 'district')"></select>
</div>
<div class="col-sm-3">
<select class="district form-control m-b" name="district" id="district" required onchange="selectRegion('district', 'street')"></select>
</div>
<div class="col-sm-3">
<select class="street form-control m-b" name="streetId" id="streetId" required></select>
</div>
</div>
</div>
@ -243,15 +201,15 @@
<div class="form-group">
<label class="col-sm-2 control-label is-required">下单模式:</label>
<div class="col-sm-8 row" id="orderModeRadioGroup">
<div class="col-sm-8 row">
<div class="col-sm-2">
<label><input type="radio" value="02" name="orderMode" checked > 带价发布</label>
<label><input type="radio" checked="" value="1" name="orderMode"> 带价发布</label>
</div>
<div class="col-sm-2">
<label><input type="radio" value="01" name="orderMode"> 一票价发布</label>
<label><input type="radio" value="2" name="orderMode"> 一票价发布</label>
</div>
<div class="col-sm-2">
<label><input type="radio" value="03" name="orderMode"> 回收模式</label>
<label><input type="radio" value="3" name="orderMode"> 回收模式</label>
</div>
</div>
</div>
@ -272,7 +230,7 @@
</div>
<div class="col-sm-2">
<div class="input-group">
<input type="text" name="informationFee" class="form-control" placeholder="信息费">
<input type="text" name="informationFee" class="form-control" required placeholder="信息费">
<div class="input-group-btn">
<button data-toggle="dropdown" class="btn btn-white dropdown-toggle dropdown-btn" type="button" id="informationFeeUnit">单位<span class="caret"></span></button>
<ul class="dropdown-menu pull-right">
@ -345,12 +303,8 @@
<div class="oper-banner-end col-sm-5">
<div class="m-r">
<div class="checkbox">
<a href="#" shiro:hasPermission="consult:order:add"><input id="consultOrder" type="checkbox" value="02" name="consultOrder" onclick="changeConsultOrder(this)" >合约订单</a>
</div>
</div>
<div class="m-r">
<div class="checkbox">
<label><input id="payOnDoorMode" type="checkbox" value="02" name="payMode" onclick="changePayOnDoorMode(this)">上门到付/保外单</label>
<label>
<input type="checkbox" value="1" name="isPayOffline">线下到付</label>
</div>
</div>
<div class="m-r">
@ -366,33 +320,10 @@
</form>
<th:block th:include="include :: footer"/>
<th:block th:include="include :: layout-latest-js"/>
<th:block th:include="include :: jquery-cxselect-js" />
<th:block th:include="include :: datetimepicker-js" />
<th:block th:include="include :: bootstrap-fileinput-js"/>
<script th:src="@{/js/plugins/miniCascader/cascader.js}"></script>
<script th:src="@{/data/four-level-area.js}"></script>
<script type="text/javascript">
// 级联下拉
let categoryCascader = new eo_cascader([], {
elementID: 'categoryCxSelect',
multiple: true, // 是否多选
separator: '-', // 分割符 山西-太原-小店区 || 山西/太原/小店区
clearable: true, // 是否可一键删除已选
value: 'goodsCategoryId',
label: 'goodsCategoryName',
children: 'child',
checkedCallback: checkedCategoryCallback
});
let areaCascader = new eo_cascader(fourLevelAreaList, {
elementID: 'areaCxSelect',
multiple: false, // 是否多选
separator: '-', // 分割符 山西-太原-小店区 || 山西/太原/小店区
clearable: false, // 是否可一键删除已选
value: 'areaId',
label: 'areaName',
children: 'child'
});
$(function(){
var icon = "<i class='fa fa-times-circle'></i> ";
// $("#addTemplateForm").validate({
@ -402,6 +333,7 @@
// }
// });
// 级联下拉
$.ajax({
type: "POST",
dataType:"json",
@ -410,47 +342,36 @@
contentType: 'application/json',
success: function (result) {
if (result.code == web_status.SUCCESS) {
<!-- $('#categoryCxSelect').cxSelect({-->
<!-- selects: ['category1', 'category2', 'category3', 'category4'],-->
<!-- jsonValue: 'deptGoodsCategoryId',-->
<!-- jsonName: 'goodsCategoryName',-->
<!-- jsonSub: 'child',-->
<!-- data: result.data-->
<!-- });-->
categoryCascader = new eo_cascader(result.data, {
elementID: 'categoryCxSelect',
multiple: true, // 是否多选
checkedValue: null,
separator: '-', // 分割符 山西-太原-小店区 || 山西/太原/小店区
clearable: true, // 是否可一键删除已选
value: 'deptGoodsCategoryId',
label: 'goodsCategoryName',
children: 'child',
checkedCallback: checkedCategoryCallback
})
$('#categoryCxSelect').cxSelect({
selects: ['category1', 'category2', 'category3', 'category4'],
jsonValue: 'deptGoodsCategoryId',
jsonName: 'goodsCategoryName',
jsonSub: 'child',
data: result.data
});
} else {
$.modal.msgError("数据加载错误,请重试!")
}
}
})
<!-- $.ajax({-->
<!-- type: "POST",-->
<!-- dataType:"json",-->
<!-- url: ctx + "system/area/list",-->
<!-- success: function (result) {-->
<!-- if (result.code == web_status.SUCCESS) {-->
<!-- $('#areaCxSelect').cxSelect({-->
<!-- selects: ['province', 'city', 'district', 'street'],-->
<!-- jsonValue: 'areaId',-->
<!-- jsonName: 'areaName',-->
<!-- data: result.data-->
<!-- });-->
<!-- } else {-->
<!-- $.modal.msgError("数据加载错误,请重试!")-->
<!-- }-->
<!-- }-->
<!-- })-->
$.ajax({
type: "POST",
dataType:"json",
url: ctx + "system/area/list",
success: function (result) {
if (result.code == web_status.SUCCESS) {
$('#areaCxSelect').cxSelect({
selects: ['province', 'city', 'district', 'street'],
jsonValue: 'areaId',
jsonName: 'areaName',
data: result.data
});
} else {
$.modal.msgError("数据加载错误,请重试!")
}
}
})
$("#servDate").datetimepicker({
format: "yyyy-mm-dd",
@ -488,157 +409,45 @@
// })
});
function checkedCategoryCallback() {
let checkedIdArr = categoryCascader.getCheckedByID();
if (checkedIdArr && checkedIdArr.length > 0) {
$('#goodsNumList').html(null);
$('#goodsNumList').removeClass('oneGoodsNumList');
$('#goodsNumList').addClass('goodsNumList');
checkedIdArr.forEach(function(id, index) {
$('#goodsNumList').append('<input type="number" name="goodsNum' + id + '" class="form-control goodsNum" required>');
});
} else {
$('#goodsNumList').removeClass('goodsNumList');
$('#goodsNumList').addClass('oneGoodsNumList');
$('#goodsNumList').html('<input type="number" name="goodsNum" class="form-control" required>');
}
}
function changeInformationFeeUnit(unit) {
this.$('#informationFeeUnit').html(unit + '<span class="caret"></span>');
}
<!-- function selectRegion(regionLevelName, nextRegionLevelName) {-->
<!-- var regionId = $("#" + regionLevelName).val();-->
<!-- if ($.common.isEmpty(regionId)) {-->
<!-- return;-->
<!-- }-->
function selectRegion(regionLevelName, nextRegionLevelName) {
var regionId = $("#" + regionLevelName).val();
if ($.common.isEmpty(regionId)) {
return;
}
<!-- //Ajax调用处理-->
<!-- $.ajax({-->
<!-- type: "POST",-->
<!-- dataType:"json",-->
<!-- url: ctx + "system/area/list",-->
<!-- data: {parentCode: regionId},-->
<!-- success: function (result) {-->
<!-- if (result.code == web_status.SUCCESS) {-->
<!-- $('#areaCxSelect').cxSelect({-->
<!-- selects: [nextRegionLevelName],-->
<!-- jsonValue: 'areaId',-->
<!-- jsonName: 'areaName',-->
<!-- data: result.data-->
<!-- });-->
<!-- } else {-->
<!-- $.modal.msgError("数据加载错误,请重试!")-->
<!-- }-->
<!-- }-->
<!-- })-->
<!-- }-->
function changeConsultOrder(e){
if ($(e).is(':checked')) {
$('#consultOrder').prop("value", '01');
//Ajax调用处理
$.ajax({
type: "POST",
dataType:"json",
url: ctx + "system/area/list",
data: {parentCode: regionId},
success: function (result) {
if (result.code == web_status.SUCCESS) {
$('#areaCxSelect').cxSelect({
selects: [nextRegionLevelName],
jsonValue: 'areaId',
jsonName: 'areaName',
data: result.data
});
} else {
$('#consultOrder').prop("value", '02');
$.modal.msgError("数据加载错误,请重试!")
}
}
})
}
function changePayOnDoorMode(e) {
if ($(e).is(':checked')) {
$('#payOnDoorMode').prop("value", '01');
} else {
$('#payOnDoorMode').prop("value", '02');
}
}
function validSpecialComponent() {
// 类目
let categoryIds = categoryCascader.getCheckedByID();
if (!categoryIds || categoryIds.length === 0) {
$.modal.msgError("服务类目不能为空")
return false;
}
// 图片是否上传
if (!$('input[name=imageUrl]').val()) {
$.modal.msgError("图片未上传")
return false;
}
// 地区
let checkedAreaPathList = areaCascader.getCheckedPaths();
if (!checkedAreaPathList || checkedAreaPathList.length === 0) {
$.modal.msgError("服务地址不能为空")
return false;
}
// 下单模式
if (!$('#orderModeRadioGroup input[name=orderMode]').is(':checked')) {
$.modal.msgError("请录入完整必填信息")
return false;
}
return true;
}
function translateForm(data) {
function submitOrder() {
if ($.validate.form()) {
var data = $("#addTemplateForm").serializeArray();
var params= {};
data.forEach(function (item){
params[item.name] = item.value;
});
let categoryIds = categoryCascader.getCheckedByID();
let orderGoodsStandards = [];
categoryIds.forEach(function (item){
orderGoodsStandards.push({
deptCategoryId: item,
goodsStandardNum: $(".goodsNum[name=goodsNum" + item + "]").val()
});
});
params.orderGoodsStandards = orderGoodsStandards;
params.categoryId1 = categoryCascader.getCheckedPaths()[0][0];
params.categoryId2 = categoryCascader.getCheckedPaths()[0][1];
params.categoryId3 = categoryCascader.getCheckedPaths()[0][2];
params.provinceId = areaCascader.getCheckedPaths()[0][0];
params.cityId = areaCascader.getCheckedPaths()[0][1];
params.districtId = areaCascader.getCheckedPaths()[0][2];
params.streetId = areaCascader.getCheckedPaths()[0][3];
params.payMode = $('#payOnDoorMode').val();
params.consultMode = $('#consultOrder').val();
return params;
}
// 营业执照上传
$('#imageUrlStr').fileinput({
language: 'zh', //设置语言
dropZoneEnabled: false, //是否显示拖拽区域
showPreview: false,
uploadExtraData: {
"name": "imageUrlStr"
},
dropZoneTitle: "可以将图片拖放到这里", //拖拽区域显示文字
uploadUrl: ctx + 'tool/qiniu/dept/upload', //上传路径
allowedFileExtensions: ['jpg', 'png', 'gif', 'jpeg'], //指定上传文件类型
maxFileSize: 0,
maxFileSize: 2048, //上传文件最大值单位kb
uploadAsync: true, //异步上传
maxFileCount: 2 //上传文件最大个数。
}).on("fileuploaded", function(event,data) { //异步上传成功后回调
if(data.response.code === 0){
$("input[name='imageUrl']").val(data.response.url)
}else {
alert("上传失败!");
}
});
function submitOrder() {
if (!validSpecialComponent()) return;
if ($.validate.form()) {
var data = $("#addTemplateForm").serializeArray();
var params= translateForm(data);
$.ajax({
type: "POST",
dataType:"json",
@ -647,37 +456,22 @@
contentType: 'application/json',
success: function (result) {
if (result.code == web_status.SUCCESS) {
layer.open({
type: 0,
area: ['250px', '180px'],
fix: false,
//不固定
maxmin: true,
shade: 0.3,
title: '系统通知',
content: '发单成功,是否前往发单管理?',
btn: ['确定','继续下单'],
// 弹层外区域关闭
shadeClose: true,
yes: function(index) {
$.modal.parentTab('发单管理', 'order/master/pc');
}
});
$.modal.msgSuccess("提交成功")
} else {
$.modal.msgError(result.msg)
$.modal.msgError("请求失败")
}
}
})
} else {
$.modal.msgError("请录入完整必填信息")
}
}
function addTemplate() {
if (!validSpecialComponent()) return;
if ($.validate.form()) {
var data = $("#addTemplateForm").serializeArray();
var params= translateForm(data);
var params= {};
data.forEach(function (item){
params[item.name] = item.value;
});
$.ajax({
type: "POST",
@ -689,7 +483,7 @@
if (result.code == web_status.SUCCESS) {
$.modal.msgSuccess("提交成功")
} else {
$.modal.msgError(result.msg)
$.modal.msgError("请求失败")
}
}
})

View File

@ -30,7 +30,7 @@
<script th:src="@{/ajax/libs/validate/jquery.validate.extend.js?v=1.19.3}"></script>
<script th:src="@{/ajax/libs/validate/messages_zh.js?v=1.19.3}"></script>
<!-- bootstrap-table 表格树插件 -->
<script th:src="@{/ajax/libs/bootstrap-table/extensions/tree/bootstrap-table-tree.js?v=1.18.3}"></script>
<script th:src="@{/ajax/libs/bootstrap-table/extensions/tree/bootstrap-table-tree.min.js?v=1.18.3}"></script>
<!-- 遮罩层 -->
<script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js?v=2.70.0}"></script>
<script th:src="@{/ajax/libs/iCheck/icheck.min.js?v=1.0.3}"></script>

View File

@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="renderer" content="webkit">
<title>管理系统</title>
<title>工圈子管理系统</title>
<!-- 避免IE使用兼容模式 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link th:href="@{favicon.ico}" rel="shortcut icon"/>
@ -26,7 +26,7 @@
</div>
<a th:href="@{/index}">
<li class="logo hidden-xs">
<span class="logo-lg">后台系统</span>
<span class="logo-lg">工圈子</span>
</li>
</a>
<div class="sidebar-collapse">

View File

@ -3,8 +3,8 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<title>叮咚工链</title>
<meta name="description" content="后台管理框架">
<title>追风者</title>
<meta name="description" content="叮咚工链后台管理框架">
<link href="../static/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
<link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
<link href="../static/css/style.min.css" th:href="@{/css/style.min.css}" rel="stylesheet"/>
@ -26,13 +26,14 @@
<div class="col-sm-7">
<div class="signin-info">
<div class="logopanel m-b">
<h1>[ 后台管理系统 ]</h1>
<h1>[ 叮咚工链 ]</h1>
</div>
<div class="m-b"></div>
<h4>欢迎使用 <strong>后台管理系统</strong></h4>
<h4>欢迎使用 <strong>叮咚工链 后台管理系统</strong></h4>
<ul class="m-b">
<li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> 再多平方米</li>
<li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> 不如我懂你</li>
<li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> 叮咚工链</li>
<li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> 在你需要的时候</li>
<li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> 总在您身边</li>
</ul>
@ -64,9 +65,8 @@
</div>
<div class="signup-footer">
<div class="pull-left">
Copyright © 2018-2021 gmjlb.com All Rights Reserved. <br>
<a href="https://beian.miit.gov.cn/" target="_blank">备案号:</a>
<a href="https://beian.miit.gov.cn/" target="_blank">桂ICP备2024024616号-3</a>
Copyright © 2018-2021 opsoul.com All Rights Reserved. <br>
备案号 粤ICP备2021044349号-1
</div>
</div>
</div>

View File

@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--360浏览器优先以webkit内核解析-->
<title>介绍</title>
<title>工圈子介绍</title>
<link rel="shortcut icon" href="favicon.ico">
<link href="../static/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
<link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
@ -22,11 +22,14 @@
<br>
</div>
<div class="col-sm-5">
<h2>后台管理框架</h2>
<p>一直想做一款后台管理系统,看了很多优秀的开源项目但是发现没有合适自己的。于是利用空闲休息时间开始自己写一套后台系统。如此有了管理系统。她可以用于所有的Web应用程序<b>网站管理后台</b><b>网站会员中心</b><b>CMS</b><b>CRM</b><b>OA</b>等等,当然,您也可以对她进行深度定制,以做出更强系统。所有前端后台代码封装过后十分精简易上手,出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。</p>
<h2>工圈子后台管理框架</h2>
<p>一直想做一款后台管理系统,看了很多优秀的开源项目但是发现没有合适自己的。于是利用空闲休息时间开始自己写一套后台系统。如此有了工圈子管理系统。她可以用于所有的Web应用程序<b>网站管理后台</b><b>网站会员中心</b><b>CMS</b><b>CRM</b><b>OA</b>等等,当然,您也可以对她进行深度定制,以做出更强系统。所有前端后台代码封装过后十分精简易上手,出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。</p>
<p>
<b>当前版本:</b><span>v[[${version}]]</span>
</p>
<p>
<span class="label label-warning">叮咚链家</span>
</p>
<br>
</div>
<div class="col-sm-4">

View File

@ -1,289 +0,0 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<th:block th:include="include :: header('指派师傅')"/>
<th:block th:include="include :: layout-latest-css"/>
<style>
.custom-container {
padding: 0 30px 20px 30px;
}
.flex-board {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
}
.flex-board-no-wrap {
display: flex;
justify-content: flex-start;
align-items: center;
}
.flex-board.select-content {
flex-basis: 100%
}
.flex-board.select-content .flex-board-no-wrap {
flex-basis: 90%
}
.flex-board.input-content {
flex-basis: 50%;
}
.flex-board.input-content input {
flex-basis: 75%
}
.specCanAssignNum {
text-align: center;
line-height: 31px;
}
</style>
</head>
<body class="gray-bg">
<div class="animated fadeInRight row custom-container">
<div class="col-sm-12 search-collapse">
<form class="m" id="canAssignSpecForm">
<div id="canAssignSpecList" class="m-b">
</div>
<div class="row">
<div class="col-sm-4">
<span>派单金额:</span>
<span id="moneyCanAssign"></span>
<span></span>
</div>
<!-- <div class="col-sm-5">-->
<!-- <div class="flex-board input-content">-->
<!-- <label class="form-control-label">派出金额:</label>-->
<!-- <input name="totalPay" type="number" class="form-control">-->
<!-- </div>-->
<!-- </div>-->
</div>
</form>
</div>
<div class="col-sm-12 search-collapse">
<form class="flex-board m" id="workerForm">
<div class="flex-board select-content m-t">
<label class="form-control-label">区域筛选:</label>
<div id="areaCxSelect" class="flex-board-no-wrap">
<select class="province form-control cx-select-input m-r" name="province" id="province" data-first-title="选择省" onchange="selectRegion('province', 'city')"></select>
<select class="city form-control cx-select-input m-r" name="city" id="city" data-first-title="选择市" onchange="selectRegion('city', 'district')"></select>
<select class="district form-control cx-select-input m-r" name="areaId" id="district" data-first-title="选择区" onchange="selectRegion('district', 'street')"></select>
<select class="street form-control cx-select-input m-r" name="streetId" id="streetId" data-first-title="选择街道" ></select>
</div>
</div>
<div class="flex-board select-content m-t">
<label class="form-control-label">类别筛选:</label>
<div id="categoryCxSelect" class="flex-board-no-wrap">
<select class="category1 form-control cx-select-input m-r" name="category1" id="category1" data-first-title="选择一类"></select>
<select class="category2 form-control cx-select-input m-r" name="category2" id="category2" data-first-title="选择二类"></select>
<select class="category3 form-control cx-select-input m-r" name="goodsCategoryId" id="category3" data-first-title="选择三类"></select>
<select class="category4 form-control cx-select-input m-r" name="category4" id="category4" data-first-title="选择四类" ></select>
</div>
</div>
<div class="flex-board input-content m-t">
<label class="form-control-label">名称/手机号:</label>
<input name="keyWords" type="text" class="form-control normal-input m-r">
</div>
<div class="m-t">
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search('workerForm')"><i
class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset('workerForm')"><i
class="fa fa-refresh"></i>&nbsp;重置</a>
</div>
</form>
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
<th:block th:include="include :: footer"/>
<th:block th:include="include :: jquery-cxselect-js" />
<script type="text/javascript">
var orderMasterId = '[[${orderId}]]';
var prefix = ctx + "worker"
$(function () {
loadCanAssignSpecInfo();
initForm();
initTable();
});
function loadCanAssignSpecInfo() {
$.ajax({
type: "POST",
dataType:"json",
url: ctx + "order/can/assign",
data: JSON.stringify({orderMasterId: orderMasterId}),
contentType: 'application/json',
success: function (result) {
if (result.code == web_status.SUCCESS) {
$('#canAssignSpecList').html('');
$.each(result.data, function(index, spec) {
$('#canAssignSpecList').append(
'<div class="row m-b">' +
' <div class="col-sm-6">' +
' <input disabled class="form-control" value="' + spec.goodsName +'">' +
' </div>' +
' <div class="col-sm-2 specCanAssignNum">' +
spec.goodsNum +
' </div>' +
'</div>'
)
});
} else {
$.modal.msgError("数据加载错误,请重试!")
}
}
})
$.ajax({
type: "POST",
dataType:"json",
url: ctx + "order/master/app/detail",
data: JSON.stringify({id: orderMasterId}),
contentType: 'application/json',
success: function (result) {
if (result.code == web_status.SUCCESS) {
$('#moneyCanAssign').html(result.data.serverMoney);
} else {
$.modal.msgError("数据加载错误,请重试!")
}
}
})
}
function initForm() {
$.ajax({
type: "POST",
dataType:"json",
url: ctx + "system/area/list",
success: function (result) {
if (result.code == web_status.SUCCESS) {
$('#areaCxSelect').cxSelect({
selects: ['province', 'city', 'district', 'street'],
jsonValue: 'areaId',
jsonName: 'areaName',
data: result.data
});
} else {
$.modal.msgError("数据加载错误,请重试!")
}
}
})
$.ajax({
type: "POST",
dataType:"json",
url: ctx + "goods/deptcategory/app/list",
data: JSON.stringify({deptId: 101, goodsCategoryId: 1}),
contentType: 'application/json',
success: function (result) {
if (result.code == web_status.SUCCESS) {
$('#categoryCxSelect').cxSelect({
selects: ['category1', 'category2', 'category3', 'category4'],
jsonValue: 'goodsCategoryId',
jsonName: 'goodsCategoryName',
jsonSub: 'child',
data: result.data
});
} else {
$.modal.msgError("数据加载错误,请重试!")
}
}
})
}
function initTable() {
var options = {
url: prefix + "/list",
modalName: "师傅派单列表",
firstLoad: false,
columns: [
{
checkbox: true
}, {
field: 'name',
title: '人员名称',
align: "left"
}, {
field: 'phone',
title: '手机号',
align: "left"
}, {
title: '操作',
align: 'left',
formatter: function (value, row, index) {
var actions = [];
actions.push('<a class="btn btn-success btn-xs" href="javascript:void(0)" onclick="assign(' + row.workerId + ')">指派</a> ');
return actions.join('');
}
}
]
};
$.table.init(options);
$.table.search('workerForm');
}
function selectRegion(regionLevelName, nextRegionLevelName) {
var regionId = $("#" + regionLevelName).val();
if ($.common.isEmpty(regionId)) {
return;
}
//Ajax调用处理
$.ajax({
type: "POST",
dataType:"json",
url: ctx + "system/area/list",
data: {parentCode: regionId},
success: function (result) {
if (result.code == web_status.SUCCESS) {
$('#areaCxSelect').cxSelect({
selects: [nextRegionLevelName],
jsonValue: 'areaId',
jsonName: 'areaName',
data: result.data
});
} else {
$.modal.msgError("数据加载错误,请重试!")
}
}
})
}
function assign(workerId) {
var params = {
id: orderMasterId,
workerId: workerId,
orderStatus: 0
};
$.ajax({
type: "POST",
dataType:"json",
url: ctx + "order/master/editOrderMaster",
data: JSON.stringify(params),
contentType: 'application/json',
success: function (result) {
if (result.code == web_status.SUCCESS) {
$.modal.msgSuccess("指派成功")
parent.layer.close(parent.layer.getFrameIndex(window.name));
} else {
$.modal.msgError("指派失败")
}
}
})
}
</script>
</body>
</html>

View File

@ -1,36 +0,0 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('批量改价')" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-change-price">
<input name="orderIds" type="hidden" th:value="${orderIds}" />
<div class="form-group">
<label class="col-sm-3 control-label">输入修改后价格:</label>
<div class="col-sm-8">
<input class="form-control" type="text" name="changePrice" id="changePrice">
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script type="text/javascript">
$("#changePrice").validate({
rules:{
changePrice:{
required:true
},
}
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(ctx + "order/master/batchChangePrice", $('#form-change-price').serialize());
}
}
</script>
</body>
</html>

View File

@ -1,30 +0,0 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('选择保险')" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-change-insurance">
<input name="orderMasterIds" type="hidden" th:value="${orderIds}" />
<div class="form-group">
<label class="col-sm-3 control-label">保险:</label>
<div class="col-sm-8">
<select id="insuranceId" name="insuranceId" class="form-control control-label" required>
<option th:each="insurance:${insurances}" th:value="${insurance.id}" th:text="${insurance.insuranceName}" ></option>
</select>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script type="text/javascript">
function submitHandler() {
if ($.validate.form()) {
$.operate.save(ctx + "order/master/pcOrderWorker/batchChangeInsurance", $('#form-change-insurance').serialize());
}
}
</script>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More