Compare commits

..

43 Commits

Author SHA1 Message Date
601dd0abd6 feat(database): 添加签到功能相关表结构
- 新增 zy_sign_record 表,用于记录用户签到信息
- 新增 zy_sign_set 表,用于配置签到奖励设置
2025-06-16 11:16:31 +08:00
055521dc8e chore: 删除已废弃的配置文件
- 删除了多个已废弃的配置文件,包括:
  - address/config.php
  - alisms/config.php
  - epay/config.php
  - hwobs/config.php
- 这些配置文件可能属于已不再使用的插件或功能
- 删除这些文件有助于清理代码库,减少潜在的混淆和维护成本
2025-06-16 11:09:01 +08:00
0432965b88 refactor(shopro): 优化代码中的用户 ID 处理逻辑 2025-06-14 16:59:21 +08:00
70baaa2fd5 refactor(zy): 修改消息通知的类型和功能 2025-06-09 10:52:18 +08:00
c9a8b9d5e8 feat(消息模块): 优化消息查询逻辑,支持俱乐部消息展示
- 修改了 User、Activity、Circle、Club 和 Game 控制器中的消息查询逻辑
- 增加了对俱乐部成员的判断,使得俱乐部消息能够展示给相关用户
- 调整了消息表中的字段名称,统一使用 user_id 替代 target_id
- 优化了订单创建流程,只在需要时创建订单
- 更新了活动模型中的 costKey 属性,以适应新的费用结构
- 添加了新的费用类型翻译,以支持多退少补等功能
2025-06-06 12:00:13 +08:00
d788227ff1 refactor(user): 重构用户个人信息页面并添加新功能
- 重构了用户个人信息页面,增加了权限控制和访问记录功能
2025-06-05 16:58:25 +08:00
9223c1b127 feat(shopro): 添加俱乐部、球馆的访客记录功能
- 在 Club 控制器中添加访客记录逻辑
- 在 Gym 控制器中添加访客记录逻辑
- 在 Sys 控制器中添加获取访客记录的功能
2025-06-05 14:55:16 +08:00
582c52e3a1 fix(shopro): 修复活动时间显示问题
- 拆分 startTime 和 endTime 字段,将日期和时间分开存储
- 优化活动时间的显示格式,提高可读性
2025-06-03 11:28:05 +08:00
19bfe5e992 feat(比赛): 优化团队排名算法并更新个人排名逻辑
- 新增团队排名算法,根据比赛得分和胜负情况计算排名
- 更新个人排名查询条件,排除 status 为 -1 的参与者
2025-06-01 18:46:12 +08:00
3feb90619c feat(order): 增加比赛订单,免费退坑时间时自动确认收货功能
- 新增逻辑判断,检查订单是否关联了比赛
- 如果关联了比赛,设置自动确认收货时间为比赛结束时
- 保留原有自动确认收货功能,作为备选方案
2025-06-01 17:34:34 +08:00
8fe0a460cd refactor(shopro): 优化订单处理逻辑
- 修改活动报名状态更新逻辑,根据报名人数和限制人数比较确定状态
- 移除不必要的模型引用,简化代码结构
- 调整订单自动处理和支付逻辑,提高代码可读性
- 重构订单监听器,优化体育活动报名相关操作
2025-06-01 16:41:13 +08:00
1b63962bff fix(shopro): 修复体育游戏自动退坑和更新用户得分逻辑
- 在 Game 控制器中,为 teamAuser 查询添加 status > -1 的条件,以确保只更新有效用户的得分
- 在 OrderAutoOper 任务中,修复 GameJoin 表格的 status 字段更新逻辑,并添加 Participant 表格的状态更新
2025-05-31 22:22:47 +08:00
35725ffd2d fix(zy): 修复活动报名时间和状态逻辑
- 修复了活动报名时间判断逻辑,增加了对报名结束时间的判断
- 修改了活动报名状态的判断条件,提高了代码的可读性和准确性
- 优化了订单自动操作和支付后的处理流程,确保活动报名状态正确更新
- 新增了用户权限验证功能,确保只有管理员或裁判可以修改用户状态
2025-05-31 21:22:44 +08:00
2a1cec7909 fix(shopro): 修复活动商品价格设置错误
- 将 Activity 控制器中的 original_price 字段赋值从 price 改为 cost
- 在 Game 控制器中添加团队排名和个人排名接口
2025-05-31 20:10:54 +08:00
681af2a1ca feat(message): 增加消息分类功能并优化消息列表
- 新增 msgGroup 方法实现消息分类功能
- 优化 msg 方法,支持分页并解析消息内容
- 修改 Circle 控制器中的消息发送逻辑
2025-05-31 18:00:13 +08:00
a44f364914 feat(zy): 优化影圈审核功能并添加新功能
- 在 zy_circle 表中添加 top 字段,用于置顶影圈帖子
- 重构 Circle 控制器中的 approve 方法,支持批量审核影圈帖子
- 新增 delete 方法,支持批量删除影圈帖子
- 新增 top 方法,用于置顶影圈帖子
- 优化影圈帖子列表的排序逻辑,按置顶和创建时间排序
2025-05-31 17:16:51 +08:00
be7ee40690 feat(zy): 实现比赛报名和自动分组功能
- 新增比赛报名逻辑,支持单双打和团队赛
- 实现自动分组算法,根据比赛规则生成对阵表
- 添加下一轮对阵安排功能,支持淘汰赛制
- 优化比赛结果处理,自动计算排名和得分
- 新增参赛人员列表接口,支持多种查询条件
2025-05-30 16:29:57 +08:00
6e655c6121 feat(shopro): 中羿体育活动报名费处理
- 新增报名费商品类别和商品创建逻辑
- 实现报名费价格动态更新
- 添加活动报名功能
- 优化 SkuPrice trait 中的 sku 处理逻辑
- 修复活动列表和详情页面的一些小问题
2025-05-30 14:39:30 +08:00
94a540ac96 feat(shopro): 优化比赛模块功能和流程
- 新增赛制说明接口和页面
- 实现比赛列表和对阵详情页面
- 添加比赛计分功能
- 优化比赛报名和参赛者分配逻辑
- 重构赛制配置和对阵安排方法
2025-05-27 08:51:27 +08:00
b7023e7ab3 feat(zy): 添加消息通知功能并优化活动相关逻辑
- 在 Circle 控制器中添加点赞、评论和审核通知
- 在 Game 控制器中添加退坑、取消活动和发送消息功能
- 优化 Activity 控制器中的订单关联逻辑
- 更新语言包,添加新的活动状态翻译
2025-05-26 11:03:39 +08:00
d48daea477 feat(zy): 添加圈子审核功能并优化相关页面
- 在 User 控制器中加入 Club 模型引用,用于获取俱乐部信息
- 在 Circle 控制器中添加 approve 方法,用于审核圈子帖子
- 更新圈子列表查询逻辑,支持按状态筛选
- 修改圈子添加和编辑页面,增加状态选择字段
- 更新圈子列表页面,显示帖子状态并支持状态筛选
2025-05-25 20:10:58 +08:00
185578aa6a feat(user): 优化个人详情接口并添加俱乐部列表和关注功能
- 在用户详情中添加 club_list 字段,返回用户加入的俱乐部列表
- 优化俱乐部成员接口,支持分页和显示更多用户信息
- 新增关注功能,用户可以关注其他用户
2025-05-24 22:32:13 +08:00
ac0777e34b feat(游戏模块): 重构比赛逻辑并添加赛制支持
- 移除了原有的比赛时间检查逻辑
- 引入了赛制类文件,实现了比赛自动编排功能
- 新增了 GameMatch 模型用于存储比赛对阵信息
- 优化了数据库事务处理逻辑
- 更新了 Composer 自动加载配置,添加 format 命名空间
2025-05-23 17:37:48 +08:00
8481d8ef0c refactor(shopro): game 2025-05-20 17:25:44 +08:00
c3b0a47e6d feat(俱乐部): 增加俱乐部详细介绍和关注数功能 2025-05-18 20:20:01 +08:00
55af3cb570 feat(zy): 增加俱乐部详情接口并优化游戏详情页面
- 新增俱乐部详情接口,包括成员性别比例和关注度统计
- 在游戏详情页面增加关注度统计
- 更新游戏活动状态文案
- 优化 dd 和 getsql 函数输出格式
2025-05-18 11:44:02 +08:00
6c4fc6bff6 feat(hwobs): 返回华为obs参数 2025-05-18 10:47:10 +08:00
e420668a44 feat(user): 个人详情接口增加消息和俱乐部数量
- 在用户详情中添加未读消息数、俱乐部数和卡券数
- 新增 Message 模型用于消息相关操作
- 使用 Menber 模型统计用户在俱乐部的角色数量
2025-05-16 11:33:13 +08:00
751c742726 feat(俱乐部和比赛模块): 增加俱乐部和比赛的相关功能和优化
- 在 Club 控制器中添加了对俱乐部列表的查询,包括俱乐部名称、场馆名称、俱乐部标签等信息
- 在 Game 控制器中增加了对比赛列表的查询,包括比赛名称、场馆名称、俱乐部名称、参赛选手头像等信息
- 优化了 Game 控制器中的比赛详情查询,增加了参赛选手头像的解析
- 在 Game、GameJoin 和 Participant 模型中添加了 tableName 静态属性,便于统一管理表名
2025-05-16 11:16:29 +08:00
8a68fb84af refactor(zy): 修复分页查询错误问题 2025-05-16 09:37:13 +08:00
c2478c1aea refactor(zy): 重构查询接口并添加分页功能
- 重构了 Activity、Circle、Club、Game 和 Gym 控制器中的查询方法
- 添加了分页功能,支持指定页码和每页数量
- 优化了查询结果,返回包含总数的格式化数据
- 使用 alias 和 join 方法改进了查询效率
- 删除了 Base 控制器中的通用查询方法
2025-05-11 17:58:45 +08:00
1dc3d9c516 fix(shopro): 修复数据库不支持JSON_ARRAYAGG函数问题
- 修改了 Circle 控制器中的查询语句,使用 CONCAT 和 GROUP_CONCAT 替代 JSON_ARRAYAGG
- 优化了 likes 和 comments 字段的数据格式,确保正确返回 JSON 数组格式
- 该修改解决了数据返回格式错误导致的前端解析问题
2025-05-11 17:15:56 +08:00
1bd66c30ba 修改index接口无需登录 2025-05-11 16:46:19 +08:00
6a5d81badc 俱乐部完善 2025-05-11 16:14:57 +08:00
7934afeb04 修复华为云存储报错 2025-05-11 10:02:08 +08:00
4ff29bed97 数据库字符集转换 2025-05-11 09:37:46 +08:00
b7002e3e2a refactor(zh-cn): 优化影圈模块的后台显示 2025-05-10 20:19:04 +08:00
12adc51eeb fix(hwobs): 升级华为OBS云储存 2025-05-10 19:50:27 +08:00
e0e42e3ecc add:增加影圈功能,优化部分接口 2025-05-10 19:47:12 +08:00
1c53b73614 upd:测试用户密码 2025-05-09 10:08:15 +08:00
c76019416a feat(user): 添加用户申请联系功能并优化俱乐部相关操作
- 新增用户申请联系信息功能,包括申请、审核和处理流程
- 优化俱乐部申请、邀请和处理申请的逻辑
- 修复活动不存在时的错误提示
- 优化活动查询条件,支持一次性活动的特殊处理
2025-05-04 17:23:11 +08:00
98eda4e5ff feat(zy): 添加俱乐部功能和用户消息功能
- 新增俱乐部相关接口和功能,包括创建俱乐部、申请加入俱乐部、邀请加入俱乐部等
- 添加用户消息功能,包括发送消息、查看消息等
- 优化了部分代码结构,提高了可维护性
- 更新了文档,添加了新的接口说明
2025-05-04 11:11:44 +08:00
207e6b8a5d add:消息 2025-05-02 14:24:28 +08:00
94 changed files with 5262 additions and 5921 deletions

4
.gitignore vendored
View File

@@ -11,3 +11,7 @@ composer.lock
.vscode
node_modules
.user.ini
addons/alisms/config.php
addons/address/config.php
addons/epay/config.php
addons/hwobs/config.php

View File

@@ -1,93 +1,5 @@
FastAdmin是一款基于ThinkPHP+Bootstrap的极速后台开发框架。
## 主要特性
* 基于`Auth`验证的权限管理系统
* 支持无限级父子级权限继承,父级的管理员可任意增删改子级管理员及权限设置
* 支持单管理员多角色
* 支持管理子级数据或个人数据
* 强大的一键生成功能
* 一键生成CRUD,包括控制器、模型、视图、JS、语言包、菜单、回收站等
* 一键压缩打包JS和CSS文件一键CDN静态资源部署
* 一键生成控制器菜单和规则
* 一键生成API接口文档
* 完善的前端功能组件开发
* 基于`AdminLTE`二次开发
* 基于`Bootstrap`开发自适应手机、平板、PC
* 基于`RequireJS`进行JS模块管理按需加载
* 基于`Less`进行样式开发
* 强大的插件扩展功能,在线安装卸载升级插件
* 通用的会员模块和API模块
* 共用同一账号体系的Web端会员中心权限验证和API接口会员权限验证
* 二级域名部署支持,同时域名支持绑定到应用插件
* 多语言支持,服务端及客户端支持
* 支持大文件分片上传、剪切板粘贴上传、拖拽上传,进度条显示,图片上传前压缩
* 支持表格固定列、固定表头、跨页选择、Excel导出、模板渲染等功能
* 强大的第三方应用模块支持([CMS](https://www.fastadmin.net/store/cms.html)、[CRM](https://www.fastadmin.net/store/facrm.html)、[企业网站管理系统](https://www.fastadmin.net/store/ldcms.html)、[知识库文档系统](https://www.fastadmin.net/store/knowbase.html)、[在线投票系统](https://www.fastadmin.net/store/vote.html)、[B2C商城](https://www.fastadmin.net/store/shopro.html)、[B2B2C商城](https://www.fastadmin.net/store/wanlshop.html))
* 整合第三方短信接口(阿里云、腾讯云短信)
* 无缝整合第三方云存储(七牛云、阿里云OSS、腾讯云存储、又拍云)功能,支持云储存分片上传
* 第三方富文本编辑器支持(Summernote、百度编辑器)
* 第三方登录(QQ、微信、微博)整合
* 第三方支付(微信、支付宝)无缝整合微信支持PC端扫码支付
* 丰富的插件应用市场
## 安装使用
https://doc.fastadmin.net
## 在线演示
https://demo.fastadmin.net
用户名admin
 123456
提 示:演示站数据无法进行修改,请下载源码安装体验全部功能
## 界面截图
![控制台](https://images.gitee.com/uploads/images/2020/0929/202947_8db2d281_10933.gif "控制台")
## 问题反馈
在使用中有任何问题,请使用以下联系方式联系我们
问答社区: https://ask.fastadmin.net
Github: https://github.com/fastadminnet/fastadmin
Gitee: https://gitee.com/fastadminnet/fastadmin
## 特别鸣谢
感谢以下的项目,排名不分先后
ThinkPHPhttp://www.thinkphp.cn
AdminLTEhttps://adminlte.io
Bootstraphttp://getbootstrap.com
jQueryhttp://jquery.com
Bootstrap-tablehttps://github.com/wenzhixin/bootstrap-table
Nice-validator: https://validator.niceue.com
SelectPage: https://github.com/TerryZ/SelectPage
Layer: https://layuion.com/layer/
DropzoneJS: https://www.dropzonejs.com
## 版权信息
FastAdmin遵循Apache2开源协议发布并提供免费使用。
本项目包含的第三方源码和二进制文件之版权信息另行标注。
版权所有Copyright © 2017-2024 by FastAdmin (https://www.fastadmin.net)
All rights reserved。
### 队列启动命令
- php think queue:work --daemon --queue shopro
- php think queue:work --daemon --queue shopro-high

34
add.sql Normal file
View File

@@ -0,0 +1,34 @@
ALTER TABLE `zy_club` ADD COLUMN `intro` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '介绍' AFTER `blurb`;
ALTER TABLE `zy_club` ADD COLUMN `contect` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '联系方式' AFTER `img`;
ALTER TABLE `zy_club` ADD COLUMN `attention` int(11) NOT NULL DEFAULT 0 COMMENT '关注人数' AFTER `contect`;
-- 已执行 2025-05-18
ALTER TABLE `zy_circle` ADD COLUMN `top` int NOT NULL DEFAULT 0 COMMENT '置顶' AFTER `status`;
-- 已执行 2025-05-31
CREATE TABLE `zy_sign_record` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '用户id',
`date` date NOT NULL DEFAULT current_timestamp() COMMENT '签到日期',
`last` int(11) NOT NULL DEFAULT 1 COMMENT '已持续天数',
`create_time` datetime NOT NULL DEFAULT current_timestamp() COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp() COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE,
KEY `user_id` (`user_id`,`last`) USING BTREE,
KEY `date` (`date`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='签到记录';
CREATE TABLE `zy_sign_set` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`last` tinyint(4) NOT NULL DEFAULT 1 COMMENT '连续天数',
`chance1` tinyint(4) NOT NULL DEFAULT 0 COMMENT '概率1',
`coupon1_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '券1',
`chance2` tinyint(4) NOT NULL DEFAULT 0 COMMENT '概率2',
`coupon2_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '券2',
`create_time` datetime NOT NULL DEFAULT current_timestamp() COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp() COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE,
KEY `type` (`last`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='签到设置';
-- 已执行 2025-06-16

View File

@@ -1,132 +0,0 @@
<?php
return [
[
'name' => 'maptype',
'title' => '默认地图类型',
'type' => 'radio',
'content' => [
'baidu' => '百度地图',
'amap' => '高德地图',
'tencent' => '腾讯地图',
],
'value' => 'amap',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'zoom',
'title' => '默认缩放级别',
'type' => 'string',
'content' => [],
'value' => '11',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'lat',
'title' => '默认Lat',
'type' => 'string',
'content' => [],
'value' => '23.002569',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'lng',
'title' => '默认Lng',
'type' => 'string',
'content' => [],
'value' => '113.752215',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'baidukey',
'title' => '百度地图KEY',
'type' => 'string',
'content' => [],
'value' => '',
'rule' => '',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'amapkey',
'title' => '高德地图KEY',
'type' => 'string',
'content' => [],
'value' => '78c9a922ba2d29f005eaa89e3f1b00bb',
'rule' => '',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'amapsecurityjscode',
'title' => '高德地图安全密钥',
'type' => 'string',
'content' => [],
'value' => '',
'rule' => '',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'tencentkey',
'title' => '腾讯地图KEY',
'type' => 'string',
'content' => [],
'value' => '',
'rule' => '',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'coordtype',
'title' => '坐标系类型',
'type' => 'select',
'content' => [
'DEFAULT' => '默认(使用所选地图默认坐标系)',
'GCJ02' => 'GCJ-02',
'BD09' => 'BD-09',
],
'value' => 'DEFAULT',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => '__tips__',
'title' => '温馨提示',
'type' => '',
'content' => [],
'value' => '请先申请对应地图的Key配置后再使用',
'rule' => '',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => 'alert-danger-light',
],
];

View File

@@ -1,77 +0,0 @@
<?php
return array(
array(
'name' => 'key',
'title' => '应用key',
'type' => 'string',
'content' =>
array(),
'value' => 'your key',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
array(
'name' => 'secret',
'title' => '密钥secret',
'type' => 'string',
'content' =>
array(),
'value' => 'your secret',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
array(
'name' => 'sign',
'title' => '签名',
'type' => 'string',
'content' =>
array(),
'value' => 'your sign',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
array(
'name' => 'template',
'title' => '短信模板',
'type' => 'array',
'content' =>
array(),
'value' =>
array(
'register' => 'SMS_114000000',
'resetpwd' => 'SMS_114000000',
'changepwd' => 'SMS_114000000',
'changemobile' => 'SMS_114000000',
'profile' => 'SMS_114000000',
'notice' => 'SMS_114000000',
),
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
array(
'name' => '__tips__',
'title' => '温馨提示',
'type' => 'string',
'content' =>
array(),
'value' => '应用key和密钥你可以通过 https://ak-console.aliyun.com/?spm=a2c4g.11186623.2.13.fd315777PX3tjy#/accesskey 获取',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
);

View File

@@ -1,70 +0,0 @@
<?php
return [
[
'name' => 'version',
'title' => 'API版本(请勿修改该值)',
'type' => 'radio',
'content' => [],
'value' => 'v2',
'rule' => '',
'msg' => '',
'tip' => 'V2版本只支持微信支付V2密钥V3版本只支持微信支付V3密钥请勿修改该值',
'ok' => '',
'extend' => '',
],
[
'name' => 'wechat',
'title' => '微信',
'type' => 'array',
'content' => [],
'value' => [
'appid' => '',
'app_id' => '',
'app_secret' => '',
'miniapp_id' => '',
'mch_id' => '',
'key' => '',
'key_v3' => '',
'mode' => 'normal',
'sub_mch_id' => '',
'sub_appid' => '',
'sub_app_id' => '',
'sub_miniapp_id' => '',
'notify_url' => '',
'cert_client' => '/addons/epay/certs/apiclient_cert.pem',
'cert_key' => '/addons/epay/certs/apiclient_key.pem',
'log' => '1',
],
'rule' => 'required',
'msg' => '',
'tip' => '微信参数配置',
'ok' => '',
'extend' => '',
],
[
'name' => 'alipay',
'title' => '支付宝',
'type' => 'array',
'content' => [],
'value' => [
'app_id' => '',
'mode' => 'normal',
'notify_url' => '/addons/epay/api/notifyx/type/alipay',
'return_url' => '/addons/epay/api/returnx/type/alipay',
'private_key' => '',
'signtype' => 'cert',
'pid' => '',
'ali_public_key' => '',
'app_cert_public_key' => '',
'alipay_root_cert' => '',
'log' => '1',
'scanpay' => '0',
],
'rule' => 'required',
'msg' => '',
'tip' => '支付宝参数配置',
'ok' => '',
'extend' => '',
]
];

View File

@@ -1 +1 @@
{"files":["public\\assets\\addons\\hwobs\\js\\spark.js"],"license":"regular","licenseto":"34485","licensekey":"kaCpXL6B57yO89Rv h7EIXhuMw6+sCcUldTSJoQ==","domains":["localhost"],"licensecodes":[],"validations":["757319b447175b6ca1882635b132a594"]}
{"files":["public\\assets\\addons\\hwobs\\js\\spark.js"],"license":"regular","licenseto":"34485","licensekey":"fE1oqlUNvPsVy07I LHfdNbd7Yb6AD1LjzKfdIA==","domains":[],"licensecodes":[],"validations":[]}

View File

@@ -1,245 +0,0 @@
<?php
return [
[
'name' => 'accessKey',
'title' => 'Access Key',
'type' => 'string',
'content' => [],
'value' => '',
'rule' => 'required',
'msg' => '',
'tip' => '请前往华为云控制台->我的凭证->访问密钥中生成',
'ok' => '',
'extend' => '',
],
[
'name' => 'secretKey',
'title' => 'Secret Key',
'type' => 'string',
'content' => [],
'value' => '',
'rule' => 'required',
'msg' => '',
'tip' => '请前往华为云控制台->我的凭证->访问密钥中生成',
'ok' => '',
'extend' => '',
],
[
'name' => 'bucket',
'title' => '存储桶名称',
'type' => 'string',
'content' => [],
'value' => 'yourbucket',
'rule' => 'required',
'msg' => '',
'tip' => '存储桶名称',
'ok' => '',
'extend' => '',
],
[
'name' => 'endpoint',
'title' => 'Endpoint',
'type' => 'string',
'content' => [],
'value' => 'obs.cn-south-1.myhuaweicloud.com',
'rule' => 'required;endpoint',
'msg' => '',
'tip' => '请输入你的Endpoint',
'ok' => '',
'extend' => 'data-rule-endpoint="[/^(?!http(s)?:\/\/).*$/, \'不能以http(s)://开头\']"',
],
[
'name' => 'uploadurl',
'title' => '上传接口地址',
'type' => 'string',
'content' => [],
'value' => 'https://yourbucket.obs.cn-south-1.myhuaweicloud.com',
'rule' => 'required;uploadurl',
'msg' => '',
'tip' => '请使用存储桶->基本信息->访问域名的值并在前面加上http://或https://',
'ok' => '',
'extend' => 'data-rule-uploadurl="[/^http(s)?:\/\/.*$/, \'必需以http(s)://开头\']"',
],
[
'name' => 'cdnurl',
'title' => 'CDN地址',
'type' => 'string',
'content' => [],
'value' => 'https://yourbucket.obs.cn-south-1.myhuaweicloud.com',
'rule' => 'required;cdnurl',
'msg' => '',
'tip' => '如果你的云存储有绑定自定义域名,请输入自定义域名',
'ok' => '',
'extend' => 'data-rule-cdnurl="[/^http(s)?:\/\/.*$/, \'必需以http(s)://开头\']"',
],
[
'name' => 'uploadmode',
'title' => '上传模式',
'type' => 'select',
'content' => [
'client' => '客户端直传(速度快,无备份)',
'server' => '服务器中转(占用服务器带宽,有备份)',
],
'value' => 'server',
'rule' => '',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'serverbackup',
'title' => '服务器中转模式备份',
'type' => 'radio',
'content' => [
1 => '备份(附件管理将产生2条记录)',
0 => '不备份',
],
'value' => '1',
'rule' => '',
'msg' => '',
'tip' => '服务器中转模式下是否备份文件',
'ok' => '',
'extend' => '',
],
[
'name' => 'savekey',
'title' => '保存文件名',
'type' => 'string',
'content' => [],
'value' => '/uploads/{year}{mon}{day}/{filemd5}{.suffix}',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'expire',
'title' => '上传有效时长',
'type' => 'string',
'content' => [],
'value' => '600',
'rule' => 'required',
'msg' => '',
'tip' => '用户停留页面上传有效时长,单位秒',
'ok' => '',
'extend' => '',
],
[
'name' => 'maxsize',
'title' => '最大可上传',
'type' => 'string',
'content' => [],
'value' => '10M',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'mimetype',
'title' => '可上传后缀格式',
'type' => 'string',
'content' => [],
'value' => 'jpg,png,bmp,jpeg,gif,zip,rar,xls,xlsx',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'multiple',
'title' => '多文件上传',
'type' => 'bool',
'content' => [],
'value' => '0',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'thumbstyle',
'title' => '缩略图样式',
'type' => 'string',
'content' => [],
'value' => '',
'rule' => '',
'msg' => '',
'tip' => '用于后台列表缩略图样式,可使用:?x-image-process=image/resize,m_fixed,h_90,w_120或?x-image-process=style/样式名称',
'ok' => '',
'extend' => '',
],
[
'name' => 'chunking',
'title' => '分片上传',
'type' => 'radio',
'content' => [
1 => '开启',
0 => '关闭',
],
'value' => '0',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'chunksize',
'title' => '分片大小',
'type' => 'number',
'content' => [],
'value' => '4194304',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'syncdelete',
'title' => '附件删除时是否同步删除云存储文件',
'type' => 'bool',
'content' => [],
'value' => '0',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'apiupload',
'title' => 'API接口使用云存储',
'type' => 'bool',
'content' => [],
'value' => '0',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'noneedlogin',
'title' => '免登录上传',
'type' => 'checkbox',
'content' => [
'api' => 'API',
'index' => '前台',
'admin' => '后台',
],
'value' => '',
'rule' => '',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
];

View File

@@ -2,16 +2,17 @@
namespace addons\hwobs\controller;
use addons\hwobs\library\Auth;
use addons\hwobs\library\Signer;
use app\common\exception\UploadException;
use app\common\library\Upload;
use app\common\model\Attachment;
use Obs\Internal\Common\Model;
use Obs\Internal\Signature\DefaultSignature;
use Obs\ObsClient;
use think\addons\Controller;
use think\Config;
use Obs\ObsClient;
use addons\hwobs\Hwobs;
use think\addons\Controller;
use addons\hwobs\library\Auth;
use app\common\library\Upload;
use Obs\Internal\Common\Model;
use addons\hwobs\library\Signer;
use app\common\model\Attachment;
use app\common\exception\UploadException;
use Obs\Internal\Signature\DefaultSignature;
class Index extends Controller
{
@@ -31,6 +32,13 @@ class Index extends Controller
$this->error("当前插件暂无前台页面");
}
public function config()
{
$upload = [];
(new Hwobs)->uploadConfigInit($upload);
$this->success('', null, $upload);
}
public function params()
{
$this->check();
@@ -39,6 +47,14 @@ class Index extends Controller
$name = $this->request->post('name');
$md5 = $this->request->post('md5');
$chunk = $this->request->post('chunk');
$name = xss_clean($name);
// 检查文件后缀
$extension = strtolower(pathinfo($name, PATHINFO_EXTENSION));
$allowedExtensions = explode(',', strtolower($config['mimetype']));
if (!in_array($extension, $allowedExtensions) || in_array($extension, ['php', 'html', 'htm', 'phar', 'phtml']) || preg_match("/^php(.*)/i", $extension)) {
$this->error('不允许的文件类型');
}
$key = (new Upload())->getSavekey($config['savekey'], $name, $md5);
$key = ltrim($key, "/");
@@ -75,8 +91,7 @@ class Index extends Controller
$signature = $obs->createPostSignature([
'Bucket' => $config['bucket'],
'Key' => $key,
'FormParams' => [
]
'FormParams' => []
]);
$params['key'] = $key;
$params['AccessKeyId'] = $config['accessKey'];
@@ -86,7 +101,6 @@ class Index extends Controller
$params['headers'] = $headers;
$params['date'] = $date;
$this->success('', null, $params);
return;
}
/**
@@ -321,5 +335,4 @@ class Index extends Controller
$this->error("请求已经超时");
}
}
}

View File

@@ -3,7 +3,7 @@ title = 华为OBS云储存
intro = 使用华为OBS作为默认云储存
author = FastAdmin
website = https://www.fastadmin.net
version = 1.2.9
version = 1.2.10
state = 1
url = /addons/hwobs
license = regular

View File

@@ -28,17 +28,17 @@ class Model implements \ArrayAccess, \IteratorAggregate, \Countable, ToArrayInte
{
protected $data;
public function __construct(array $data = [])
public function __construct(?array $data = [])
{
$this->data = $data;
}
public function count()
public function count(): int
{
return count($this->data);
}
public function getIterator()
public function getIterator(): \Traversable
{
return new \ArrayIterator($this->data);
}
@@ -55,7 +55,7 @@ class Model implements \ArrayAccess, \IteratorAggregate, \Countable, ToArrayInte
return $this;
}
public function getAll(array $keys = null)
public function getAll(?array $keys = null)
{
return $keys ? array_intersect_key($this->data, array_flip($keys)) : $this->data;
}
@@ -119,7 +119,7 @@ class Model implements \ArrayAccess, \IteratorAggregate, \Countable, ToArrayInte
return array_search($value, $this->data);
}
public function replace(array $data)
public function replace(?array $data)
{
$this->data = $data;
@@ -148,7 +148,7 @@ class Model implements \ArrayAccess, \IteratorAggregate, \Countable, ToArrayInte
return $this;
}
public function map(\Closure $closure, array $context = [], $static = true)
public function map(\Closure $closure, ?array $context = [], $static = true)
{
$collection = $static ? new static() : new self();
foreach ($this as $key => $value) {
@@ -170,29 +170,29 @@ class Model implements \ArrayAccess, \IteratorAggregate, \Countable, ToArrayInte
return $collection;
}
public function offsetExists($offset)
public function offsetExists($offset): bool
{
return isset($this->data[$offset]);
}
public function offsetGet($offset)
public function offsetGet($offset): mixed
{
return isset($this->data[$offset]) ? $this->data[$offset] : null;
}
public function offsetSet($offset, $value)
public function offsetSet($offset, $value): void
{
$this->data[$offset] = $value;
}
public function offsetUnset($offset)
public function offsetUnset($offset): void
{
unset($this->data[$offset]);
}
public function setPath($path, $value)
{
$current =& $this->data;
$current = &$this->data;
$queue = explode('/', $path);
while (null !== ($key = array_shift($queue))) {
if (!is_array($current)) {
@@ -200,10 +200,10 @@ class Model implements \ArrayAccess, \IteratorAggregate, \Countable, ToArrayInte
} elseif (!$queue) {
$current[$key] = $value;
} elseif (isset($current[$key])) {
$current =& $current[$key];
$current = &$current[$key];
} else {
$current[$key] = [];
$current =& $current[$key];
$current = &$current[$key];
}
}
@@ -213,7 +213,7 @@ class Model implements \ArrayAccess, \IteratorAggregate, \Countable, ToArrayInte
public function getPath($path, $separator = '/', $data = null)
{
if ($data === null) {
$data =& $this->data;
$data = &$this->data;
}
$path = is_array($path) ? $path : explode($separator, $path);
@@ -221,7 +221,7 @@ class Model implements \ArrayAccess, \IteratorAggregate, \Countable, ToArrayInte
if (!is_array($data)) {
return null;
} elseif (isset($data[$part])) {
$data =& $data[$part];
$data = &$data[$part];
} elseif ($part != '*') {
return null;
} else {
@@ -248,7 +248,7 @@ class Model implements \ArrayAccess, \IteratorAggregate, \Countable, ToArrayInte
$output = str_repeat('=', strlen($output)) . "\n" . $output . "\n" . str_repeat('=', strlen($output)) . "\n\n";
$output .= "Model data\n-----------\n\n";
$output .= "This data can be retrieved from the model object using the get() method of the model "
. "(e.g. \$model->get(\$key)) or accessing the model like an associative array (e.g. \$model['key']).\n\n";
. "(e.g. \$model->get(\$key)) or accessing the model like an associative array (e.g. \$model['key']).\n\n";
$lines = array_slice(explode("\n", trim(print_r($this->toArray(), true))), 2, -1);
$output .= implode("\n", $lines);

View File

@@ -41,7 +41,7 @@ class SdkCurlFactory implements CurlFactoryInterface
$this->maxHandles = $maxHandles;
}
public function create(RequestInterface $request, array $options): EasyHandle
public function create(?RequestInterface $request, ?array $options): EasyHandle
{
if (isset($options['curl']['body_as_string'])) {
$options['_body_as_string'] = $options['curl']['body_as_string'];
@@ -85,7 +85,7 @@ class SdkCurlFactory implements CurlFactoryInterface
}
}
public function release(EasyHandle $easy): void
public function release(?EasyHandle $easy): void
{
$resource = $easy->handle;
unset($easy->handle);
@@ -102,7 +102,7 @@ class SdkCurlFactory implements CurlFactoryInterface
}
}
private function getDefaultConf(EasyHandle $easy)
private function getDefaultConf(?EasyHandle $easy)
{
$conf = [
'_headers' => $easy->request->getHeaders(),
@@ -129,7 +129,7 @@ class SdkCurlFactory implements CurlFactoryInterface
return $conf;
}
private function applyMethod(EasyHandle $easy, array &$conf)
private function applyMethod(?EasyHandle $easy, ?array &$conf)
{
$body = $easy->request->getBody();
$size = $body->getSize();
@@ -155,7 +155,7 @@ class SdkCurlFactory implements CurlFactoryInterface
}
}
private function applyBody(RequestInterface $request, array $options, array &$conf)
private function applyBody(?RequestInterface $request, ?array $options, ?array &$conf)
{
$size = $request->hasHeader('Content-Length')
? (int) $request->getHeaderLine('Content-Length')
@@ -209,7 +209,7 @@ class SdkCurlFactory implements CurlFactoryInterface
}
}
private function applyHeaders(EasyHandle $easy, array &$conf)
private function applyHeaders(?EasyHandle $easy, ?array &$conf)
{
foreach ($conf['_headers'] as $name => $values) {
foreach ($values as $value) {
@@ -223,7 +223,7 @@ class SdkCurlFactory implements CurlFactoryInterface
}
}
private function removeHeader($name, array &$options)
private function removeHeader($name, ?array &$options)
{
foreach (array_keys($options['_headers']) as $key) {
if (!strcasecmp($key, $name)) {
@@ -233,7 +233,7 @@ class SdkCurlFactory implements CurlFactoryInterface
}
}
private function applyHandlerOptions(EasyHandle $easy, array &$conf)
private function applyHandlerOptions(?EasyHandle $easy, ?array &$conf)
{
$options = $easy->options;
if (isset($options['verify'])) {
@@ -381,7 +381,7 @@ class SdkCurlFactory implements CurlFactoryInterface
}
private function createHeaderFn(EasyHandle $easy)
private function createHeaderFn(?EasyHandle $easy)
{
if (isset($easy->options['on_headers'])) {
$onHeaders = $easy->options['on_headers'];

View File

@@ -38,7 +38,7 @@ class SdkStreamHandler
{
private $lastHeaders = [];
public function __invoke(RequestInterface $request, array $options)
public function __invoke(?RequestInterface $request, ?array $options)
{
if (isset($options['delay'])) {
usleep($options['delay'] * 1000);
@@ -77,10 +77,10 @@ class SdkStreamHandler
}
private function invokeStats(
array $options,
RequestInterface $request,
?array $options,
?RequestInterface $request,
$startTime,
ResponseInterface $response = null,
?ResponseInterface $response = null,
$error = null
) {
if (isset($options['on_stats'])) {
@@ -96,8 +96,8 @@ class SdkStreamHandler
}
private function createResponse(
RequestInterface $request,
array $options,
?RequestInterface $request,
?array $options,
$stream,
$startTime
) {
@@ -141,7 +141,7 @@ class SdkStreamHandler
return new FulfilledPromise($response);
}
private function createSink(StreamInterface $stream, array $options)
private function createSink(StreamInterface $stream, ?array $options)
{
if (!empty($options['stream'])) {
return $stream;
@@ -156,7 +156,7 @@ class SdkStreamHandler
: \GuzzleHttp\Psr7\Utils::streamFor($sink);
}
private function checkDecode(array $options, array $headers, $stream)
private function checkDecode(?array $options, ?array $headers, $stream)
{
if (!empty($options['decode_content'])) {
$normalizedKeys = \GuzzleHttp\normalize_header_keys($headers);
@@ -232,7 +232,7 @@ class SdkStreamHandler
return $resource;
}
private function createStream(RequestInterface $request, array $options)
private function createStream(?RequestInterface $request, ?array $options)
{
static $methods;
if (!$methods) {
@@ -309,7 +309,7 @@ class SdkStreamHandler
);
}
private function resolveHost(RequestInterface $request, array $options)
private function resolveHost(?RequestInterface $request, ?array $options)
{
$uri = $request->getUri();
@@ -332,7 +332,7 @@ class SdkStreamHandler
return $uri;
}
private function getDefaultContext(RequestInterface $request)
private function getDefaultContext(?RequestInterface $request)
{
$headers = '';
foreach ($request->getHeaders() as $name => $value) {
@@ -365,7 +365,7 @@ class SdkStreamHandler
return $context;
}
private function add_proxy(RequestInterface $request, &$options, $value, &$params)
private function add_proxy(?RequestInterface $request, &$options, $value, &$params)
{
if (!is_array($value)) {
$options['http']['proxy'] = $value;
@@ -384,14 +384,14 @@ class SdkStreamHandler
}
}
private function add_timeout(RequestInterface $request, &$options, $value, &$params)
private function add_timeout(?RequestInterface $request, &$options, $value, &$params)
{
if ($value > 0) {
$options['http']['timeout'] = $value;
}
}
private function add_verify(RequestInterface $request, &$options, $value, &$params)
private function add_verify(?RequestInterface $request, &$options, $value, &$params)
{
if ($value === true) {
if (PHP_VERSION_ID < 50600) {
@@ -415,7 +415,7 @@ class SdkStreamHandler
$options['ssl']['allow_self_signed'] = false;
}
private function add_cert(RequestInterface $request, &$options, $value, &$params)
private function add_cert(?RequestInterface $request, &$options, $value, &$params)
{
if (is_array($value)) {
$options['ssl']['passphrase'] = $value[1];
@@ -429,7 +429,7 @@ class SdkStreamHandler
$options['ssl']['local_cert'] = $value;
}
private function add_progress(RequestInterface $request, &$options, $value, &$params)
private function add_progress(?RequestInterface $request, &$options, $value, &$params)
{
$this->addNotification(
$params,
@@ -441,7 +441,7 @@ class SdkStreamHandler
);
}
private function add_debug(RequestInterface $request, &$options, $value, &$params)
private function add_debug(?RequestInterface $request, &$options, $value, &$params)
{
if ($value === false) {
return;
@@ -478,7 +478,7 @@ class SdkStreamHandler
);
}
private function addNotification(array &$params, callable $notify)
private function addNotification(?array &$params, callable $notify)
{
if (!isset($params['notification'])) {
$params['notification'] = $notify;
@@ -490,7 +490,7 @@ class SdkStreamHandler
}
}
private function callArray(array $functions)
private function callArray(?array $functions)
{
return function () use ($functions) {
$args = func_get_args();

View File

@@ -16,7 +16,7 @@ class Command extends BaseCommand
/**
* 执行帮助命令
*/
protected function execute(Input $input, Output $output)
protected function execute(?Input $input, ?Output $output)
{
$this->input = $input;
$this->output = $output;

View File

@@ -42,7 +42,7 @@ class ShoproChat extends Command
/**
* 执行帮助命令
*/
protected function execute(Input $input, Output $output)
protected function execute(?Input $input, ?Output $output)
{
$this->input = $input;
$this->output = $output;

View File

@@ -2,14 +2,24 @@
namespace addons\shopro\controller\user;
use think\Db;
use think\Exception;
use app\common\library\Sms;
use app\admin\model\zy\Club;
use app\admin\model\zy\Menber;
use think\exception\PDOException;
use app\admin\model\zy\link\Apply;
use addons\shopro\controller\Common;
use app\admin\model\zy\link\Message;
use app\admin\model\zy\link\Visitor;
use app\admin\model\zy\link\Relation;
use app\admin\model\shopro\ThirdOauth;
use think\exception\ValidateException;
use addons\shopro\service\user\UserAuth;
use app\admin\model\shopro\user\User as UserModel;
use app\admin\model\shopro\user\Coupon as UserCouponModel;
use app\admin\model\shopro\order\Order as OrderModel;
use app\admin\model\shopro\user\Coupon as UserCouponModel;
use app\admin\model\shopro\order\Aftersale as AftersaleModel;
use app\admin\model\shopro\ThirdOauth;
class User extends Common
{
@@ -76,11 +86,41 @@ class User extends Common
public function profile()
{
//TODO @ldh: 1.账号被禁用 2.连表查group
$user = auth_user(true);
$user = UserModel::with(['parent_user', 'third_oauth'])->where('id', $user->id)->find();
$self = auth_user(true); //自己
$user_id = $self->id;
$params = $this->request->param();
if (!empty($params['user_id'])) {
$user_id = $params['user_id'];
$relation = Relation::where('user_id', $self->id)->where('target_id', $user_id)->find();
$content = json_decode($relation->content ?? '', true);
$visitor = Visitor::where('type', 2)->where('obj_id', $user_id)->where('user_id', $self->id)->find();
if (empty($visitor)) {
$visitor = new Visitor;
}
$visitor->allowField(true)->save([
'type' => 2,
'obj_id' => $user_id,
'user_id' => $self->id,
'nickname' => $self['nickname'],
'avatar' => $self['avatar'],
'gender' => $self['gender'],
'times' => empty($visitor->times) ? 1 : $visitor->times + 1
]);
}
$user = UserModel::with(['parent_user', 'third_oauth'])->where('id', $user_id)->find();
$user->hidden(['password', 'salt', 'createtime', 'updatetime', 'deletetime', 'remember_token', 'login_fail', 'login_ip', 'login_time']);
$user = $user->toArray();
$user['msg_num'] = Message::where('user_id', $user['id'])->where('status', 0)->count();
$user['club_list'] = Menber::alias('m')->join([Club::$tableName => 'c'], 'c.id=m.club_id')->field('m.*,c.name')->where('user_id', $user['id'])->where('role', '>', 0)->select();
$user['club_num'] = count($user['club_list']);
$user['card_num'] = 0;
if (isset($content)) {
if (empty($content['phone'])) $user['mobile'] = ''; //手机查看权限
if (empty($content['wechat'])) $user['wechat'] = ''; //微信查看权限
if (empty($content['qq'])) $user['qq'] = ''; //qq查看权限
$user['content'] = $content; //权限
}
$this->success('个人详情', $user);
}
@@ -92,7 +132,7 @@ class User extends Common
{
$user = auth_user();
$params = $this->request->only(['avatar', 'nickname', 'gender']);
$params = $this->request->only(['avatar', 'nickname', 'mobile', 'gender', 'qq', 'wechat', 'years', 'bio']);
$this->svalidate($params);
$user->save($params);
@@ -147,7 +187,7 @@ class User extends Common
}
//如果已经有账号则直接登录
$ret = $this->auth->direct($user->id);
}else {
} else {
$this->error('该手机号暂未注册');
}
if (isset($ret) && $ret) {
@@ -302,4 +342,279 @@ class User extends Common
$this->success('注销成功');
}
// 发送用户消息
public function sendMsg()
{
$params = $this->request->param();
if ($params['user_id'] == $this->auth->id) {
$this->error('不能发送给自己');
}
$user = auth_user();
$target = UserModel::get($params['user_id']);
if (empty($target)) {
$this->error('用户不存在');
}
Db::startTrans();
try {
$result = (new Message())->allowField(true)->save([
'type' => 2,
'name' => $user['nickname'],
'avatar' => $user['avatar'],
'from_id' => $user['id'],
'user_id' => $params['user_id'],
'content' => json_encode([
'topic' => '好友消息',
'time' => date('Y-m-d H:i:s'),
'content' => $params['content']
]),
'status' => 0
]);
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result === false) {
$this->error('操作失败');
}
$this->success('Success');
}
// 分类消息
public function msgGroup()
{
$params = $this->request->param();
$member = Menber::where('user_id', $this->auth->id)->where('role', '>', 1)->column('club_id');
if (!empty($member)) {
$query1 = Message::field('*,count(*) as num')->where(function ($q1) use ($member) {
$q1->where('user_id', $this->auth->id)
->whereOr(function ($q2) use ($member) {
$q2->where('type', 3)->whereIn('from_id', $member);
});
});
$query2 = Message::field('*,count(*) as num')->where(function ($q1) use ($member) {
$q1->where('user_id', $this->auth->id)
->whereOr(function ($q2) use ($member) {
$q2->where('type', 3)->whereIn('from_id', $member);
});
});
} else {
$query1 = Message::field('*,count(*) as num')->where('user_id', $this->auth->id);
$query2 = Message::field('*,count(*) as num')->where('user_id', $this->auth->id);
}
if (isset($params['type'])) {
$query1->where('type', $params['type']);
$query2->where('type', $params['type']);
}
$query1->group('from_id')->order('update_time', 'desc');
$query2->group('from_id')->order('update_time', 'desc');
$num = $query2->where('status', 0)->column('count(*) as num', 'from_id');
$res = $query1->paginate($params['pageSize'] ?? 10);
$list = $res->items();
foreach ($list as &$r) {
$r['content'] = json_decode($r['content'], true);
$r['num'] = $num[$r['from_id']] ?? 0;
}
$this->success('Success', ['list' => $list, 'count' => $res->total()]);
}
// 用户消息
public function msg()
{
$params = $this->request->param();
$member = Menber::where('user_id', $this->auth->id)->where('role', '>', 1)->column('club_id');
if (!empty($member)) {
$query = Message::where(function ($q1) use ($member) {
$q1->where('user_id', $this->auth->id) //用户消息
->whereOr(function ($q2) use ($member) { //俱乐部消息
$q2->where('type', 3)->whereIn('from_id', $member);
});
});
} else {
$query = Message::where('user_id', $this->auth->id);
}
if (isset($params['type'])) {
$query->where('type', $params['type']);
}
$res = $query->paginate($params['pageSize'] ?? 10);
$list = $res->items();
foreach ($list as &$r) {
$r['content'] = json_decode($r['content'], true);
}
$this->success('Success', ['list' => $list, 'count' => $res->total()]);
}
// 消息读取
public function msgRead()
{
$params = $this->request->param();
$model = Message::get($params['msg_id'] ?? NULL);
if (empty($model)) {
$this->error(__('No rows were found'));
}
$model->save(['status' => 1]); //已读
$model['content'] = json_decode($model['content'], true);
$this->success('Success', $model);
}
// 申请联系信息
public function apply()
{
$params = $this->request->param();
if (empty($params['content'])) {
return $this->error('申请内容不能为空');
}
Db::startTrans();
try {
$fromUser = auth_user();
$user = UserModel::get($params['user_id'] ?? NULL);
if (empty($user)) {
return $this->error('用户不存在');
}
$apply = (new Apply);
if ($apply::get(['type' => 2, 'user_id' => $fromUser->id, 'target_id' => $user->id, 'status' => 1])) {
return $this->error('申请处理中');
}
$apply->allowField(true)->save([ // 记录申请
'type' => 2,
'user_id' => $fromUser->id,
'target_id' => $user->id,
'content' => $params['content'],
'reason' => $params['reason'] ?? '',
'status' => 1
]);
// (new Message())->allowField(true)->save([ // 消息通知
// 'type' => 2,
// 'name' => $fromUser->nickname,
// 'avatar' => $fromUser->avatar,
// 'from_id' => $fromUser->id,
// 'user_id' => $user->id,
// 'content' => json_encode([
// 'topic' => '申请联系信息',
// '申请人' => $fromUser->nickname,
// '申请时间' => date('Y-m-d H:i:s'),
// 'reason' => $params['reason'] ?? '',
// 'apply_id' => $apply->id
// ])
// ]);
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('已邀请,请等候审核');
}
// 获取申请列表
public function applyList()
{
$params = $this->request->param();
$query = Apply::where('type', 2)->where('target_id', $this->auth->id);
if (isset($params['status'])) {
$query->where('status', $params['status']);
}
$applyList = $query->select();
$this->success('Success', $applyList);
}
// 处理申请
public function handle()
{
$params = $this->request->param();
Db::startTrans();
try {
$apply = Apply::get(['id' => $params['apply_id'], 'user_id' => $this->auth->id, 'status' => 1]);
if (empty($apply)) {
return $this->error('申请记录不存在');
}
if ($params['status'] == 2) { //同意
$relation = Relation::get(['user_id' => $apply['user_id'], 'target_id' => $apply['user_id']]);
if (empty($relation)) {
$relation = new Relation;
}
$relation->allowField(true)->save([
'target_id' => $apply['user_id'],
'user_id' => $apply['target_id'],
'status' => 1,
'content' => $params['content'],
]);
}
$apply->save([
'status' => $params['status'],
'reply' => $params['reply'] ?? ''
]);
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('Success');
}
// 好友关系
public function relation()
{
$params = $this->request->param();
if (!isset($params['status'])) {
$this->error('缺少参数:status');
}
$ids = explode(',', $params['user_id']);
if (empty($ids)) {
$this->error('缺少参数:user_id');
}
foreach ($ids as $id) {
if ($id == $this->auth->id) {
$this->error('不能设置与自己的好友关系');
}
}
Db::startTrans();
try {
$dbUserId = UserModel::where('id', 'IN', $ids)->column('id');
if (!empty($diffId = array_diff($ids, $dbUserId))) {
return $this->error('用户不存在:' . implode(',', $diffId));
}
$res = Relation::where('user_id', $this->auth->id)->where('target_id', 'IN', $ids)->update(['status' => $params['status']]);
if ($res < count($ids)) {
$target = Relation::where('user_id', $this->auth->id)->where('target_id', 'IN', $ids)->column("target_id");
$_relationModel = new Relation;
foreach ((array_diff($ids, $target)) as $id) {
(clone $_relationModel)->allowField(true)->save([
'user_id' => $this->auth->id,
'target_id' => $id,
'status' => $params['status'],
]);
}
}
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('Success');
}
// 获取关系列表
public function list()
{
$params = $this->request->param();
$query = Relation::alias('r')
->join([UserModel::$tableName => 'u'], 'u.id=r.target_id')
->field('r.*,u.avatar,u.gender,u.nickname')
->where('user_id', $this->auth->id);
if (isset($params['status'])) {
$query->where('r.status', $params['status']);
} else {
$query->where('r.status', '<>', 0);
}
$list = $query->select();
foreach ($list as &$l) {
$l['content'] = json_decode($l['content'] ?? '[]', true);
}
$this->success('Success', $list);
}
}

View File

@@ -0,0 +1,282 @@
<?php
namespace addons\shopro\controller\zy;
use think\Db;
use think\Exception;
use app\admin\model\zy\Club;
use app\admin\model\zy\Stadium;
use app\admin\model\zy\game\Game;
use think\exception\PDOException;
use app\admin\model\shopro\Category;
use app\admin\model\zy\link\Message;
use app\admin\model\zy\game\GameJoin;
use think\exception\ValidateException;
use app\admin\model\shopro\goods\Goods;
use app\admin\model\zy\game\Participant;
use addons\shopro\service\order\OrderCreate;
use app\admin\controller\shopro\traits\SkuPrice;
class Activity extends Base
{
use SkuPrice;
protected $noNeedLogin = ['index', 'test'];
public function __construct()
{
$this->model = new \app\admin\model\zy\game\Activity;
parent::__construct();
}
public function index()
{
$params = $this->request->param();
$query = $this->model->alias('a')
->join([Stadium::$tableName => 's'], 's.id = a.gym_id', 'LEFT')
->join([Club::$tableName => 'c'], 'c.id = a.club_id', 'LEFT')
->field('a.*, s.name as gym_name, c.name as club_name');
if (isset($params['name'])) {
$query->where('a.name', 'like', '%' . $params['name'] . '%');
}
if (isset($params['gym_id'])) {
$query->where('a.gym_id', $params['gym_id']);
}
if (isset($params['club_id'])) {
$query->where('a.club_id', $params['club_id']);
}
if (isset($params['week'])) {
$query->where('week', $params['week']);
}
if (isset($params['pid'])) {
$query->where('pid', $params['pid']);
} else {
$query->where('pid', 0);
}
$res = $query->paginate($params['pageSize'] ?? 10);
$list = $res->items();
foreach ($list as &$v) {
$v['public_time'] = json_decode($v['public_time'] ?? '[]', true);
$v['join_start_time'] = json_decode($v['join_start_time'] ?? '[]', true);
$v['join_end_time'] = json_decode($v['join_end_time'] ?? '[]', true);
$v['quit_time'] = json_decode($v['quit_time'] ?? '[]', true);
$v['cost'] = json_decode($v['cost'] ?? '[]', true);
$v['referee'] = explode(',', $v['referee'] ?? '');
}
$this->success('Success', ['list' => $list, 'count' => $res->total()]);
}
public function view()
{
$model = $this->model->get($this->request->param('id'));
if (empty($model)) {
$this->error(__('No rows were found'));
}
$model['public_time'] = json_decode($model['public_time'] ?? '[]', true);
$model['join_start_time'] = json_decode($model['join_start_time'] ?? '[]', true);
$model['join_end_time'] = json_decode($model['join_end_time'] ?? '[]', true);
$model['quit_time'] = json_decode($model['quit_time'] ?? '[]', true);
$model['cost'] = json_decode($model['cost'] ?? '[]', true);
$model['referee'] = explode(',', $model['referee'] ?? '');
$this->success('Success', $model);
}
public function add()
{
$params = $this->request->param();
Db::startTrans();
try {
$category = new Category;
$category->name = $params['name'];
$category->parent_id = 157;
$category->description = '报名费商品';
$category->save();
foreach ($this->model->costKey as $key => $val) {
if (isset($params['cost'][$key])) {
$goods = new Goods;
$goods->category_ids = $category->id;
$goods->subtitle = $key;
$goods->title = $val;
$goods->type = 'virtual';
$goods->limit_type = 'none';
$goods->dispatch_type = 'autosend';
$goods->dispatch_id = 2;
$goods->is_sku = 0;
$goods->original_price = $params['cost'][$key];
$goods->price = $params['cost'][$key];
$goods->save();
$this->zySku($goods, 'add');
} else {
throw new Exception('请填写' . $val);
}
}
$params['public_time'] = json_encode($params['public_time'] ?? []);
$params['join_start_time'] = json_encode($params['join_start_time'] ?? []);
$params['join_end_time'] = json_encode($params['join_end_time'] ?? []);
$params['quit_time'] = json_encode($params['quit_time'] ?? []);
$params['cost']['goods_category_id'] = $category->id;
$params['cost'] = json_encode($params['cost'] ?? []);
$result = $this->model->allowField(true)->save($params);
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if (empty($result)) {
$this->error('操作失败');
}
$this->success('Success');
}
public function update()
{
$params = $this->request->param();
$model = $this->model->get($params['id']);
if (empty($model)) {
$this->error(__('No rows were found'));
}
$cost = json_decode($model->cost, true);
$goods = Goods::where('category_ids', $cost['goods_category_id'])->select();
foreach ($this->model->costKey as $key => $val) {
if (isset($params['cost'][$key])) {
foreach ($goods as $g) { //更新报名费价格
if ($g['title'] == $val && $g['price'] != $params['cost'][$key]) {
$g->save(['price' => $params['cost'][$key]]);
$this->zySku($g, 'edit');
}
}
} else {
throw new Exception('请填写' . $val);
}
}
$params['public_time'] = json_encode($params['public_time'] ?? []);
$params['join_start_time'] = json_encode($params['join_start_time'] ?? []);
$params['join_end_time'] = json_encode($params['join_end_time'] ?? []);
$params['quit_time'] = json_encode($params['quit_time'] ?? []);
$params['cost']['goods_category_id'] = $cost['goods_category_id'];
$params['cost'] = json_encode($params['cost'] ?? []);
Db::startTrans();
try {
$result = $model->allowField(true)->save($params);
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if (empty($result)) {
$this->error('操作失败');
}
$this->success('Success');
}
// 启动周期性活动创建比赛任务
public function test()
{
if (!\think\Cache::has('addons\shopro\job\Test@zy')) {
$res = \think\Queue::push('\addons\shopro\job\Test@zy', time(), 'shopro');
\think\Cache::set('addons\shopro\job\Test@zy', $res);
$this->success('Success', $res);
}
$this->success('Success', '任务已存在');
}
// 比赛报名
public function gameJoin()
{
Db::startTrans();
try {
$params = $this->request->param();
if (isset($params['game_id'])) {
$game = Game::get($params['game_id']);
} else {
$game = Game::where('id', $params['act_id'] ?? NULL)
->where('week', $params['week'] ?? NULL)
->where('date', $params['date'] ?? NULL)
->find();
}
if (empty($game)) {
$this->error('活动不存在');
}
$currentTime = date('Y-m-d H:i:s');
if ($game['join_start_time'] > $currentTime || $game['join_end_time'] < $currentTime) {
$this->error('不在报名时间');
}
if (empty($params['users']) || !is_array($params['users']) || empty($params['goods_list']) || !is_array($params['goods_list'])) {
$this->error('请核对报名人员');
}
$join = GameJoin::where(['game_id' => $game['id'], 'user_id' => $this->auth->id])->where('status', '>', -1)->find();
if (!empty($join)) {
$this->error('您已报名此活动');
}
$order = GameJoin::where('game_id', $game['id'])->count();
$gender = ['man' => 0, 'woman' => 0];
$user = auth_user();
$participant = $msgs = [];
foreach ($params['users'] as $u) {
$order++;
$participant[] = [
'user_id' => $u['user_id'],
'gender' => $u['gender'],
'avatar' => $u['avatar'],
'name' => $u['nickname'],
'game_id' => $game['id'],
'signin' => 0,
'order' => $order,
'status' => ($order > $game['limit_num']) ? 0 : 1, //超过报名人数为候补
];
if ($u['gender'] == 0) {
$gender['woman'] += 1;
} else {
$gender['man'] += 1;
}
$msgs[] = [
'type' => 1,
'name' => '系统消息',
'avatar' => '',
'from_id' => 0,
'user_id' => $u['user_id'],
'content' => json_encode([
'msgType' => 1,
'content' => $user['nickname'] . ' 帮你报名了组球',
'game_id' => $game['id'],
'act_id' => $game['act_id'],
])
];
}
foreach ($gender as $k => $v) {
if ($params['goods_list'][$k]['goods_num'] != $v) {
$this->error('报名人数错误');
}
}
$cost = json_decode($game['cost'], true);
if (!empty($cost['type']) && ($cost['type'] == 10 || $cost['type'] == 30)) {
$orderCreate = new OrderCreate($params);
$result = $orderCreate->calc('create');
$order = $orderCreate->create($result);
$join = new GameJoin;
$join->allowField(true)->save([
'act_id' => $game['act_id'],
'game_id' => $game['id'],
'user_id' => $this->auth->id,
'order_id' => $order['id'],
'status' => 0, //待支付
'users' => json_encode($params['users'] ?? [])
]);
}
foreach ($participant as &$p) {
$p['game_join_id'] = $join->id;
}
(new Participant)->insertAll($participant);
(new Message())->insertAll($msgs);
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage(), $e);
}
$this->success('Success', $order ?? []);
}
}

View File

@@ -10,18 +10,16 @@ use think\exception\ValidateException;
class Base extends Common
{
protected $noNeedLogin = ['index'];
protected $noNeedRight = ['*'];
protected $model;
protected $user;
public function index()
public function _initialize()
{
$params = $this->request->param();
if (isset($params['name'])) {
$this->model->where('name', 'like', '%' . $params['name'] . '%');
}
$res = $this->model->select();
$this->success('获取成功', $res);
parent::_initialize();
$this->user = auth_user();
}
public function add()
@@ -37,9 +35,9 @@ class Base extends Common
$this->error($e->getMessage());
}
if ($result === false) {
$this->error(__('No rows were inserted'));
$this->error('操作失败');
}
$this->success();
$this->success('Success');
}
public function update()
@@ -59,9 +57,9 @@ class Base extends Common
$this->error($e->getMessage());
}
if ($result === false) {
$this->error(__('No rows were inserted'));
$this->error('操作失败');
}
$this->success();
$this->success('Success');
}
public function view()
@@ -70,6 +68,6 @@ class Base extends Common
if (empty($model)) {
$this->error(__('No rows were found'));
}
$this->success($model);
$this->success('Success', $model);
}
}

View File

@@ -0,0 +1,289 @@
<?php
namespace addons\shopro\controller\zy;
use think\Db;
use think\Exception;
use app\admin\model\zy\Club;
use app\admin\model\zy\Menber;
use think\exception\PDOException;
use app\admin\model\zy\circle\Likes;
use app\admin\model\zy\link\Message;
use app\admin\model\zy\link\Relation;
use app\admin\model\zy\circle\Comment;
use think\exception\ValidateException;
use app\admin\model\zy\circle\Circle as CircleModel;
class Circle extends Base
{
public function index()
{
$params = $this->request->param();
$sub = CircleModel::alias('c')
->join([Likes::$tableName => 'l'], 'c.id = l.circle_id', 'LEFT')
->field("c.*,JSON_ARRAYAGG(JSON_OBJECT(
'id', l.id,
'user_id', l.user_id,
'nickname', l.nickname,
'avatar', l.avatar,
'gender', l.gender
)) AS likes")->group('c.id')->buildSql();
$query = Comment::alias('m')
->join([$sub => 'c'], 'c.id = m.circle_id', 'RIGHT')
->field("c.*,
JSON_ARRAYAGG(JSON_OBJECT(
'id', m.id,
'pid', m.pid,
'puser_id', m.puser_id,
'pnickname', m.pnickname,
'user_id', m.user_id,
'nickname', m.nickname,
'avatar', m.avatar,
'gender', m.gender,
'content', m.content,
'create_time', m.create_time
)) AS comment")->group('c.id');
if (isset($params['status'])) {
$query->where('c.status', $params['status']);
} else {
$query->where('c.status', 1);
}
if (isset($params['club_id'])) {
$query->where('c.club_id', $params['club_id']);
}
if (isset($params['user_id'])) {
$query->where('c.user_id', $params['user_id']);
}
if (isset($params['friend'])) {
$friend = Relation::where('user_id', $this->auth->id)->where('status', 'IN', explode(',', $params['friend']))->column('target_id');
$query->where('c.user_id', 'IN', $friend);
}
$query->order(['c.top' => 'desc', 'c.create_time' => 'desc']);
$res = $query->paginate($params['pageSize'] ?? 10);
$list = $res->items();
foreach ($list as &$r) {
$r['likes'] = json_decode($r['likes'], true);
if (count($r['likes']) == 1 && empty($r['likes'][0]['id'])) $r['likes'] = [];
$r['comment'] = buildTree(json_decode($r['comment'], true));
}
$this->success('Success', ['list' => $list, 'count' => $res->total()]);
}
public function view()
{
$model = CircleModel::get($this->request->param('id'));
if (empty($model)) {
$this->error(__('No rows were found'));
}
$this->success('Success', $model);
}
public function add()
{
$params = $this->request->param();
if (empty($params['content'])) {
$this->error('内容不能为空');
}
$user = auth_user();
$club = Menber::alias('m')->join([Club::$tableName => 'c'], 'm.club_id=c.id')
->field('c.name')
->where(['m.club_id' => $params['club_id'], 'm.user_id' => $user['id']])
->where('m.role', '>', 0)->find();
if (empty($club)) {
$this->error('你无权在此俱乐部发布');
}
$params['user_id'] = $user['id'];
$params['nickname'] = $user['nickname'];
$params['avatar'] = $user['avatar'];
$params['gender'] = $user['gender'];
$params['club_name'] = $club['name'];
$params['status'] = 0;
Db::startTrans();
try {
$result = (new CircleModel)->allowField(true)->save($params);
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result === false) {
$this->error('操作失败');
}
$this->success('Success');
}
// 点赞
public function like()
{
$params = $this->request->param();
$circle = CircleModel::get($params['circle_id']);
if (empty($circle)) {
$this->error('数据不存在');
}
$user = auth_user();
Db::startTrans();
try {
$like = Likes::get(['circle_id' => $params['circle_id'], 'user_id' => $user['id']]);
if (empty($like)) { // 点赞
(new Likes)->allowField(true)->save([
'circle_id' => $params['circle_id'],
'user_id' => $user['id'],
'nickname' => $user['nickname'],
'avatar' => $user['avatar'],
'gender' => $user['gender'],
]);
// (new Message())->allowField(true)->save([ // 消息通知
// 'type' => 1,
// 'name' => '互动消息',
// 'avatar' => '',
// 'from_id' => 0,
// 'user_id' => $circle->user_id,
// 'content' => json_encode([
// 'topic' => '点赞',
// 'content' => $user['nickname'] . '点赞了你的帖子',
// 'circle_id' => $circle->id
// ])
// ]);
} else { // 取消点赞
$like->delete();
}
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('Success');
}
// 评论
public function comment()
{
$params = $this->request->param();
$circle = CircleModel::get($params['circle_id']);
if (empty($circle)) {
$this->error('数据不存在');
}
if (empty($params['content'])) {
$this->error('内容不能为空');
}
$pcomment = Comment::get($params['pid']);
if (!empty($params['pid']) && empty($pcomment)) {
$this->error('回复的评论不存在');
}
$user = auth_user();
Db::startTrans();
try {
(new Comment)->allowField(true)->save([
'circle_id' => $params['circle_id'],
'pid' => $params['pid'],
'puser_id' => $pcomment['user_id'] ?? 0,
'pnickname' => $pcomment['nickname'] ?? '',
'user_id' => $user['id'],
'nickname' => $user['nickname'],
'avatar' => $user['avatar'],
'gender' => $user['gender'],
'content' => $params['content'],
]);
// (new Message())->allowField(true)->save([ // 消息通知
// 'type' => 1,
// 'name' => '互动消息',
// 'avatar' => '',
// 'from_id' => 0,
// 'target_id' => $circle->user_id,
// 'content' => json_encode([
// 'topic' => '评论',
// 'content' => $user['nickname'] . '评论了你的帖子',
// 'circle_id' => $circle->id
// ])
// ]);
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('Success');
}
public function approve()
{
$params = $this->request->param();
$ids = explode(',', $params['ids'] ?? '');
if (empty($ids) || empty($params['club_id'])) {
$this->error('参数错误');
}
if (empty($params['status']) || ($params['status'] != -1 && $params['status'] != 1)) {
$this->error('status:参数错误');
}
$member = Menber::get(['club_id' => $params['club_id'], 'user_id' => $this->auth->id]);
if (empty($member) || $member->role < 2) {
$this->error('无权审核');
}
$models = CircleModel::where('id', 'IN', $ids)->where('club_id', $params['club_id'])->select();
if (empty($models)) {
$this->error('数据不存在');
}
Db::startTrans();
try {
foreach ($models as $model) {
if ($model->status != 0) {
throw new Exception($model->id . ' 此记录不在待审核状态');
}
$model->save(['status' => $params['status']]);
// (new Message())->allowField(true)->save([ // 消息通知
// 'type' => 3,
// 'name' => '通知消息',
// 'avatar' => '',
// 'from_id' => 1,
// 'user_id' => $model->user_id,
// 'content' => json_encode([
// 'topic' => '影圈审核',
// 'result' => ($params['status'] == 1) ? '通过' : '不通过',
// 'circle_id' => $model->id
// ])
// ]);
}
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('Success', count($models));
}
public function delete()
{
$params = $this->request->param();
$ids = explode(',', $params['ids'] ?? '');
if (empty($ids) || empty($params['club_id'])) {
$this->error('参数错误');
}
$member = Menber::get(['club_id' => $params['club_id'], 'user_id' => $this->auth->id]);
if (empty($member) || $member->role < 2) {
$this->error('无权删除');
}
$result = CircleModel::where('id', 'IN', $ids)->where('club_id', $params['club_id'])->delete();
$this->success('Success', $result);
}
public function top()
{
$params = $this->request->param();
$model = CircleModel::get($params['id'] ?? null);
if (empty($model)) {
$this->error('数据不存在');
}
$member = Menber::get(['club_id' => $model['club_id'], 'user_id' => $this->auth->id]);
if (empty($member) || $member->role < 2) {
$this->error('无权操作');
}
$result = CircleModel::where('club_id', $model['club_id'])->column('max(top) as top');
$model->save(['top' => $result[0] + 1]);
$this->success('Success', $model);
}
}

View File

@@ -2,14 +2,23 @@
namespace addons\shopro\controller\zy;
use think\Db;
use think\Exception;
use app\admin\model\zy\Menber;
use app\admin\model\zy\Stadium;
use app\admin\model\zy\game\Game;
use think\exception\PDOException;
use app\admin\model\zy\link\Apply;
use app\admin\model\zy\link\Message;
use app\admin\model\zy\link\Visitor;
use app\admin\model\shopro\user\User;
use app\admin\model\zy\game\Activity;
use think\exception\ValidateException;
use app\admin\model\zy\game\Participant;
use app\admin\model\zy\link\Relation;
class Club extends Base
{
// protected $noNeedLogin = ['index'];
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
public function __construct()
{
$this->model = new \app\admin\model\zy\Club;
@@ -19,12 +28,402 @@ class Club extends Base
public function index()
{
$params = $this->request->param();
$model = $this->model;
$sub = Game::alias('g')
->join([Participant::$tableName => 'p'], 'p.game_id=g.id', 'LEFT')
->field('g.id,g.pid,g.club_id,g.act_id,g.date,g.name,g.start_time,g.end_time,g.cost,JSON_ARRAYAGG(p.avatar) as avatar,count(p.id) as join_num')
->where('g.date', '>=', date('Y-m-d'))
->order('g.date', 'asc')->group('g.id')->buildSql();
$query = $this->model->alias('c')
->join([Stadium::$tableName => 's'], 's.id = c.gym_id', 'LEFT')
->join([$sub => 'g'], 'g.club_id = c.id', 'LEFT')
->field("c.*, s.position,s.name as gym_name,JSON_ARRAYAGG(JSON_OBJECT(
'id', g.id,
'pid', g.pid,
'act_id', g.act_id,
'date', g.date,
'name', g.name,
'start_time', g.start_time,
'end_time', g.end_time,
'join_num', g.join_num,
'avatar', g.avatar,
'cost', g.cost
)) AS games")->group('c.id');
if (isset($params['name'])) {
$model->where('name', 'like', '%' . $params['name'] . '%');
$query->where('c.name', 'like', '%' . $params['name'] . '%');
}
$res = $model->select();
if (isset($params['tag'])) {
$query->where('c.tags', 'like', '%' . $params['tag'] . '%');
}
if (isset($params['gym_id'])) {
$query->where('c.gym_id', $params['gym_id']);
}
if (isset($params['order'])) {
$query->order($params['order'], $params['sort'] ?? NULL);
}
$res = $query->paginate($params['pageSize'] ?? 10);
$list = $res->items();
foreach ($list as &$l) {
$games = json_decode($l['games'], true);
if (count($games) == 1 && empty($games[0]['id'])) $games = [];
foreach ($games as &$g) {
$g['cost'] = json_decode($g['cost'], true);
}
$l['games'] = $games;
}
$this->success('Success', ['list' => $list, 'count' => $res->total()]);
}
$this->success('获取成功', $res);
public function view()
{
$model = $this->model->get($this->request->param('id'))->toarray();
if (empty($model)) {
$this->error(__('No rows were found'));
}
$menber = Menber::alias('m')
->join([User::$tableName => 'u'], 'u.id = m.user_id')
->where('club_id', $model['id'])->field('gender,count(*) as num')->group('u.gender')
->column('count(*) as num', 'gender');
$model['gender0'] = $menber[0] ?? 0;
$model['gender1'] = $menber[1] ?? 0;
$this->model->where('id', $model['id'])->setInc('attention');
$user = auth_user();
$visitor = Visitor::where('type', 0)->where('obj_id', $model['id'])->where('user_id', $user['id'])->find();
if (empty($visitor)) {
$visitor = new Visitor;
}
$visitor->allowField(true)->save([
'type' => 0,
'obj_id' => $model['id'],
'user_id' => $user['id'],
'nickname' => $user['nickname'],
'avatar' => $user['avatar'],
'gender' => $user['gender'],
'times' => empty($visitor->times) ? 1 : $visitor->times + 1
]);
$this->success('Success', $model);
}
public function add()
{
$result = false;
$params = $this->request->param();
Db::startTrans();
try {
$params['president'] = $this->auth->id;
$result = $this->model->allowField(true)->save($params);
$menber = new Menber;
$menber->allowField(true)->save([
'club_id' => $this->model->id,
'user_id' => $this->auth->id,
'role' => 3
]);
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result === false) {
$this->error('操作失败');
}
$this->success('Success', $result);
}
// 获取俱乐部成员
public function menber()
{
$params = $this->request->param();
$sub = Relation::field('user_id,target_id,content')->where('user_id', $this->auth->id)->buildSql();
$query = Db::table(Menber::$tableName)->alias('m')
->join([User::$tableName => 'u'], 'u.id = m.user_id', 'LEFT')
->join([$sub => 'r'], 'r.target_id = m.user_id', 'LEFT')
->field('m.*,u.avatar,u.gender,u.nickname,u.wechat,u.qq,u.mobile,r.content');
if (empty($params['id'])) {
return $this->error('参数错误');
}
$query->where('club_id', $params['id']);
if (isset($params['role'])) {
$query->where('role', 'IN', explode(',', $params['role']));
} else {
$query->where('role', '>', 0);
}
if (isset($params['nickname'])) {
$query->where('nickname', 'LIKE', '%' . $params['nickname'] . '%');
}
if (isset($params['order'])) {
$query->order($params['order'], $params['sort'] ?? NULL);
}
$res = $query->paginate($params['pageSize'] ?? 10);
$list = $res->items();
foreach ($list as &$l) {
$l['content'] = json_decode($l['content'] ?? '[]', true);
}
$this->success('Success', ['list' => $list, 'count' => $res->total()]);
}
// 获取俱乐部活动
public function activity()
{
$params = $this->request->param();
$query = Db::table(Activity::$tableName)
->where('pid', 0) //主活动
->field('');
if (isset($params['club_id'])) {
$query->where('club_id', $params['club_id']);
}
if (isset($params['week'])) {
$query->where('week', $params['week']);
}
$res = $query->select();
$this->success('Success', $res);
}
// 申请加入俱乐部
public function apply()
{
$params = $this->request->param();
Db::startTrans();
try {
$club = $this->model->get($params['club_id']);
if (empty($club)) {
return $this->error('俱乐部不存在');
}
if ($club['join_type'] > 1) {
$this->error('该俱乐部不允许申请');
}
$user = Menber::get(['club_id' => $club->id, 'user_id' => $this->auth->id]);
if (empty($user)) {
$user = new Menber;
} else {
if ($user['role'] > 0) {
$this->error('您已经是俱乐部成员,无需重复申请');
} else if ($user['role'] == -1) {
$this->error('您已被管理员拉黑');
}
}
if ($club['join_type'] == 0) {
$user->allowField(true)->save([
'club_id' => $club->id,
'user_id' => $this->auth->id,
'role' => 1
]);
} else {
if (Apply::get(['type' => 1, 'user_id' => $this->auth->id, 'target_id' => $club->id, 'status' => 1])) {
return $this->error('申请审核中');
}
$apply = new Apply;
$apply->allowField(true)->save([ // 记录申请
'type' => 1,
'user_id' => $this->auth->id,
'target_id' => $club->id,
'content' => json_encode(['reason' => $params['reason'] ?? '']),
'reason' => $params['reason'],
'status' => 1
]);
// (new Message())->allowField(true)->save([ // 消息通知
// 'type' => 3,
// 'name' => $club->name,
// 'avatar' => $club->logo,
// 'from_id' => $club->id,
// 'content' => json_encode([
// 'topic' => '俱乐部加入申请',
// '俱乐部名称' => $club->name,
// '申请人' => $this->user->nickname,
// '申请时间' => date('Y-m-d H:i:s'),
// 'reason' => $params['reason'] ?? '',
// 'apply_id' => $apply->id
// ])
// ]);
}
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('Success');
}
//join_type 0:'开放加入,无需审核',1:'开放申请,审核加入',2:'会员邀请,无需审核',3:'会员邀请,审核加入',4:'仅管理员邀请,无需审核'
// 邀请加入俱乐部
public function invite()
{
$params = $this->request->param();
Db::startTrans();
try {
$club = $this->model->get($params['club_id']);
if (empty($club)) {
return $this->error('俱乐部不存在');
}
$user = User::get($params['user_id']);
if (empty($user)) {
return $this->error('用户不存在');
}
$menber = Menber::where('club_id', $params['club_id'])
->where('user_id', $this->auth->id)
->where('role', '>', 0)->find();
if (empty($menber)) {
$this->error('您无权邀请加入俱乐部');
}
$invate = Menber::get(['user_id' => $params['user_id'], 'club_id' => $params['club_id']]);
if (empty($invate)) {
$invate = new Menber;
} else {
if ($invate['role'] > 0) {
$this->error('用户已在俱乐部');
} else if ($invate['role'] == -1) {
$this->error('用户已被管理员拉黑');
}
}
if ($menber['role'] > 1 || $club['join_type'] == 0 || $club['join_type'] == 2) { // 管理员或者开放加入
$invate->allowField(true)->save([
'club_id' => $club->id,
'user_id' => $user->id,
'role' => 1
]);
} else {
if (Apply::get(['type' => 1, 'user_id' => $this->auth->id, 'target_id' => $user->id, 'status' => 1])) {
return $this->error('申请审核中');
}
$apply = new Apply;
$apply->allowField(true)->save([ // 记录申请
'type' => 1,
'user_id' => $user->id,
'target_id' => $club->id,
'content' => json_encode(['reason' => $params['reason'] ?? '']),
'reason' => $params['reason'],
'status' => 1
]);
// (new Message())->allowField(true)->save([ // 消息通知
// 'type' => 3,
// 'name' => $club->name,
// 'avatar' => $club->logo,
// 'from_id' => $club->id,
// 'content' => json_encode([
// 'topic' => '俱乐部加入申请',
// '俱乐部名称' => $club->name,
// '申请人' => $user->nickname,
// '申请时间' => date('Y-m-d H:i:s'),
// 'reason' => $params['reason'] ?? '',
// 'apply_id' => $apply->id,
// ])
// ]);
}
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('Success');
}
// 获取申请列表
public function applyList()
{
$params = $this->request->param();
$club = $this->model->get($params['club_id']);
if (empty($club)) {
return $this->error('俱乐部不存在');
}
$menber = Menber::where('club_id', $params['club_id'])
->where('user_id', $this->auth->id)
->where('role', '>', 1)->find();
if (empty($menber)) {
$this->error('您无权处理申请');
}
$query = Apply::where('type', 1)->where('target_id', $params['club_id']);
if (isset($params['status'])) {
$query->where('status', $params['status']);
}
$applyList = $query->select();
$this->success('Success', $applyList);
}
// 处理申请
public function handle()
{
$params = $this->request->param();
Db::startTrans();
try {
$apply = Apply::get(['id' => $params['apply_id'], 'status' => 1]);
if (empty($apply)) {
return $this->error('申请记录不存在');
}
$menber = Menber::where('club_id', $apply['target_id'])
->where('user_id', $this->auth->id)
->where('role', '>', 1)->find();
if (empty($menber)) {
$this->error('您无权处理申请');
}
if ($apply['status'] != 1) {
return $this->error('该申请已处理');
}
if ($params['status'] == 2) {
(new Menber)->allowField(true)->save([
'club_id' => $apply['target_id'],
'user_id' => $apply['user_id'],
'role' => 1
]);
}
$apply->allowField(true)->save([
'status' => $params['status'],
'reply' => $params['reply'] ?? ''
]);
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('Success');
}
// 设置成员角色
public function setmember()
{
$params = $this->request->param();
$user = Menber::where('club_id', $params['club_id'])
->where('user_id', $this->auth->id)
->where('role', '>', 1)->find();
if (empty($user)) {
$this->error('无权限');
}
if (isset($params['role']) && ($params['role'] < -1 || $params['role'] > 2)) {
$this->error('非法角色');
}
$user_ids = explode(',', $params['user_id'] ?? '');
$menber = Menber::where('club_id', $params['club_id'])->where('user_id', 'IN', $user_ids)->select();
if (empty($menber)) {
$this->error('成员不存在');
}
if ($user['role'] != 3) {
if (isset($params['role']) && $params['role'] > 1) {
$this->error('只有会长才能设置管理员');
}
foreach ($menber as $m) {
if ($m['role'] > 1) $this->error('只有会长才能修改管理员');
}
} else {
foreach ($menber as $m) {
if ($m['role'] == 3 && isset($params['role'])) {
$this->error('不可修改会长角色');
}
}
}
$update = [];
if (isset($params['role'])) $update['role'] = $params['role'];
if (isset($params['remark'])) $update['remark'] = $params['remark'];
if (isset($params['tags'])) $update['tags'] = $params['tags'];
Db::startTrans();
try {
Menber::where('club_id', $params['club_id'])->where('user_id', 'IN', $user_ids)->update($update);
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('Success');
}
}

View File

@@ -0,0 +1,493 @@
<?php
namespace addons\shopro\controller\zy;
use think\Db;
use think\Exception;
use app\admin\model\zy\Club;
use app\admin\model\zy\Menber;
use app\admin\model\zy\Stadium;
use think\exception\PDOException;
use app\admin\model\zy\link\Message;
use app\admin\model\zy\game\Activity;
use app\admin\model\zy\game\GameJoin;
use app\admin\model\zy\game\GameMatch;
use think\exception\ValidateException;
use app\admin\model\zy\game\Participant;
use addons\shopro\service\order\OrderRefund;
class Game extends Base
{
public function __construct()
{
$this->model = new \app\admin\model\zy\game\Game;
parent::__construct();
}
public function index()
{
$params = $this->request->param();
$query = $this->model->alias('g')
->join([Participant::$tableName => 'p'], 'p.game_id=g.id', 'LEFT')
->join([Activity::$tableName => 'a'], 'a.id=g.act_id', 'LEFT')
->join([Stadium::$tableName => 's'], 's.id = g.gym_id', 'LEFT')
->join([Club::$tableName => 'c'], 'c.id = g.club_id', 'LEFT')
->field('g.*,a.type,s.name as gym_name,c.name as club_name,JSON_ARRAYAGG(p.avatar) as avatar,count(p.id) as join_num');
if (isset($params['name'])) {
$query->where('g.name', 'like', '%' . $params['name'] . '%');
}
if (isset($params['club_id'])) {
$query->where('g.club_id', $params['club_id']);
}
if (isset($params['week'])) {
$query->where('g.week', $params['week']);
}
if (isset($params['pid'])) {
$query->where('g.pid', $params['pid']);
} else {
$query->where('g.pid', 0);
}
if (isset($params['public_time'])) {
$query->where('g.public_time', $params['public_time']);
} else {
$query->where('g.public_time', '<=', date('Y-m-d H:i:s'));
}
if (isset($params['page'])) {
$pageSize = intval($params['pageSize'] ?? 10);
$offeset = (intval($params['page']) - 1) * $pageSize;
$query->limit($offeset, $pageSize);
}
$res = $query->paginate($params['pageSize'] ?? 10);
$list = $res->items();
foreach ($list as &$v) {
$v['cost'] = json_decode($v['cost'] ?? '[]', true);
$v['avatar'] = json_decode($v['avatar'] ?? '[]', true);
}
$this->success('Success', ['list' => $list, 'count' => $res->total()]);
}
public function view()
{
$model = $this->model->get($this->request->param('id'));
if (empty($model)) {
$this->error(__('No rows were found'));
}
$this->model->where('id', $model['id'])->setInc('attention');
$model['cost'] = json_decode($model['cost'] ?? '[]', true);
$model['referee'] = explode(',', $model['referee'] ?? '');
$this->success('Success', $model);
}
// 退坑
public function quit()
{
$model = $this->model->get($this->request->param('id'));
if (empty($model)) {
$this->error(__('No rows were found'));
}
if ($model['status'] > 1) {
$this->error('活动已开始或结束,不能退出');
}
if ($model['status'] == -1) {
$this->error('活动已取消');
}
$join = GameJoin::where('user_id', $this->auth->id)->find();
if (empty($join) || $join['status'] == -1) {
$this->error('未报名或已取消');
}
if (date('Y-m-d H:i:s') >= $model['quit_time']) {
$this->error('已超过免费退出时间');
}
Db::startTrans();
try {
$join->save(['status' => -1]);
if ($join['status'] == 1) {
$order = $this->model->paid()->where('id', $join->order_id)->lock(true)->find();
if (!$order) {
$this->error('订单不存在或不可退款');
}
$orderRefund = new OrderRefund($order);
$orderRefund->fullRefund(NULL, [
'refund_type' => 'back',
'remark' => '用户自行退出活动'
]);
}
// (new Message())->save([
// 'type' => 1,
// 'name' => '系统消息',
// 'avatar' => '',
// 'from_id' => 0,
// 'user_id' => $join->user_id,
// 'content' => json_encode([
// 'topic' => '退出',
// 'content' => '已退出 ' . $model['name'] . ' 活动',
// 'game_id' => $model->id
// ])
// ]);
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('Success');
}
// 取消活动
public function cancle()
{
$model = $this->model->get($this->request->param('id'));
if (empty($model)) {
$this->error(__('No rows were found'));
}
$member = Menber::get(['club_id' => $model->club_id, 'user_id' => $this->auth->id]);
if (empty($member) || $member->role < 2) {
$this->error('无权取消活动');
}
if ($model['pid'] != 0) {
$this->error('不能取消子活动');
}
if ($model['status'] > 1) {
$this->error('活动已开始或结束,不能取消');
}
if ($model['status'] == -1) {
$this->error('活动已取消');
}
Db::startTrans();
try {
$model->save(['status' => -1]);
(new \app\admin\model\zy\game\Game)->where('pid', $model->id)->update(['status' => -1]);
//取消成功,进入退款流程并通知用户
$join = GameJoin::where('game_id', $model['id'])->select();
$msgs = [];
foreach ($join as $j) {
$j->save(['status' => -1]);
if ($j['status'] == 1) {
$order = $this->model->paid()->where('id', $j->order_id)->lock(true)->find();
if (!$order) {
$this->error('订单不存在或不可退款');
}
$orderRefund = new OrderRefund($order);
$orderRefund->fullRefund(NULL, [
'refund_type' => 'back',
'remark' => '活动取消,全额退款'
]);
}
// $msgs[] = [
// 'type' => 1,
// 'name' => '系统消息',
// 'avatar' => '',
// 'from_id' => 0,
// 'user_id' => $j->user_id,
// 'content' => json_encode([
// 'topic' => '评论',
// 'content' => $model['name'] . ' 活动已取消',
// 'game_id' => $model->id
// ])
// ];
}
// (new Message())->insertAll($msgs);;
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('Success');
}
// 赛制说明
public function describe()
{
$params = $this->request->param();
Db::startTrans();
try {
$game = $this->model->get($params['id'] ?? NULL);
if (empty($game)) {
$this->error('比赛不存在');
}
$gameClass = 'format\\Game' . $game['team_type'] . $game['rule_type'];
if (!class_exists($gameClass)) {
throw new Exception("赛制文件不存在,请联系管理人员: {$gameClass}");
}
$format = new $gameClass;
if (!$format instanceof \format\GameInterface) {
throw new Exception("赛制配置错误,请联系管理人员: {$gameClass}");
}
$describe = $format->describe();
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage(), $e);
}
$this->success('Success', $describe);
}
//参与人员列表
public function participant()
{
$params = $this->request->param();
$query = Participant::where('game_id', $params['game_id']);
if (isset($params['game_join_id'])) {
$query->where('game_join_id', $params['game_join_id']);
}
if (isset($params['status'])) {
$query->where('status', $params['status']);
} else {
$query->where('status', 1);
}
if (isset($params['gender'])) {
$query->where('gender', $params['gender']);
}
if (isset($params['order'])) {
$query->order($params['order'], $params['sort'] ?? NULL);
}
$this->success('Success', $query->select());
}
// 用户
public function setUser()
{
$params = $this->request->param();
$user = Participant::get($params['id'] ?? NULL);
if (empty($user)) {
$this->error('用户不存在');
}
$game = $this->model->get($user['game_id']);
$referee = explode(',', $game['referee'] ?? ''); //裁判
$menber = Menber::where(['club_id' => $game['club_id'], 'user_id' => $this->auth->id])->where('role', '>', 1)->find();
if (empty($menber) && !in_array($this->auth->id, $referee)) {
$this->error('您没有权限');
}
$update['status'] = intval($params['status']);
if ($update['status'] > 1 || $update['status'] < -1) {
$this->error('status错误');
}
if (!empty($params['mark'])) {
$update['mark'] = $params['mark'];
}
$user->save($update);
$this->success('修改成功');
}
// 获取比赛匹配列表
public function macthList()
{
$params = $this->request->param();
Db::startTrans();
try {
$game = $this->model->get($params['game_id'] ?? NULL);
if (empty($game)) {
$this->error('比赛不存在');
}
$dataTime = date('Y-m-d H:i:s');
$startTime = $game['date'] . ' ' . $game['start_time'];
if ($dataTime < $startTime) {
$this->error('比赛时间未开始');
}
$endTime = $game['date'] . ' ' . $game['end_time'];
if ($dataTime > $endTime) {
$this->error('比赛时间已结束');
}
$matchs = GameMatch::where('game_id', $game['id'])->select();
if (empty($matchs)) {
$participant = Participant::where('game_id', $game['id'])->where('status', 1)->select();
$gameClass = 'format\\Game' . $game['team_type'] . $game['rule_type'];
if (!class_exists($gameClass)) {
throw new Exception("赛制文件不存在,请联系管理人员: {$gameClass}");
}
$format = new $gameClass;
if (!$format instanceof \format\GameInterface) {
throw new Exception("赛制配置错误,请联系管理人员: {$gameClass}");
}
$matchs = $format->match($game, $participant);
$res = (new GameMatch)->insertAll($matchs);
$matchs = GameMatch::where('game_id', $game['id'])->select();
}
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage(), $e);
}
foreach ($matchs as $k => &$m) {
if (!empty($params['level']) && $params['level'] != $m['level']) {
unset($matchs[$k]);
continue;
}
$m['teamA'] = json_decode($m['teamA'], true);
$m['teamB'] = json_decode($m['teamB'], true);
}
$this->success('Success', $matchs);
}
public function getMacth()
{
$params = $this->request->param();
$m = GameMatch::get($params['id'] ?? NULL);
if (empty($m)) {
$this->error('对阵记录不存在');
}
$m['teamA'] = json_decode($m['teamA'] ?? '[]', true);
$m['teamB'] = json_decode($m['teamB'] ?? '[]', true);
$m['round1'] = json_decode($m['round1'] ?? '[]', true);
$m['round2'] = json_decode($m['round2'] ?? '[]', true);
$m['round3'] = json_decode($m['round3'] ?? '[]', true);
$m['winner'] = json_decode($m['winner'] ?? '[]', true);
return $this->success('Success', $m);
}
public function scoring()
{
$params = $this->request->param();
Db::startTrans();
try {
$match = GameMatch::get($params['id'] ?? NULL);
if (empty($match)) {
$this->error('对阵记录不存在');
}
$game = $this->model->get($match['game_id']);
$referee = explode(',', $game['referee']?? '');
if (empty($referee)) {
$this->error('请先设置裁判');
}
if (!in_array($this->auth->id, $referee)) {
$this->error('不是裁判无权计分');
}
if (empty($params['round']) || ($params['round'] != 1 && $params['round'] != 2 && $params['round'] != 3)) {
$this->error('回合(局)数错误');
}
$round = 'round' . $params['round'];
if (!empty($match->$round)) {
$this->error('请勿重复提交');
}
$match->$round = json_encode([
'addedA' => $params['addedA'], //队伍B让分
'addedB' => $params['addedB'], //队伍A让分
'scoreA' => $params['scoreA'], //队伍A得分
'scoreB' => $params['scoreB'], //队伍B得分
]);
$totalA = $params['scoreA'] + $params['addedA'];
$totalB = $params['scoreB'] + $params['addedB'];
if ($totalA > $totalB) {
$match->scoreA = $match->scoreA + 1; //队伍A回合得分加1
} else if ($totalA < $totalB) {
$match->scoreB = $match->scoreB + 1; //队伍B回合得分加1
} else {
$this->error('回合(局)内分数不能相等');
}
if (!empty($match->round1) && !empty($match->round2) && !empty($match->round3)) { //3局结束
$match->winner = $match->scoreA > $match->scoreB ? $match->teamA : $match->teamB;
}
$match->save();
// 更新用户得分
$teamA = json_decode($match->teamA, true);
$teamAuser = Participant::where('game_id', $game['id'])
->where('user_id', 'IN', array_column($teamA['user'], 'user_id'))
->where('status', '>', -1)->select();
// dd($teamAuser);
foreach ($teamAuser as $u) {
$u->team = $teamA['name']; //队伍名
$u->score = $totalA; //得分
$u->net_score = $params['scoreA']; //净得分
$u->save();
}
$teamB = json_decode($match->teamB, true);
$teamBuser = Participant::where('game_id', $game['id'])->where('user_id', 'IN', array_column($teamB['user'], 'user_id'))->select();
foreach ($teamBuser as $u) {
$u->team = $teamB['name']; //队伍名
$u->score = $totalA; //得分
$u->net_score = $params['scoreA']; //净得分
$u->save();
}
$undone = GameMatch::where('level', $match['level'])->where('winner', null)->count();
if ($undone == 0) { //所有比赛完成,开启下一轮比赛
$gameClass = 'format\\Game' . $game['team_type'] . $game['rule_type'];
if (!class_exists($gameClass)) {
throw new Exception("赛制文件不存在,请联系管理人员: {$gameClass}");
}
$format = new $gameClass;
if (!$format instanceof \format\GameInterface) {
throw new Exception("赛制配置错误,请联系管理人员: {$gameClass}");
}
$done = GameMatch::where('level', $match['level'])->where('winner', '!=', '')->select();
$matchs = $format->nextLevel($game, $done, $match['level'] + 1);
if (!empty($matchs)) {
(new GameMatch)->insertAll($matchs);
}
}
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage(), $e);
}
$this->success('Success');
}
// 团队排名
public function teamRank()
{
$params = $this->request->param();
$game = $this->model->get($params['game_id']) ?? null;
if (empty($game)) {
$this->error('比赛不存在');
}
$match = GameMatch::field('*,GREATEST(scoreA,scoreB) as score')->where('game_id', $game['id'])->order(['level' => 'desc', 'score' => 'desc'])->select();
$teams = [];
$rank = 1;
foreach ($match as $m) {
$win = json_decode($m['winner'] ?? '', true);
if (empty($win)) { // 未决出胜负的按暂时得分 高的队伍排名靠前
$teamA = json_decode($m['teamA'] ?? '', true);
$teamB = json_decode($m['teamB'] ?? '', true);
if (($m['scoreA'] >= $m['scoreB'])) {
$teamA['rank'] = $rank;
$teamB['rank'] = $rank + 1;
$teams[] = $teamA;
$teams[] = $teamB;
$rank += 2;
} else {
$teamB['rank'] = $rank;
$teamA['rank'] = $rank + 1;
$teams[] = $teamB;
$teams[] = $teamA;
$rank += 2;
}
} else {
$win['rank'] = $rank;
$rank++;
$teams[] = $win;
}
}
$this->success('Success', $teams);
}
// 个人排名
public function rank()
{
$params = $this->request->param();
$game = $this->model->get($params['game_id']) ?? null;
if (empty($game)) {
$this->error('比赛不存在');
}
$list = Participant::where('game_id', $game['id'])->where('status', '>', -1)->order('score', 'desc')->select();
$rank = 1;
foreach ($list as &$l) {
$l['rank'] = $rank;
$rank += 1;
}
$this->success('Success', $list);
}
}

View File

@@ -2,13 +2,12 @@
namespace addons\shopro\controller\zy;
use app\admin\model\zy\link\Visitor;
class Gym extends Base
{
// protected $noNeedLogin = ['index'];
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
public function __construct()
@@ -20,13 +19,35 @@ class Gym extends Base
public function index()
{
$params = $this->request->param();
$model = $this->model->where('status', 1);
$query = $this->model->where('status', 1);
if (isset($params['name'])) {
$model->where('name', 'like', '%' . $params['name'] . '%');
$query->where('name', 'like', '%' . $params['name'] . '%');
}
$res = $model->select();
$res = $query->paginate($params['pageSize'] ?? 10);
$this->success('Success', ['list' => $res->items(), 'count' => $res->total()]);
}
public function view()
{
$model = $this->model->get($this->request->param('id'));
if (empty($model)) {
$this->error(__('No rows were found'));
}
$user = auth_user();
$visitor = Visitor::where('type', 1)->where('obj_id', $model['id'])->where('user_id', $user['id'])->find();
if (empty($visitor)) {
$visitor = new Visitor;
}
$visitor->allowField(true)->save([
'type' => 1,
'obj_id' => $model['id'],
'user_id' => $user['id'],
'nickname' => $user['nickname'],
'avatar' => $user['avatar'],
'gender' => $user['gender'],
'times' => empty($visitor->times) ? 1 : $visitor->times + 1
]);
$this->success('获取成功', $res);
$this->success('Success', $model);
}
}

View File

@@ -0,0 +1,82 @@
<?php
namespace addons\shopro\controller\zy;
use think\Db;
use think\Exception;
use app\admin\model\zy\Tags;
use think\exception\PDOException;
use app\admin\model\zy\link\Visitor;
use app\admin\model\shopro\user\User;
use app\admin\model\zy\circle\Circle;
use app\admin\model\zy\link\Complaint;
use think\exception\ValidateException;
class Sys extends Base
{
public function index()
{
$params = $this->request->param();
$model = new Tags();
if (isset($params['type'])) {
$model->where('type', $params['type']);
}
if (isset($params['group'])) {
$model->where('group', $params['group']);
}
$res = $model->select();
$this->success('Success', $res);
}
// 举报投诉
public function complain()
{
$params = $this->request->param();
if ($params['type'] == 3) { //用户举报
$target = User::get($params['target_id']);
} elseif ($params['type'] == 2) { //影圈举报
$target = Circle::get($params['target_id']);
} elseif ($params['type'] == 1) {
$target = ['id' => 0];
$params['target_id'] = 0;
} else {
$this->error('type 类型错误');
}
if (empty($target)) {
$this->error('举报对象不存在');
}
if (empty($params['content'])) {
$this->error('举报内容不能为空');
}
$user = auth_user();
$res = Complaint::get(['user_id' => $user['id'], 'target_id' => $params['target_id'], 'type' => $params['type'], 'status' => 0]);
if ($res) {
$this->error('您已举报过该对象');
}
$params['status'] = 0;
$params['user_id'] = $user['id'];
$params['username'] = $params['username'] ?? $user['username'];
Db::startTrans();
try {
$result = (new Complaint)->allowField(true)->save($params);
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result === false) {
$this->error('操作失败');
}
$this->success('Success');
}
public function visitor()
{
$params = $this->request->param();
$res = Visitor::where('type', $params['type'])->where('obj_id', $params['obj_id'])->paginate($params['pageSize'] ?? 10);
$this->success('Success', ['list' => $res->items(), 'count' => $res->total()]);
}
}

View File

@@ -1,29 +0,0 @@
<?php
namespace addons\shopro\controller\zy;
use app\admin\model\zy\Tags as TagsModel;
use addons\shopro\controller\Common;
class Tags extends Common
{
// protected $noNeedLogin = ['index'];
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
public function index()
{
$params = $this->request->param();
$model = new TagsModel();
if (isset($params['type'])) {
$model->where('type', $params['type']);
}
if (isset($params['group'])) {
$model->where('group', $params['group']);
}
$res = $model->select();
$this->success('获取成功', $res);
}
}

View File

@@ -2,7 +2,11 @@
namespace addons\shopro\job;
use think\Db;
use think\Exception;
use think\queue\Job;
use think\exception\PDOException;
use think\exception\ValidateException;
class Test extends BaseJob
{
@@ -48,4 +52,88 @@ class Test extends BaseJob
@mkdir($dir, 0755, true);
}
}
/**
* 周期性活动创建比赛
*/
public function zy(Job $job, $data)
{
Db::startTrans();
try {
$_actModel = new \app\admin\model\zy\game\Activity();
$_gameModel = new \app\admin\model\zy\game\Game();
$dateTime = date('Y-m-d H:i:s'); //当前星期
$week = date('w'); //当前星期
$current = time(); //当前时间
$activity = (clone $_actModel)::where('pid', 0)->select(); //周期性主活动
foreach ($activity as $act) {
$act = $act->toArray();
$publicTime = json_decode($act['public_time'] ?? '[]', true);
$publicBefore = intval($publicTime['before'] ?? 0); //提前几天
$PublicWeek = $act['week'] - $publicBefore; //设定应该发布的星期
if ($PublicWeek != $week && ($PublicWeek + 7) != $week) {
print_r('星期不对');
continue; // 星期不对
}
$public_time = strtotime($publicTime['time']); //设定的时间
if ($current < $public_time) {
print_r('时间未到');
continue; //时间未到
}
$act['public_time'] = date('Y-m-d H:i:s', $public_time - $publicBefore * 86400); //设定的时间
$act['date'] = date('Y-m-d', $public_time - $publicBefore * 86400); //设定的日期
$startTime = explode(' ', $act['startTime']);
if (count($startTime) == 2) {
$act['date'] = $startTime[0];
$act['startTime'] = $startTime[1];
}
$endTime = explode(' ', $act['endTime']);
if (count($endTime) == 2) $act['endTime'] = $endTime[1];
$query = (clone $_gameModel)::where('act_id', $act['id']);
if ($act['type'] == 0) { //一次性活动
$query->where('public_time', $act['public_time'])->where('date', $act['date']);
}
$games = $query->select();
if (!empty($games)) {
print_r('已存在');
continue; // 已存在
}
$joinStartTime = json_decode($act['join_start_time'] ?? '[]', true);
$act['join_start_time'] = date('Y-m-d H:i:s', strtotime($joinStartTime['time']) - intval($joinStartTime['before']) * 86400);
$joinEndTime = json_decode($act['join_end_time'] ?? '[]', true);
$act['join_end_time'] = date('Y-m-d H:i:s', strtotime($joinEndTime['time']) - intval($joinEndTime['before']) * 86400);
$quitTime = json_decode($act['quit_time'] ?? '[]', true);
$act['quit_time'] = date('Y-m-d H:i:s', strtotime($quitTime['time']) - intval($quitTime['before']) * 86400);
$act['act_id'] = $act['id'];
unset($act['id']);
$res = (clone $_gameModel)->allowField(true)->save($act);
$subs = (clone $_actModel)::where('pid', $act['act_id'])->select();
foreach ($subs as $sub) { //存在子活动
$sub = $sub->toArray();
$sub['public_time'] = $act['public_time'];
$sub['join_start_time'] = $act['join_start_time'];
$sub['join_end_time'] = $act['join_end_time'];
$sub['quit_time'] = $act['quit_time'];
$sub['act_id'] = $act['act_id'];
$sub['date'] = $act['date'];
unset($sub['id']);
$res = (clone $_gameModel)->allowField(true)->save($sub);
}
}
//处理已生成的比赛
$games = (clone $_gameModel)::where('join_start_time', '>=', $dateTime)->where('status', '<', 2)->select();
foreach ($games as $g) {
if ($g['join_start_time'] <= $dateTime && $g['join_end_time'] > $dateTime) {
$g->save(['status' => 1]); //开始报名
} elseif ($g['join_end_time'] <= $dateTime) {
$g->save(['status' => 2]); //报名截止,活动进行中
}
}
Db::commit();
} catch (ValidateException | PDOException | Exception $e) {
Db::rollback();
format_log_error($e, 'zy.activity create game');
}
$job->release(600); //$delay为延迟时间
}
}

View File

@@ -24,7 +24,7 @@ class Tree
* @param \Closure $resultCb 用来处理每一次查询的结果 比如要取出树中的所有 name
* @return Collection
*/
public function getTree($items = 0, \Closure $resultCb = null)
public function getTree($items = 0, ?\Closure $resultCb = null)
{
if (!is_array($items) && !$items instanceof Collection) {
$items = $this->getQuery()->where('parent_id', $items)->select();
@@ -48,7 +48,7 @@ class Tree
* @param \Closure $resultCb 用来处理每一次查询的结果 比如要取出树中的所有 name
* @return Collection
*/
public function getChildren($id, \Closure $resultCb = null)
public function getChildren($id, ?\Closure $resultCb = null)
{
$self = $this->getQuery()->where('id', $id)->select();
if(!$self) {

View File

@@ -2,30 +2,32 @@
namespace addons\shopro\listener;
use addons\shopro\library\notify\Notify;
use addons\shopro\library\Pipeline;
use addons\shopro\service\order\OrderThrough;
use app\admin\model\shopro\user\User;
use app\admin\model\shopro\Admin;
use addons\shopro\facade\Wechat;
use app\admin\model\shopro\Cart;
use app\admin\model\shopro\user\Coupon;
use app\admin\model\shopro\order\Order as OrderModel;
use app\admin\model\shopro\order\OrderItem;
use app\admin\model\shopro\order\Invoice as OrderInvoiceModel;
use app\admin\model\shopro\order\Express as OrderExpressModel;
use app\admin\model\shopro\order\Action;
use app\admin\model\shopro\order\Invoice;
use app\admin\model\shopro\Admin;
use app\admin\model\shopro\Config;
use addons\shopro\library\Pipeline;
use addons\shopro\service\StockSale;
use addons\shopro\traits\CouponSend;
use addons\shopro\service\order\OrderRefund;
use app\admin\model\shopro\user\User;
use app\admin\model\zy\game\GameJoin;
use addons\shopro\service\pay\PayOper;
use app\admin\model\shopro\user\Coupon;
use addons\shopro\library\notify\Notify;
use app\admin\model\shopro\order\Action;
use app\admin\model\zy\game\Participant;
use app\admin\model\shopro\order\Invoice;
use addons\shopro\service\order\OrderOper;
use addons\shopro\service\user\User as UserService;
use app\admin\model\shopro\order\OrderItem;
use addons\shopro\service\order\OrderRefund;
use addons\shopro\service\order\OrderThrough;
use addons\shopro\service\order\OrderDispatch;
use addons\shopro\library\activity\traits\GiveGift;
use addons\shopro\service\user\User as UserService;
use addons\shopro\facade\Activity as ActivityFacade;
use addons\shopro\facade\Wechat;
use app\admin\model\shopro\order\Order as OrderModel;
use app\admin\model\shopro\order\Express as OrderExpressModel;
use app\admin\model\shopro\order\Invoice as OrderInvoiceModel;
use addons\shopro\library\easywechatPlus\WechatMiniProgramShop;
class Order
@@ -252,6 +254,9 @@ class Order
])
);
}
// zy体育报名处理
GameJoin::where('order_id', $order->id)->update(['status' => 1]);
}
@@ -348,12 +353,21 @@ class Order
}
}
// 添加自动确认收货队列,这个队列只自动确认 本次发货的 items
$confirm_days = Config::getConfigField('shop.order.auto_confirm');
$confirm_days = $confirm_days > 0 ? $confirm_days : 0;
if ($confirm_days) {
// 小于等于0 不自动确认收货
\think\Queue::later(($confirm_days * 86400), '\addons\shopro\job\OrderAutoOper@autoConfirm', $params, 'shopro');
//ZY比赛开始时自动确认收货。
$join = GameJoin::get('order_id', $order->id);
if (!empty($join)) {
$later = strtotime($join->quit_time) - time();
if ($later > 0) {
\think\Queue::later(($later), '\addons\shopro\job\OrderAutoOper@autoConfirm', $params, 'shopro');
}
} else {
// 添加自动确认收货队列,这个队列只自动确认 本次发货的 items
$confirm_days = Config::getConfigField('shop.order.auto_confirm');
$confirm_days = $confirm_days > 0 ? $confirm_days : 0;
if ($confirm_days) {
// 小于等于0 不自动确认收货
\think\Queue::later(($confirm_days * 86400), '\addons\shopro\job\OrderAutoOper@autoConfirm', $params, 'shopro');
}
}
}
@@ -599,6 +613,13 @@ class Order
// 将开票信息取消
$this->cancelInvoice($order, 'invalid');
// zy体育报名处理(未支付,自动退坑)
$join = GameJoin::where('order_id', $order->id)->find();
if (!empty($join)) {
$join->save(['status' => -1]);
Participant::where('game_join_id', $join['id'])->update(['status' => -1]);
}
return $order;
}

View File

@@ -195,7 +195,7 @@ trait StockWarning
$stockWarning = new StockLogModel();
$stockWarning->goods_id = $goodsSkuPrice['goods_id'];
$stockWarning->admin_id = $admin['id'];
$stockWarning->admin_id = $admin['id'] ?? 0;
$stockWarning->goods_sku_price_id = $goodsSkuPrice['id'];
$stockWarning->goods_sku_text = is_array($goodsSkuPrice['goods_sku_text']) ? join(',', $goodsSkuPrice['goods_sku_text']) : $goodsSkuPrice['goods_sku_text'];
$stockWarning->before = $before;

View File

@@ -40,7 +40,13 @@ trait SkuPrice
protected function editSimSku($goods, $type = 'add')
{
$params = $this->request->only([
'stock', 'stock_warning', 'sn', 'weight', 'cost_price', 'original_price', 'price'
'stock',
'stock_warning',
'sn',
'weight',
'cost_price',
'original_price',
'price'
]);
$data = [
@@ -83,7 +89,36 @@ trait SkuPrice
// 检测库存预警
$this->checkStockWarning($skuPrice, $type);
}
}
// 中羿体育项目报名费sku处理
private function zySku($goods, $type)
{
$data = [
'goods_id' => $goods->id,
'stock' => 999,
'cost_price' => 0,
'original_price' => 0,
'price' => $goods['price'][0] ?? 0,
'original_price' => $goods['price'][0] ?? 0,
'stock_warning' => null
];
if ($type == 'edit') {
$skuPrice = SkuPriceModel::where('goods_id', $goods->id)->order('id', 'asc')->find();
if ($skuPrice) {
SkuPriceModel::where('goods_id', $goods->id)->where('id', '<>', $skuPrice->id)->delete();
SkuModel::where('goods_id', $goods->id)->delete();
}
unset($data['stock']);
}
if (!isset($skuPrice) || !$skuPrice) {
$skuPrice = new SkuPriceModel();
}
$skuPrice->save($data);
if ($type == 'add') {
$this->addStockLog($skuPrice, 0, $data['stock'], $type);
$this->checkStockWarning($skuPrice, $type);
}
}
@@ -97,7 +132,8 @@ trait SkuPrice
protected function editMultSku($goods, $type = 'add')
{
$params = $this->request->only([
'skus', 'sku_prices'
'skus',
'sku_prices'
]);
$skus = $params['skus'] ?? [];
$skuPrices = $params['sku_prices'] ?? [];

View File

@@ -0,0 +1,71 @@
<?php
namespace app\admin\controller\zy\link;
use app\common\controller\Backend;
/**
* 消息管理
*
* @icon fa fa-circle-o
*/
class Message extends Backend
{
/**
* Message模型对象
* @var \app\admin\model\zy\link\Message
*/
protected $model = null;
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\zy\link\Message;
}
/**
* 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
* 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
* 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
*/
/**
* 查看
*/
public function index()
{
//当前是否为关联查询
$this->relationSearch = true;
//设置过滤方法
$this->request->filter(['strip_tags', 'trim']);
if ($this->request->isAjax()) {
//如果发送的来源是Selectpage则转发到Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$list = $this->model
->with(['user'])
->where($where)
->order($sort, $order)
->paginate($limit);
foreach ($list as $row) {
$row->getRelation('user')->visible(['nickname']);
}
$result = array("total" => $list->total(), "rows" => $list->items());
return json($result);
}
return $this->view->fetch();
}
}

View File

@@ -0,0 +1,71 @@
<?php
namespace app\admin\controller\zy\link;
use app\common\controller\Backend;
/**
* 标签
*
* @icon fa fa-circle-o
*/
class Visitor extends Backend
{
/**
* Visitor模型对象
* @var \app\admin\model\zy\link\Visitor
*/
protected $model = null;
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\zy\link\Visitor;
}
/**
* 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
* 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
* 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
*/
/**
* 查看
*/
public function index()
{
//当前是否为关联查询
$this->relationSearch = true;
//设置过滤方法
$this->request->filter(['strip_tags', 'trim']);
if ($this->request->isAjax()) {
//如果发送的来源是Selectpage则转发到Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$list = $this->model
->with(['user'])
->where($where)
->order($sort, $order)
->paginate($limit);
foreach ($list as $row) {
$row->getRelation('user')->visible(['nickname']);
}
$result = array("total" => $list->total(), "rows" => $list->items());
return json($result);
}
return $this->view->fetch();
}
}

View File

@@ -3,14 +3,24 @@
return [
'Club_id' => '俱乐部',
'User_id' => '用户',
'Username' => '用户名称',
'Nickname' => '称',
'Avatar' => '头像',
'Gender' => '性别',
'Club_name' => '俱乐部名称',
'Content' => '内容',
'Imgs' => '图片',
'Status' => '状态',
'Create_time' => '创建时间',
'Update_time' => '修改时间',
'Club.name' => '俱乐部名称',
'User.nickname' => '昵称'
'User.nickname' => '昵称',
'Gender1' => '男',
'Gender0' => '女',
'Status-1' => '审核不通过',
'Status0' => '待审核',
'Status1' => '审核通过',
];

View File

@@ -1,14 +1,17 @@
<?php
return [
'Circle_id' => '影圈',
'Pid' => '回复评论',
'Circle_id' => '影圈id',
'Pid' => '评论id',
'User_id' => '用户',
'Username' => '用户名称',
'Nickname' => '称',
'Avatar' => '用户头像',
'Gender' => '性别',
'Content' => '评论或回复内容',
'Status' => '状态',
'Create_time' => '创建时间',
'Update_time' => '修改时间'
'Update_time' => '修改时间',
'Male' => '男',
'Female' => '女',
];

View File

@@ -1,12 +1,15 @@
<?php
return [
'Circle_id' => '影圈',
'Circle_id' => '影圈id',
'User_id' => '用户',
'Username' => '用户名称',
'Nickname' => '称',
'Avatar' => '用户头像',
'Gender' => '性别',
'Create_time' => '创建时间',
'Update_time' => '修改时间',
'User.nickname' => '昵称'
'User.nickname' => '昵称',
'Male' => '男',
'Female' => '女',
];

View File

@@ -5,13 +5,16 @@ return [
'Name' => '俱乐部名称',
'Sub_name' => '简称',
'Logo' => 'logo',
'Contect' => '联系方式',
'City' => '常住地',
'Blurb' => '简介',
'Intro' => '详细介绍',
'Join_type' => '入会方式',
'Img' => '图片',
'President' => '会长',
'Admin_ids' => '管理员',
'Tags' => '标签',
'attention' => '关注数',
'Is_public' => '是否公开',
'Create_time' => '创建时间',
'Update_time' => '修改时间',

View File

@@ -35,49 +35,48 @@ return [
'Club.name' => '俱乐部名称',
'User.username' => '用户名',
"Is_public0" => "",
"Is_public1" => "",
'Is_public0' => '否',
'Is_public1' => '是',
"Is_bring0" => "",
"Is_bring1" => "",
'Is_bring0' => '否',
'Is_bring1' => '是',
"Team_type1" => "双打",
"Team_type2" => "单打",
"Team_type3" => "团队",
'Team_type1' => '双打',
'Team_type2' => '单打',
'Team_type3' => '团队',
"Rule_type1" => "八人转",
"Rule_type2" => "超八转",
"Rule_type3" => "混双转",
"Rule_type4" => "固搭转",
"Rule_type5" => "固定擂",
"Rule_type6" => "活动擂",
"Rule_type7" => "转转",
"Rule_type8" => "分区转",
"Rule_type9" => "擂台赛",
"Rule_type10" => "守擂赛",
"Rule_type11" => "追分赛",
"Rule_type12" => "固搭追分赛",
"Rule_type13" => "大循环群内赛",
"Rule_type14" => "两队PK赛",
"Rule_type15" => "战队淘汰赛",
"Rule_type16" => "单项淘汰赛",
"Rule_type17" => "分区循环淘汰赛",
'Rule_type1' => '八人转',
'Rule_type2' => '超八转',
'Rule_type3' => '混双转',
'Rule_type4' => '固搭转',
'Rule_type5' => '固定擂',
'Rule_type6' => '活动擂',
'Rule_type7' => '转转',
'Rule_type8' => '分区转',
'Rule_type9' => '擂台赛',
'Rule_type10' => '守擂赛',
'Rule_type11' => '追分赛',
'Rule_type12' => '固搭追分赛',
'Rule_type13' => '大循环群内赛',
'Rule_type14' => '两队PK赛',
'Rule_type15' => '战队淘汰赛',
'Rule_type16' => '单项淘汰赛',
'Rule_type17' => '分区循环淘汰赛',
"Type0" => "一次性",
"Type1" => "周期性",
'Type0' => '一次性',
'Type1' => '周期性',
"Status0" => "未开始",
"Status1" => "报名中",
"Status2" => "进行中",
"Status3" => "已结束",
"Week0" => "周日",
"Week1" => "周一",
"Week2" => "周二",
"Week3" => "周三",
"Week4" => "周四",
"Week5" => "周五",
"Week6" => "周六",
'Status0' => '发布',
'Status1' => '报名中',
'Status2' => '比赛中',
'Status3' => '结束',
'Week0' => '周日',
'Week1' => '周一',
'Week2' => '周二',
'Week3' => '周三',
'Week4' => '周四',
'Week5' => '周五',
'Week6' => '周六',
];

View File

@@ -40,50 +40,51 @@ return [
'User.username' => '用户名',
"Is_public0" => "",
"Is_public1" => "",
'Is_public0' => '否',
'Is_public1' => '是',
"Is_bring0" => "",
"Is_bring1" => "",
'Is_bring0' => '否',
'Is_bring1' => '是',
"Team_type1" => "双打",
"Team_type2" => "单打",
"Team_type3" => "团队",
'Team_type1' => '双打',
'Team_type2' => '单打',
'Team_type3' => '团队',
"Rule_type1" => "八人转",
"Rule_type2" => "超八转",
"Rule_type3" => "混双转",
"Rule_type4" => "固搭转",
"Rule_type5" => "固定擂",
"Rule_type6" => "活动擂",
"Rule_type7" => "转转",
"Rule_type8" => "分区转",
"Rule_type9" => "擂台赛",
"Rule_type10" => "守擂赛",
"Rule_type11" => "追分赛",
"Rule_type12" => "固搭追分赛",
"Rule_type13" => "大循环群内赛",
"Rule_type14" => "两队PK赛",
"Rule_type15" => "战队淘汰赛",
"Rule_type16" => "单项淘汰赛",
"Rule_type17" => "分区循环淘汰赛",
'Rule_type1' => '八人转',
'Rule_type2' => '超八转',
'Rule_type3' => '混双转',
'Rule_type4' => '固搭转',
'Rule_type5' => '固定擂',
'Rule_type6' => '活动擂',
'Rule_type7' => '转转',
'Rule_type8' => '分区转',
'Rule_type9' => '擂台赛',
'Rule_type10' => '守擂赛',
'Rule_type11' => '追分赛',
'Rule_type12' => '固搭追分赛',
'Rule_type13' => '大循环群内赛',
'Rule_type14' => '两队PK赛',
'Rule_type15' => '战队淘汰赛',
'Rule_type16' => '单项淘汰赛',
'Rule_type17' => '分区循环淘汰赛',
"Type0" => "一次性",
"Type1" => "周期性",
'Type0' => '一次性',
'Type1' => '周期性',
"Status0" => "未开始",
"Status1" => "报名中",
"Status2" => "进行中",
"Status3" => "已结束",
'Status-1' => '取消',
'Status0' => '未开始',
'Status1' => '报名中',
'Status2' => '进行中',
'Status3' => '已结束',
"Week0" => "周日",
"Week1" => "周一",
"Week2" => "周二",
"Week3" => "周三",
"Week4" => "周四",
"Week5" => "周五",
"Week6" => "周六",
'Week0' => '周日',
'Week1' => '周一',
'Week2' => '周二',
'Week3' => '周三',
'Week4' => '周四',
'Week5' => '周五',
'Week6' => '周六',
];

View File

@@ -14,7 +14,15 @@ return [
'User.username' => '用户名',
'Order.order_sn' => '订单号',
"Status0" => "待支付",
"Status1" => "已支付",
"Status2" => "报名成功",
'Status-1' => '取消',
'Status0' => '待支付',
'Status1' => '已支付',
'Cost10' => '报名时收取',
'Cost21' => '活动后收取:固定',
'Cost22' => '活动后收取AA',
'Cost23' => '活动后收取女固定男AA',
'Cost24' => '活动后收取AA男比女高X元',
'Cost25' => '活动后收取AA男比女高X%',
'Cost30' => '多退少补',
];

View File

@@ -21,10 +21,10 @@ return [
'User.username' => '用户名',
'Game.name' => '赛事名称',
"Status0" => "候补",
"Status1" => "已报名",
"Status2" => "退坑",
'Status-1' => '退坑',
'Status0' => '候补',
'Status1' => '正常',
"Signin0" => "未签到",
"Signin1" => "已签到",
'Signin0' => '未签到',
'Signin1' => '已签到',
];

View File

@@ -0,0 +1,20 @@
<?php
return [
'Type' => '消息类型',
'From_id' => '来源id',
'User_id' => '目标用户',
'Content' => '消息内容',
'Status' => '状态',
'Create_time' => '创建时间',
'Update_time' => '修改时间',
'User.nickname' => '昵称',
'Type0' => '系统消息',
'Type1' => '通知消息',
'Type2' => '用户消息',
'Type3' => '俱乐部消息',
'Status0' => '未读',
'Status1' => '已读'
];

View File

@@ -0,0 +1,21 @@
<?php
return [
'Type' => '访问类型',
'Obj_id' => '访问对象id',
'User_id' => '用户id',
'Nickname' => '昵称',
'Avatar' => '头像',
'Gender' => '性别',
'Times' => '次数',
'Create_time' => '创建时间',
'Update_time' => '修改时间',
'User.nickname' => '昵称',
'Type0' => '俱乐部',
'Type1' => '球馆',
'Type2' => '用户',
'Gender0' => '女',
'Gender1' => '男',
];

View File

@@ -10,6 +10,7 @@ class User extends Model
{
// 表名
public static $tableName = 'user';
protected $name = 'user';
// 自动写入时间戳字段
protected $autoWriteTimestamp = 'int';

View File

@@ -12,6 +12,7 @@ class User extends Common
{
use Notifiable;
public static $tableName = 'user';
protected $name = 'user';
protected $type = [

View File

@@ -13,6 +13,7 @@ class Club extends Model
// 表名
public static $tableName = 'zy_club';
protected $table = 'zy_club';
// 自动写入时间戳字段

View File

@@ -14,6 +14,7 @@ class Menber extends Model
// 表名
protected $table = 'zy_menber';
public static $tableName = 'zy_menber';
// 自动写入时间戳字段
protected $autoWriteTimestamp = false;

View File

@@ -13,6 +13,7 @@ class Stadium extends Model
// 表名
public static $tableName = 'zy_stadium';
protected $table = 'zy_stadium';
// 自动写入时间戳字段

View File

@@ -13,6 +13,7 @@ class Circle extends Model
// 表名
public static $tableName = 'zy_circle';
protected $table = 'zy_circle';
// 自动写入时间戳字段

View File

@@ -13,6 +13,7 @@ class Comment extends Model
// 表名
public static $tableName = 'zy_circle_comment';
protected $table = 'zy_circle_comment';
// 自动写入时间戳字段

View File

@@ -13,6 +13,7 @@ class Likes extends Model
// 表名
public static $tableName = 'zy_circle_likes';
protected $table = 'zy_circle_likes';
// 自动写入时间戳字段

View File

@@ -14,6 +14,7 @@ class Activity extends Model
// 表名
protected $table = 'zy_activity';
public static $tableName = 'zy_activity';
// 自动写入时间戳字段
protected $autoWriteTimestamp = false;
@@ -24,12 +25,11 @@ class Activity extends Model
protected $deleteTime = false;
// 追加属性
protected $append = [
];
protected $append = [];
public $costKey = ['pay_type' => '支付方式', 'male' => '男费用', 'woman' => '女费用', 'extra' => '附加费', 'server' => '服务费'];

View File

@@ -13,6 +13,7 @@ class Game extends Model
// 表名
public static $tableName = 'zy_game';
protected $table = 'zy_game';
// 自动写入时间戳字段

View File

@@ -13,6 +13,7 @@ class GameJoin extends Model
// 表名
public static $tableName = 'zy_game_join';
protected $table = 'zy_game_join';
// 自动写入时间戳字段

View File

@@ -13,6 +13,7 @@ class Participant extends Model
// 表名
public static $tableName = 'zy_participant';
protected $table = 'zy_participant';
// 自动写入时间戳字段

View File

@@ -0,0 +1,45 @@
<?php
namespace app\admin\model\zy\link;
use think\Model;
class Message extends Model
{
// 表名
public static $tableName = 'zy_message';
protected $table = 'zy_message';
// 自动写入时间戳字段
protected $autoWriteTimestamp = false;
// 定义时间戳字段名
protected $createTime = false;
protected $updateTime = false;
protected $deleteTime = false;
// 追加属性
protected $append = [
];
public function user()
{
return $this->belongsTo('app\admin\model\User', 'user_id', 'id', [], 'LEFT')->setEagerlyType(0);
}
}

View File

@@ -13,6 +13,7 @@ class Relation extends Model
// 表名
public static $tableName = 'zy_relation';
protected $table = 'zy_relation';
// 自动写入时间戳字段

View File

@@ -0,0 +1,45 @@
<?php
namespace app\admin\model\zy\link;
use think\Model;
class Visitor extends Model
{
// 表名
public static $tableName = 'zy_visitor';
protected $table = 'zy_visitor';
// 自动写入时间戳字段
protected $autoWriteTimestamp = false;
// 定义时间戳字段名
protected $createTime = false;
protected $updateTime = false;
protected $deleteTime = false;
// 追加属性
protected $append = [
];
public function user()
{
return $this->belongsTo('app\admin\model\User', 'user_id', 'id', [], 'LEFT')->setEagerlyType(0);
}
}

View File

@@ -10,6 +10,7 @@ class Activity extends Validate
* 验证规则
*/
protected $rule = [
'week' => 'number|between:0,6',
];
/**
* 提示消息

View File

@@ -0,0 +1,27 @@
<?php
namespace app\admin\validate\zy\link;
use think\Validate;
class Message extends Validate
{
/**
* 验证规则
*/
protected $rule = [
];
/**
* 提示消息
*/
protected $message = [
];
/**
* 验证场景
*/
protected $scene = [
'add' => [],
'edit' => [],
];
}

View File

@@ -0,0 +1,27 @@
<?php
namespace app\admin\validate\zy\link;
use think\Validate;
class Visitor extends Validate
{
/**
* 验证规则
*/
protected $rule = [
];
/**
* 提示消息
*/
protected $message = [
];
/**
* 验证场景
*/
protected $scene = [
'add' => [],
'edit' => [],
];
}

View File

@@ -12,13 +12,7 @@
<input id="c-user_id" data-rule="required" data-source="user/user/index" data-field="nickname" class="form-control selectpage" name="row[user_id]" type="text" value="">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Username')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-username" data-rule="required" class="form-control" name="row[username]" type="text" value="">
</div>
</div>
<div class="form-group">
<!-- <div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Avatar')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group">
@@ -43,11 +37,11 @@
<div class="col-xs-12 col-sm-8">
<input id="c-club_name" class="form-control" name="row[club_name]" type="text" value="">
</div>
</div>
</div> -->
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Content')}:</label>
<div class="col-xs-12 col-sm-8">
<textarea id="c-content" class="form-control editor" rows="5" name="row[content]" cols="50">NULL</textarea>
<textarea id="c-content" class="form-control" rows="5" name="row[content]" cols="50">NULL</textarea>
</div>
</div>
<div class="form-group">
@@ -64,6 +58,12 @@
<ul class="row list-inline faupload-preview" id="p-imgs"></ul>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
<div class="col-xs-12 col-sm-8">
{:build_radios('row[status]', ['-1'=>__('Status-1'),'0'=>__('Status0'), '1'=>__('Status1')],0)}
</div>
</div>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>

View File

@@ -12,13 +12,7 @@
<input id="c-user_id" data-rule="required" data-source="user/user/index" data-field="nickname" class="form-control selectpage" name="row[user_id]" type="text" value="{$row.user_id|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Username')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-username" data-rule="required" class="form-control" name="row[username]" type="text" value="{$row.username|htmlentities}">
</div>
</div>
<div class="form-group">
<!-- <div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Avatar')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group">
@@ -43,11 +37,11 @@
<div class="col-xs-12 col-sm-8">
<input id="c-club_name" class="form-control" name="row[club_name]" type="text" value="{$row.club_name|htmlentities}">
</div>
</div>
</div> -->
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Content')}:</label>
<div class="col-xs-12 col-sm-8">
<textarea id="c-content" class="form-control editor" rows="5" name="row[content]" cols="50">{$row.content|htmlentities}</textarea>
<textarea id="c-content" class="form-control" rows="5" name="row[content]" cols="50">{$row.content|htmlentities}</textarea>
</div>
</div>
<div class="form-group">
@@ -64,6 +58,12 @@
<ul class="row list-inline faupload-preview" id="p-imgs"></ul>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
<div class="col-xs-12 col-sm-8">
{:build_radios('row[status]', ['-1'=>__('Status-1'),'0'=>__('Status0'), '1'=>__('Status1')],$row.status)}
</div>
</div>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>

View File

@@ -38,6 +38,13 @@
</div>
<ul class="row list-inline faupload-preview" id="p-logo"></ul>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Contect')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-contect" data-rule="required" class="form-control" name="row[contect]" type="text"
value="">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('City')}:</label>
@@ -51,6 +58,13 @@
<div class="col-xs-12 col-sm-8">
<textarea id="c-blurb" class="form-control " rows="5" name="row[blurb]" cols="50"></textarea>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Intro')}:</label>
<div class="col-xs-12 col-sm-8">
<textarea id="c-intro" class="form-control editor" rows="5" name="row[intro]"
cols="50"></textarea>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Join_type')}:</label>

View File

@@ -41,6 +41,13 @@
<ul class="row list-inline faupload-preview" id="p-logo"></ul>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Contect')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-contect" data-rule="required" class="form-control" name="row[contect]" type="text"
value="{$row.contect|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('City')}:</label>
<div class="col-xs-12 col-sm-8">
@@ -55,6 +62,13 @@
cols="50">{$row.blurb|htmlentities}</textarea>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Intro')}:</label>
<div class="col-xs-12 col-sm-8">
<textarea id="c-intro" class="form-control editor" rows="5" name="row[intro]"
cols="50">{$row.intro|htmlentities}</textarea>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Join_type')}:</label>
<div class="col-xs-12 col-sm-8">
@@ -92,9 +106,15 @@
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Admin_ids')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-admin_ids" data-source="user/user/index" data-field="nickname"
data-multiple="true" class="form-control selectpage" name="row[admin_ids]" type="text"
value="{$row.admin_ids|htmlentities}">
<input id="c-admin_ids" data-source="user/user/index" data-field="nickname" data-multiple="true"
class="form-control selectpage" name="row[admin_ids]" type="text" value="{$row.admin_ids|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Attention')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-attention" class="form-control" name="row[attention]" type="number"
value="{$row.attention|htmlentities}">
</div>
</div>
<div class="form-group">

View File

@@ -0,0 +1,61 @@
<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Type')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-type" data-rule="required" class="form-control" name="row[type]" type="number" value="0">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('From_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-from_id" data-rule="required" min="0" data-source="from/index" class="form-control selectpage" name="row[from_id]" type="text" value="">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('User_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-user_id" data-rule="required" min="0" data-source="user/user/index" data-field="nickname" class="form-control selectpage" name="row[user_id]" type="text" value="">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Content')}:</label>
<div class="col-xs-12 col-sm-8">
<dl class="fieldlist" data-name="row[content]">
<dd>
<ins>{:__('Key')}</ins>
<ins>{:__('Value')}</ins>
</dd>
<dd><a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> {:__('Append')}</a></dd>
<textarea name="row[content]" class="form-control hide" cols="30" rows="5">''</textarea>
</dl>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-status" data-rule="required" class="form-control" name="row[status]" type="number" value="0">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Create_time')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-create_time" data-rule="required" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[create_time]" type="text" value="{:date('Y-m-d H:i:s')}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Update_time')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-update_time" data-rule="required" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[update_time]" type="text" value="{:date('Y-m-d H:i:s')}">
</div>
</div>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
</div>
</div>
</form>

View File

@@ -0,0 +1,61 @@
<form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Type')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-type" data-rule="required" class="form-control" name="row[type]" type="number" value="{$row.type|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('From_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-from_id" data-rule="required" min="0" data-source="from/index" class="form-control selectpage" name="row[from_id]" type="text" value="{$row.from_id|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('User_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-user_id" data-rule="required" min="0" data-source="user/user/index" data-field="nickname" class="form-control selectpage" name="row[user_id]" type="text" value="{$row.user_id|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Content')}:</label>
<div class="col-xs-12 col-sm-8">
<dl class="fieldlist" data-name="row[content]">
<dd>
<ins>{:__('Key')}</ins>
<ins>{:__('Value')}</ins>
</dd>
<dd><a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> {:__('Append')}</a></dd>
<textarea name="row[content]" class="form-control hide" cols="30" rows="5">{$row.content|htmlentities}</textarea>
</dl>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-status" data-rule="required" class="form-control" name="row[status]" type="number" value="{$row.status|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Create_time')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-create_time" data-rule="required" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[create_time]" type="text" value="{$row.create_time}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Update_time')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-update_time" data-rule="required" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[update_time]" type="text" value="{$row.update_time}">
</div>
</div>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
</div>
</div>
</form>

View File

@@ -0,0 +1,29 @@
<div class="panel panel-default panel-intro">
{:build_heading()}
<div class="panel-body">
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="one">
<div class="widget-body no-padding">
<div id="toolbar" class="toolbar">
<a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
<a href="javascript:;" class="btn btn-success btn-add {:$auth->check('zy/link/message/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
<a href="javascript:;" class="btn btn-success btn-edit btn-disabled disabled {:$auth->check('zy/link/message/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-pencil"></i> {:__('Edit')}</a>
<a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('zy/link/message/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
</div>
<table id="table" class="table table-striped table-bordered table-hover table-nowrap"
data-operate-edit="{:$auth->check('zy/link/message/edit')}"
data-operate-del="{:$auth->check('zy/link/message/del')}"
width="100%">
</table>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,65 @@
<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Type')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-type" data-rule="required" class="form-control" name="row[type]" type="number" value="0">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('User_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-user_id" data-rule="required" data-source="user/user/index" data-field="nickname" class="form-control selectpage" name="row[user_id]" type="text" value="">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Nickname')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-nickname" data-rule="required" class="form-control" name="row[nickname]" type="text" value="">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Avatar')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group">
<input id="c-avatar" data-rule="required" class="form-control" size="50" name="row[avatar]" type="text" value="">
<div class="input-group-addon no-border no-padding">
<span><button type="button" id="faupload-avatar" class="btn btn-danger faupload" data-input-id="c-avatar" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,image/webp" data-multiple="false" data-preview-id="p-avatar"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
<span><button type="button" id="fachoose-avatar" class="btn btn-primary fachoose" data-input-id="c-avatar" data-mimetype="image/*" data-multiple="false"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
</div>
<span class="msg-box n-right" for="c-avatar"></span>
</div>
<ul class="row list-inline faupload-preview" id="p-avatar"></ul>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Gender')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-gender" data-rule="required" class="form-control" name="row[gender]" type="number" value="0">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Times')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-times" data-rule="required" class="form-control" name="row[times]" type="number" value="0">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Create_time')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-create_time" data-rule="required" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[create_time]" type="text" value="{:date('Y-m-d H:i:s')}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Update_time')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-update_time" data-rule="required" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[update_time]" type="text" value="{:date('Y-m-d H:i:s')}">
</div>
</div>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
</div>
</div>
</form>

View File

@@ -0,0 +1,65 @@
<form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Type')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-type" data-rule="required" class="form-control" name="row[type]" type="number" value="{$row.type|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('User_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-user_id" data-rule="required" data-source="user/user/index" data-field="nickname" class="form-control selectpage" name="row[user_id]" type="text" value="{$row.user_id|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Nickname')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-nickname" data-rule="required" class="form-control" name="row[nickname]" type="text" value="{$row.nickname|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Avatar')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group">
<input id="c-avatar" data-rule="required" class="form-control" size="50" name="row[avatar]" type="text" value="{$row.avatar|htmlentities}">
<div class="input-group-addon no-border no-padding">
<span><button type="button" id="faupload-avatar" class="btn btn-danger faupload" data-input-id="c-avatar" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,image/webp" data-multiple="false" data-preview-id="p-avatar"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
<span><button type="button" id="fachoose-avatar" class="btn btn-primary fachoose" data-input-id="c-avatar" data-mimetype="image/*" data-multiple="false"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
</div>
<span class="msg-box n-right" for="c-avatar"></span>
</div>
<ul class="row list-inline faupload-preview" id="p-avatar"></ul>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Gender')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-gender" data-rule="required" class="form-control" name="row[gender]" type="number" value="{$row.gender|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Times')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-times" data-rule="required" class="form-control" name="row[times]" type="number" value="{$row.times|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Create_time')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-create_time" data-rule="required" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[create_time]" type="text" value="{$row.create_time}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Update_time')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-update_time" data-rule="required" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[update_time]" type="text" value="{$row.update_time}">
</div>
</div>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
</div>
</div>
</form>

View File

@@ -0,0 +1,29 @@
<div class="panel panel-default panel-intro">
{:build_heading()}
<div class="panel-body">
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="one">
<div class="widget-body no-padding">
<div id="toolbar" class="toolbar">
<a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
<!-- <a href="javascript:;" class="btn btn-success btn-add {:$auth->check('zy/link/visitor/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
<a href="javascript:;" class="btn btn-success btn-edit btn-disabled disabled {:$auth->check('zy/link/visitor/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-pencil"></i> {:__('Edit')}</a>
<a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('zy/link/visitor/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
-->
</div>
<table id="table" class="table table-striped table-bordered table-hover table-nowrap"
data-operate-edit="{:$auth->check('zy/link/visitor/edit')}"
data-operate-del="{:$auth->check('zy/link/visitor/del')}"
width="100%">
</table>
</div>
</div>
</div>
</div>
</div>

View File

@@ -185,7 +185,7 @@ return [
// +----------------------------------------------------------------------
'cache' => [
// 驱动方式
'type' => 'File',
'type' => 'redis',
// 缓存保存目录
'path' => CACHE_PATH,
// 缓存前缀

View File

@@ -1,7 +1,7 @@
<?php
return [
'connector' => 'Redis', // Redis 驱动
'expire' => 0, // 任务的过期时间默认为60秒; 若要禁用,则设置为 null
'expire' => 60, // 任务的过期时间默认为60秒; 若要禁用,则设置为 null
'default' => 'default', // 默认的队列名称
'host' => '127.0.0.1', // redis 主机ip
'port' => 6379, // redis 端口

View File

@@ -41,7 +41,8 @@
},
"autoload": {
"psr-4": {
"addons\\": "addons/"
"addons\\": "addons/",
"format\\": "format/"
}
},
"repositories": [

2084
fast.sql

File diff suppressed because it is too large Load Diff

115
format/Game17.php Normal file
View File

@@ -0,0 +1,115 @@
<?php
namespace format;
use app\admin\model\zy\game\Game;
class Game17 implements GameInterface
{
// 赛制说明
public function describe(): string
{
return '双打+八人转 比赛说明:
每个人与其他人各搭档1次决出个人排名
数 4 ≦ n ≦ 16 (Default8)
轮数 3 ≦ mn (Default7)
报名费 0 ≦ m ≦ 10 元 (Default: 5)
由前几名按比例瓜分 (可调 Default40%/30%/20%/10%)';
}
// 首轮对阵安排
public function match(Game $game, array $users): array
{
$math = $team = [];
$utotal = count($users);
//队伍分配
for ($i = 0; $i < $utotal; $i++) {
for ($j = $i + 1; $j < $utotal; $j++) {
$teamName = 'team' . $i . $j;
$team[] = ([
'name' => $teamName,
'user' => [
[
'user_id' => $users[$i]['user_id'],
'gender' => $users[$i]['gender'],
'avatar' => $users[$i]['avatar'],
'name' => $users[$i]['name'],
],
[
'user_id' => $users[$j]['user_id'],
'gender' => $users[$j]['gender'],
'avatar' => $users[$j]['avatar'],
'name' => $users[$j]['name'],
]
]
]);
$users[$i]['team'] = $users[$j]['team'] = $teamName;
}
}
// 对阵分配
$ttotal = count($team);
// df("共 $utotal 人:");
$n = 1;
for ($i = 0; $i < $ttotal; $i++) {
for ($j = $i + 1; $j < $ttotal; $j++) {
if (array_intersect(array_column($team[$i]['user'], 'user_id'), array_column($team[$j]['user'], 'user_id'))) {
continue; //一个人不能同时在两边队伍
}
$math[] = [
'gym_id' => $game['gym_id'],
'club_id' => $game['club_id'],
'act_id' => $game['act_id'],
'game_id' => $game['id'],
'level' => 1, //轮次
'turn' => $n, //场次
'teamA' => json_encode($team[$i]), //队伍A
'teamB' => json_encode($team[$j]), //队伍B
];
// $ta =array_column($team[$i]['user'],'user_id');
// $tb =array_column($team[$j]['user'],'user_id');
// df("第 $n 场:".$ta[0].'/'.$ta[1].' VS '.$tb[0].'/'.$tb[1]);
$n++;
}
}
return $math;
}
// 下一轮对阵安排
public function nextLevel(Game $game, array $maths, $level): array
{
if ($game['rule_type'] < 15) { //15战队淘汰赛16单项淘汰赛17分区循环淘汰赛
return []; //只有淘汰赛才有下一轮对阵安排,其他类型比赛只有一轮
}
$winner = $next = [];
foreach ($maths as $m) {
$winner[] = json_decode($m['winner'], true);
}
$total = count($winner);
$n = 1;
for ($i = 0; $i < $total; $i++) {
for ($j = $i + 1; $j < $total; $j++) {
if (array_intersect(array_column($winner[$i]['user'], 'user_id'), array_column($winner[$j]['user'], 'user_id'))) {
continue;
}
$next[] = [
'gym_id' => $game['gym_id'],
'club_id' => $game['club_id'],
'act_id' => $game['act_id'],
'game_id' => $game['id'],
'level' => $level, //轮次
'turn' => $n, //场次
'teamA' => json_encode($winner[$i]), //队伍A
'teamB' => json_encode($winner[$j]), //队伍B
];
$n++;
}
}
return $next;
}
// 奖金分配
public function prize(array $rank): array
{
return $rank;
}
}

146
format/GameInterface.php Normal file
View File

@@ -0,0 +1,146 @@
<?php
namespace format;
use app\admin\model\zy\game\Game;
/*
赛制文件
1. 团队类型1双打2单打3团队
2. 规则类型1八人转2超八转3混双转4固搭转5固定擂6活动擂7转转8分区转9擂台赛10守擂赛11追分赛12固搭追分赛13大循环群内赛14两队PK赛15战队淘汰赛16单项淘汰赛17分区循环淘汰赛
3. 需要引入新赛制请创建新的类文件,类文件需要实现GameInterface接口,并且文件名为`Game + 团队类型代码 + 规则类型代码.php`。
如:赛制为双打+转转则文件为format/Game17.php。
赛制为单打+擂台赛则文件为format/Game29.php。
*/
interface GameInterface
{
// 赛制说明
public function describe(): string;
/**首轮对阵安排
*
入参:
$game = Array
(
[id] => 1 //比赛id
[pid] => 0 //主比赛id
[act_id] => 1 //活动id
[gym_id] => 1 //球馆id
[club_id] => 4 //俱乐部id
[name] => 聚点第八届年终团体赛 //比赛名称
[team_type] => 1 //团队类型1双打2单打3团队
[rule_type] => 7 //规则类型1八人转2超八转3混双转4固搭转5固定擂6活动擂7转转8分区转9擂台赛10守擂赛11追分赛12固搭追分赛13大循环群内赛14两队PK赛15战队淘汰赛16单项淘汰赛17分区循环淘汰赛
[date] => 2025-05-17 //比赛日期
[week] => 2 //周几
[start_time] => 09:00:00 //开始时间
[end_time] => 12:30:00 //结束时间
[public_time] => 2025-05-02 09:00:00 //公布时间
[join_start_time] => 2025-05-03 09:00:00 //报名开始时间
[join_end_time] => 2025-05-04 09:00:00 //报名结束时间
[quit_time] => 2025-05-04 08:00:00 //免费退坑时间
[game_time] => 3.5 //比赛时长
[address] => 泰新路88号 //地址
[field] => 22 //场地号
[position] => //位置
[cost] => {"type":"1","man":"84","woman":"56","extra":"10","server":"1"} //费用
[limit_num] => 30 //报名人数限制
[join_num] => 0 //已报名人数
[attention] => 0 //关注人数
[status] => 0 //状态,-1取消0未开始1报名中2进行中3已结束
[describe] => 活动介绍 //介绍
[img] => /assets/img/qrcode.png //图片
[game_rule] => 比赛规则 //规则
[is_public] => 1 //是否公开0否1是
[bring_num] => 2 //可带人数
[is_bring] => 1 //是否可带人0否1是
[referee] => 1,2 //裁判用户id
[create_time] => 2025-04-30 10:45:58
[update_time] => 2025-05-26 10:34:14
)
$users = Array(
[
[id] => 1 // 比赛参与id
[user_id] => 1 //用户id
[name] => Yam Lai Yan //昵称
[avatar] => /assets/img/qrcode.png //头像
[gender] => 0 //性别0女1男
[game_join_id] => 1 //报名记录id
[game_id] => 1 //比赛id
[team] => //本次比赛团队
[order] => 1 //本次比赛顺序
[rank] => 0 //本次比赛排名
[mark] => //备注
[status] => 1 //状态0候补1正常2退坑
[signin] => 0 //签到状态0未签到1已签到
[score] => 0 //得分
[net_score] => 0 //净得分
[win] => 0 //胜局
[create_time] => 2025-04 - 24 05: 35:00
[update_time] => 2025-05 - 26 15:08: 55
],
)
出参:
return $math = Array(
[
[gym_id] => 1 //球馆id
[club_id] => 4 //俱乐部id
[act_id] => 1 //活动id
[game_id] => 1 //比赛id
[level] => 1 //轮次
[turn] => 1 //场次
[teamA] => {"name":"team01","user":[{"user_id":1,"gender":0,"avatar":"\/assets\/img\/qrcode.png","name":"Yam Lai Yan"},{"user_id":2,"gender":1,"avatar":"\/assets\/img\/qrcode.png","name":"Yuen Wai San"}]} //队伍A
[teamB] => {"name":"team23","user":[{"user_id":3,"gender":0,"avatar":"xjgH6E5VkQ","name":"Mo Ming Sze"},{"user_id":4,"gender":1,"avatar":"hSuH5AZVxt","name":"Chan Ka Keung"}]} //队伍B
],
)
*/
public function match(Game $game, array $users): array;
/**下一轮对阵安排
*
入参:
$maths = Array(
[
[id] => 1
[gym_id] => 1
[club_id] => 4
[act_id] => 1
[game_id] => 1
[level] => 1
[turn] => 1
[teamA] => {"name":"team01","user":[{"user_id":1,"gender":0,"avatar":"\/assets\/img\/qrcode.png","name":"admin1"},{"user_id":2,"gender":1,"avatar":"\/assets\/img\/qrcode.png","name":"admin2"}]}
[teamB] => {"name":"team23","user":[{"user_id":3,"gender":0,"avatar":"\/assets\/img\/qrcode.png","name":"admin3"},{"user_id":4,"gender":1,"avatar":"\/assets\/img\/qrcode.png","name":"admin4"}]}
[round1] => {"addedA":"3","addedB":"0","scoreA":"15","scoreB":"24"}
[round2] => {"addedA":"3","addedB":"0","scoreA":"15","scoreB":"24"}
[round3] => {"addedA":"3","addedB":"0","scoreA":"15","scoreB":"24"}
[scoreA] => 0
[scoreB] => 3
[winner] => {"name":"team23","user":[{"user_id":3,"gender":0,"avatar":"\/assets\/img\/qrcode.png","name":"admin3"},{"user_id":4,"gender":1,"avatar":"\/assets\/img\/qrcode.png","name":"admin4"}]}
[create_time] => 2025-05-30 15:24:28
[update_time] => 2025-05-30 15:54:34
],
)
$level 设定为第几轮数
出参:
return $math = Array(
[
[gym_id] => 1 //球馆id
[club_id] => 4 //俱乐部id
[act_id] => 1 //活动id
[game_id] => 1 //比赛id
[level] => 1 //轮次
[turn] => 1 //场次
[teamA] => {"name":"team01","user":[{"user_id":1,"gender":0,"avatar":"\/assets\/img\/qrcode.png","name":"Yam Lai Yan"},{"user_id":2,"gender":1,"avatar":"\/assets\/img\/qrcode.png","name":"Yuen Wai San"}]} //队伍A
[teamB] => {"name":"team23","user":[{"user_id":3,"gender":0,"avatar":"xjgH6E5VkQ","name":"Mo Ming Sze"},{"user_id":4,"gender":1,"avatar":"hSuH5AZVxt","name":"Chan Ka Keung"}]} //队伍B
],
)
如return $math 为空则比赛结束
*/
public function nextLevel(Game $game, array $maths, int $level): array;
// 奖金分配
public function prize(array $rank): array;
}

View File

@@ -26,18 +26,20 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
fixedRightNumber: 1,
columns: [
[
{checkbox: true},
{field: 'id', title: __('Id')},
{field: 'club.name', title: __('Club.name'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content},
{field: 'user.nickname', title: __('User.nickname'), operate: 'LIKE'},
{field: 'username', title: __('Username'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content},
{field: 'avatar', title: __('Avatar'), operate: 'LIKE', events: Table.api.events.image, formatter: Table.api.formatter.image},
{field: 'gender', title: __('Gender'), searchList: {1: __('Male'), 0: __('Female')}},
{field: 'club_name', title: __('Club_name'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content},
{field: 'create_time', title: __('Create_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false},
{field: 'update_time', title: __('Update_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false},
{ checkbox: true },
{ field: 'id', title: __('Id') },
// {field: 'club.name', title: __('Club.name'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content},
{field: 'content', title: __('Content')},
{ field: 'club_name', title: __('Club_name'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content },
{ field: 'nickname', title: __('Nickname'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content },
{ field: 'avatar', title: __('Avatar'), operate: 'LIKE', events: Table.api.events.image, formatter: Table.api.formatter.image },
{ field: 'gender', title: __('Gender'), formatter: Table.api.formatter.label, searchList: { 1: __('Male'), 0: __('Female') } },
{ field: 'club_name', title: __('Club_name'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content },
{ field: 'status', title: __('Status'), formatter: Table.api.formatter.label, searchList: { '-1': __('Status-1'), 0: __('Status0'), 1: __('Status1') } },
{ field: 'create_time', title: __('Create_time'), operate: 'RANGE', addclass: 'datetimerange', autocomplete: false },
{ field: 'update_time', title: __('Update_time'), operate: 'RANGE', addclass: 'datetimerange', autocomplete: false },
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
{ field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate }
]
]
});

View File

@@ -30,10 +30,10 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
{field: 'id', title: __('Id')},
{field: 'circle_id', title: __('Circle_id')},
{field: 'pid', title: __('Pid')},
{field: 'user_id', title: __('User_id')},
{field: 'username', title: __('Username'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content},
// {field: 'user_id', title: __('User_id')},
{field: 'nickname', title: __('Nickname'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content},
{field: 'avatar', title: __('Avatar'), operate: 'LIKE', events: Table.api.events.image, formatter: Table.api.formatter.image},
{field: 'gender', title: __('Gender')},
{field: 'gender', title: __('Gender'),formatter: Table.api.formatter.label, searchList: {1: __('Male'), 0: __('Female')}},
{field: 'status', title: __('Status')},
{field: 'create_time', title: __('Create_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false},
{field: 'update_time', title: __('Update_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false},

View File

@@ -27,9 +27,9 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
{checkbox: true},
{field: 'id', title: __('Id')},
{field: 'circle_id', title: __('Circle_id')},
{field: 'username', title: __('Username'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content},
{field: 'nickname', title: __('Nickname'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content},
{field: 'avatar', title: __('Avatar'), operate: 'LIKE', events: Table.api.events.image, formatter: Table.api.formatter.image},
{field: 'gender', title: __('Gender')},
{field: 'gender', title: __('Gender'),formatter: Table.api.formatter.label, searchList: {1: __('Male'), 0: __('Female')}},
{field: 'create_time', title: __('Create_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false},
{field: 'update_time', title: __('Update_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false},
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}

View File

@@ -28,14 +28,14 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
[
{checkbox: true},
{field: 'id', title: __('Id')},
{field: 'type', title: __('Type')},
{field: 'target_id', title: __('Target_id')},
{field: 'type', title: __('Type'),formatter: Table.api.formatter.label, searchList: { 1: __('Type1'),2: __('Type2'),3: __('Type3')}},
// {field: 'target_id', title: __('Target_id')},
{field: 'name', title: __('Name'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content},
// {field: 'user.nickname', title: __('User.nickname'), operate: 'LIKE'},
{field: 'user_id', title: __('User_id')},
// {field: 'user_id', title: __('User_id')},
{field: 'username', title: __('Username'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content},
{field: 'phone', title: __('Phone')},
{field: 'status', title: __('Status')},
{field: 'status', title: __('Status'),formatter: Table.api.formatter.label, searchList: { 1: __('Status1'),0: __('Status0')}},
{field: 'create_time', title: __('Create_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false},
{field: 'update_time', title: __('Update_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false},
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}

View File

@@ -0,0 +1,57 @@
define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
var Controller = {
index: function () {
// 初始化表格参数配置
Table.api.init({
extend: {
index_url: 'zy/link/message/index' + location.search,
add_url: 'zy/link/message/add',
edit_url: 'zy/link/message/edit',
del_url: 'zy/link/message/del',
multi_url: 'zy/link/message/multi',
import_url: 'zy/link/message/import',
table: 'zy_message',
}
});
var table = $("#table");
// 初始化表格
table.bootstrapTable({
url: $.fn.bootstrapTable.defaults.extend.index_url,
pk: 'id',
sortName: 'id',
columns: [
[
{checkbox: true},
{field: 'id', title: __('Id')},
{field: 'type', title: __('Type')},
{field: 'from_id', title: __('From_id')},
{field: 'user_id', title: __('User_id')},
{field: 'status', title: __('Status')},
{field: 'create_time', title: __('Create_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false},
{field: 'update_time', title: __('Update_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false},
{field: 'user.nickname', title: __('User.nickname'), operate: 'LIKE'},
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
]
]
});
// 为表格绑定事件
Table.api.bindevent(table);
},
add: function () {
Controller.api.bindevent();
},
edit: function () {
Controller.api.bindevent();
},
api: {
bindevent: function () {
Form.api.bindevent($("form[role=form]"));
}
}
};
return Controller;
});

View File

@@ -0,0 +1,59 @@
define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
var Controller = {
index: function () {
// 初始化表格参数配置
Table.api.init({
extend: {
index_url: 'zy/link/visitor/index' + location.search,
add_url: 'zy/link/visitor/add',
edit_url: 'zy/link/visitor/edit',
del_url: 'zy/link/visitor/del',
multi_url: 'zy/link/visitor/multi',
import_url: 'zy/link/visitor/import',
table: 'zy_visitor',
}
});
var table = $("#table");
// 初始化表格
table.bootstrapTable({
url: $.fn.bootstrapTable.defaults.extend.index_url,
pk: 'id',
sortName: 'id',
columns: [
[
{checkbox: true},
{field: 'id', title: __('Id')},
{field: 'type', title: __('Type')},
{field: 'user_id', title: __('User_id')},
{field: 'nickname', title: __('Nickname'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content},
{field: 'avatar', title: __('Avatar'), operate: 'LIKE', events: Table.api.events.image, formatter: Table.api.formatter.image},
{field: 'gender', title: __('Gender')},
{field: 'times', title: __('Times')},
{field: 'create_time', title: __('Create_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false},
{field: 'update_time', title: __('Update_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false},
// {field: 'user.nickname', title: __('User.nickname'), operate: 'LIKE'},
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
]
]
});
// 为表格绑定事件
Table.api.bindevent(table);
},
add: function () {
Controller.api.bindevent();
},
edit: function () {
Controller.api.bindevent();
},
api: {
bindevent: function () {
Form.api.bindevent($("form[role=form]"));
}
}
};
return Controller;
});

View File

@@ -587,3 +587,75 @@ if (!function_exists('collection')) {
}
}
}
if (!function_exists('dd')) {
/**
* 调试打印
*/
function dd(...$params)
{
foreach ($params as $p) {
print_r($p);
echo PHP_EOL;
}
// echo '</pre>';
die;
}
}
if (!function_exists('df')) {
/**
* 调试打印
*/
function df(...$params)
{
foreach ($params as $p) {
print_r($p);
echo PHP_EOL;
}
}
}
if (!function_exists('getsql')) {
/**
* 调试打印
*/
function getsql($query)
{
echo '
';
print_r($query->fetchSql()->select());
// echo '</pre>';
die;
}
}
if (!function_exists('buildTree')) {
/**
* 生成树结构
*/
function buildTree($items): array
{
$refer = [];
foreach ($items as $k => $v) {
if (!isset($v['id']) || !isset($v['pid'])) {
return []; // 缺少id和pid
}
$items[$k]['child'] = [];
$refer[$v['id']] = &$items[$k]; //为每个项目建立引用关系
}
foreach ($items as $k => $v) {
if (empty($v['pid'])) continue;
$parent = &$refer[$v['pid']]; //获取父项目的引用
$parent['child'][] = &$items[$k]; //在父项目的child中再添加一个引用成员
}
// 排除非顶级项目
$group_ids = array_column($items, 'id');
foreach ($items as $k => $v) {
if (in_array($v['pid'], $group_ids)) {
unset($items[$k]);
}
}
return array_values($items);
}
}

View File

@@ -19,6 +19,8 @@ return [
'Type error' => '类型错误',
'Fatal error' => '致命错误',
'syntax error' => '语法错误',
'param error' => '参数错误',
'param lose: {:param}' => '参数缺失: {:param}',
// 框架核心错误提示
'dispatch type not support' => '不支持的调度类型',

View File

@@ -210,7 +210,7 @@ class Windows extends Pipes
}
if (null !== $w && 0 < count($w)) {
while (strlen($this->inputBuffer)) {
while (strlen((string)$this->inputBuffer)) {
$written = fwrite($w[0], $this->inputBuffer, 2 << 18);
if ($written > 0) {
$this->inputBuffer = (string) substr($this->inputBuffer, $written);

5
vendor/autoload.php vendored
View File

@@ -14,7 +14,10 @@ if (PHP_VERSION_ID < 50600) {
echo $err;
}
}
throw new RuntimeException($err);
trigger_error(
$err,
E_USER_ERROR
);
}
require_once __DIR__ . '/composer/autoload_real.php';

View File

@@ -1,4 +1,3 @@
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -18,4 +17,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,8 @@ return array(
'think\\helper\\' => array($vendorDir . '/topthink/think-helper/src'),
'think\\composer\\' => array($vendorDir . '/topthink/think-installer/src'),
'think\\captcha\\' => array($vendorDir . '/topthink/think-captcha/src'),
'think\\' => array($vendorDir . '/topthink/think-queue/src', $vendorDir . '/fastadminnet/fastadmin-addons/src', $baseDir . '/thinkphp/library/think'),
'think\\' => array($vendorDir . '/fastadminnet/fastadmin-addons/src', $baseDir . '/thinkphp/library/think', $vendorDir . '/topthink/think-queue/src'),
'format\\' => array($baseDir . '/format'),
'addons\\' => array($baseDir . '/addons'),
'ZipStream\\' => array($vendorDir . '/maennchen/zipstream-php/src'),
'Workerman\\' => array($vendorDir . '/workerman/workerman'),

File diff suppressed because it is too large Load Diff

View File

@@ -63,7 +63,7 @@ class Controller extends \think\Controller
* @param Request $request Request对象
* @access public
*/
public function __construct(Request $request = null)
public function __construct(?Request $request = null)
{
if (is_null($request)) {
$request = Request::instance();

View File

@@ -34,7 +34,7 @@ class Listen extends Command
->setDescription('Listen to a given queue');
}
public function initialize(Input $input, Output $output)
public function initialize(?Input $input, ?Output $output)
{
$this->listener = new Listener($this->findCommandPath());
$this->listener->setSleep($input->getOption('sleep'));
@@ -45,7 +45,7 @@ class Listen extends Command
});
}
public function execute(Input $input, Output $output)
public function execute(?Input $input, ?Output $output)
{
$delay = $input->getOption('delay');

View File

@@ -23,7 +23,7 @@ class Restart extends Command
$this->setName('queue:restart')->setDescription('Restart queue worker daemons after their current job');
}
public function execute(Input $input, Output $output)
public function execute(?Input $input, ?Output $output)
{
Cache::set('think:queue:restart', time());
$output->writeln("<info>Broadcasting queue restart signal.</info>");

View File

@@ -31,7 +31,7 @@ class Subscribe extends Command
->addOption('option', null, Option::VALUE_IS_ARRAY | Option::VALUE_OPTIONAL, 'the options');
}
public function execute(Input $input, Output $output)
public function execute(?Input $input, ?Output $output)
{
$url = $input->getArgument('url');

View File

@@ -33,7 +33,7 @@ class Work extends Command
*/
protected $worker;
protected function initialize(Input $input, Output $output)
protected function initialize(?Input $input, ?Output $output)
{
$this->worker = new Worker();
}
@@ -57,7 +57,7 @@ class Work extends Command
* @param Output $output
* @return int|null|void
*/
public function execute(Input $input, Output $output)
public function execute(?Input $input, ?Output $output)
{
$queue = $input->getOption('queue');