Compare commits

39 Commits

Author SHA1 Message Date
commie d0e34f36bd 22 2026-04-23 07:33:28 +08:00
commie 24273db8dd 11 2026-04-13 20:00:32 +08:00
commie 9393185f25 批量注册用户优化 2026-04-12 09:50:05 +08:00
commie a98d2b56ee fix redis clear 2026-04-12 09:48:57 +08:00
commie 4463f73efb backup: 修复备份命令的用户名密码问题
backup
2026-04-12 09:46:20 +08:00
commie d75808951e 1 2026-04-12 08:26:08 +08:00
commie f0970446f9 修复 2026-04-10 18:04:33 +08:00
commie c092662ebe payment1 2026-04-10 13:31:15 +08:00
commie 6c59e41b32 Merge branch 'main' of http://156.238.245.175:10086/commie/im 2026-04-08 10:10:23 +08:00
commie b0e87b3fb3 翻译 2026-04-08 10:05:25 +08:00
commie d0dc7930ad 添加用户批量注册命令 2026-04-07 02:30:37 +08:00
commie 594aa137ef 修复相册groupID写成了group_id 2026-04-07 01:40:52 +08:00
commie 005c775694 22 2026-04-06 04:35:35 +08:00
commie 26fb271a54 优化朋友圈 2026-04-06 03:36:41 +08:00
commie dd6745fe24 22 2026-04-06 03:10:44 +08:00
commie 7b5d43f0e8 删除 .user.ini 2026-04-06 02:02:14 +08:00
commie ffc1404baa 21 2026-04-06 01:59:22 +08:00
commie d98ac8f146 20 2026-04-04 08:52:59 +08:00
commie 66bcd8061a 19 2026-03-25 02:48:30 +08:00
commie 8704434c36 translation 2026-03-06 02:31:40 +08:00
commie 70c4966aad 18 2026-03-06 02:27:52 +08:00
commie f598cc8157 17 2026-03-02 15:59:46 +08:00
commie 92948fa856 16 2026-03-01 21:05:19 +08:00
commie 0a45a8fbb9 15 2026-03-01 00:24:34 +08:00
commie 873c7cf9c2 14 2026-02-28 19:24:05 +08:00
commie 73f67b4143 13 2026-02-28 16:18:52 +08:00
commie d75fea32f7 12 2026-02-27 13:53:53 +08:00
commie c9c8a120ab 11 2026-02-24 21:02:17 +08:00
commie 6586f27c9e 10 2026-02-21 08:21:05 +08:00
commie 1a7f4bc98a 9 2026-02-15 19:41:56 +08:00
commie 61c5192018 8 2026-01-12 12:42:08 +08:00
commie c153975eed 7 2026-01-08 05:42:44 +08:00
commie 7439a4a794 6 2025-12-25 23:30:14 +08:00
commie 7c1d6d447e 5 2025-12-25 06:02:38 +08:00
commie 20d230f6c8 database 2025-12-24 17:03:10 +08:00
commie b68946fe79 4 2025-12-24 16:59:05 +08:00
commie b52a51c09b 3 2025-11-22 15:31:01 +08:00
commie 9f25a85d07 2 2025-11-21 01:45:26 +08:00
commie f89196c73c 1 2025-11-21 01:42:54 +08:00
2972 changed files with 41302 additions and 96707 deletions
+8 -8
View File
@@ -2,14 +2,14 @@
debug = true debug = true
[server] [server]
port=8585 port=8585
domain=www.wenjb.com domain=www.shun777.com
https=false https=false
[mysql] [mysql]
host =127.0.0.1 host =127.0.0.1
port = 3307 port = 3306
database = questionnaire database = imadmin
username = questionnaire username = imadmin
password = ba9b492bda93ad4d password = ejkFmaAXAHXyNXd2
charset = utf8mb4 charset = utf8mb4
collation = utf8mb4_general_ci collation = utf8mb4_general_ci
prefix = wa_ prefix = wa_
@@ -18,13 +18,13 @@ engine =
[mongodb] [mongodb]
host = 127.0.0.1 host = 127.0.0.1
port = 27017 port = 27017
database = questionnaire_m database = imadmin_mongo
username = commie username = root
password = n1e5a6s6m7 password = n1e5a6s6m7
[redis] [redis]
host = 127.0.0.1 host = 127.0.0.1
port = 6379 port = 6379
database = 10 database = 0
password = n1e5a6s6m7 password = n1e5a6s6m7
prefix = q_ prefix = q_
+2
View File
@@ -0,0 +1,2 @@
* text=auto eol=lf
*.txt -text
Executable
+12
View File
@@ -0,0 +1,12 @@
node_modules
*.lock
unpackage
package-lock.json
.hbuilderx
config/site.php
app/command/Test.php
.env
runtime
vendor
public/shunliao.apk
.user.ini
+1
View File
@@ -0,0 +1 @@
+232
View File
@@ -0,0 +1,232 @@
---
name: "webman-openim-admin"
description: "专门针对基于webman的openim管理项目,使用了think-cache、think-orm、think-template、redis-queue、webman/event、tinywan/validate等依赖。用于项目的开发、维护和问题排查。"
---
# Webman OpenIM Admin 技能
## 项目概述
本技能专门针对基于 webman 框架开发的 OpenIM 管理项目,该项目使用了以下核心依赖:
- **think-cache**: 缓存管理
- **think-orm**: 数据库 ORM 框架
- **think-template**: 模板引擎
- **redis-queue**: Redis 队列管理
- **webman/event**: 事件系统
- **tinywan/validate**: 数据验证
## 功能特性
### 1. 项目结构分析
- 分析项目目录结构
- 识别核心模块和文件
- 理解依赖关系
### 2. 代码开发与维护
- 基于现有代码风格和模式进行开发
- 提供符合项目规范的代码建议
- 帮助排查和修复常见问题
### 3. 依赖管理
- 分析 composer.json 配置
- 提供依赖版本建议
- 处理依赖冲突问题
### 4. 数据库操作
- 基于 think-orm 的数据库操作指导
- 模型定义和关系映射
- 数据库迁移和种子数据管理
### 5. 缓存策略
- 基于 think-cache 的缓存配置和使用
- 缓存优化建议
- 缓存一致性管理
### 6. 队列管理
- redis-queue 的配置和使用
- 队列任务的创建和监控
- 队列性能优化
### 7. 事件系统
- webman/event 的配置和使用
- 事件监听和触发
- 事件驱动架构设计
### 8. 数据验证
- tinywan/validate 的配置和使用
- 表单验证规则定义
- 自定义验证规则开发
## 触发条件
当用户需要:
- 了解项目结构和依赖
- 开发新功能或修改现有功能
- 排查项目中的问题
- 优化项目性能
- 配置或调整项目依赖
- 进行数据库相关操作
- 实现缓存策略
- 管理队列任务
- 使用事件系统
- 进行数据验证
## 使用示例
### 示例 1: 分析项目结构
```bash
# 查看项目目录结构
ls -la
# 查看 composer.json 了解依赖
cat composer.json
```
### 示例 2: 数据库操作
```php
// 使用 think-orm 进行数据库查询
use think\Model;
class User extends Model
{
protected $table = 'user';
}
// 查询用户列表
$users = User::where('status', 1)->select();
```
### 示例 3: 缓存使用
```php
// 使用 think-cache
use think\facade\Cache;
// 设置缓存
Cache::set('key', 'value', 3600);
// 获取缓存
$value = Cache::get('key');
```
### 示例 4: 队列任务
```php
// 使用 redis-queue
use support\Queue;
// 推送任务
Queue::push('App\\Jobs\\SendEmail', ['email' => 'user@example.com']);
```
### 示例 5: 事件监听
```php
// 使用 webman/event
use support\Event;
// 监听事件
Event::listen('user.registered', function ($user) {
// 处理用户注册事件
});
// 触发事件
Event::trigger('user.registered', $user);
```
### 示例 6: 数据验证
```php
// 使用 tinywan/validate
use Tinywan\Validate\Validate;
$validate = new Validate();
$validate->rule([
'name' => 'require|max:25',
'email' => 'require|email',
]);
if (!$validate->check($data)) {
return $validate->getError();
}
```
## 项目配置建议
1. **composer.json** 配置:
- 保持依赖版本的稳定性
- 定期更新依赖以获取安全补丁
2. **数据库配置**
- 优化数据库连接池设置
- 合理使用索引
- 定期备份数据库
3. **缓存配置**
- 根据业务场景选择合适的缓存策略
- 设置合理的缓存过期时间
- 考虑缓存预热机制
4. **队列配置**
- 合理设置队列 worker 数量
- 监控队列任务执行状态
- 实现失败重试机制
5. **性能优化**
- 启用 OPcache
- 优化数据库查询
- 使用合适的缓存策略
- 合理设计事件系统
## 常见问题与解决方案
1. **依赖冲突**
- 检查 composer.json 中的版本约束
- 使用 `composer update` 解决版本冲突
2. **数据库连接问题**
- 检查数据库配置文件
- 确认数据库服务是否正常运行
3. **缓存失效**
- 检查缓存配置
- 确认缓存服务是否正常
4. **队列任务失败**
- 检查队列配置
- 查看任务执行日志
- 实现失败重试机制
5. **事件不触发**
- 检查事件监听注册
- 确认事件触发代码
6. **验证失败**
- 检查验证规则
- 确认输入数据格式
## 最佳实践
1. **代码组织**
- 遵循 PSR 代码规范
- 合理使用命名空间
- 保持代码结构清晰
2. **安全性**
- 防止 SQL 注入
- 防止 XSS 攻击
- 保护敏感信息
3. **可维护性**
- 编写清晰的注释
- 使用一致的代码风格
- 遵循设计模式
4. **性能**
- 优化数据库查询
- 合理使用缓存
- 减少不必要的计算
5. **扩展性**
- 采用模块化设计
- 依赖注入
- 接口分离
本技能旨在帮助开发者更高效地开发和维护基于 webman 的 OpenIM 管理项目,提供专业的技术支持和最佳实践建议。
Vendored Executable
+3
View File
@@ -0,0 +1,3 @@
{
"php.version": "8.2"
}
-10
View File
@@ -1,10 +0,0 @@
/runtime
/.idea
/.vscode
/vendor
*.log
.env
.user.ini
/config/site.php
/config/pay.php
/app/command/Test.php
@@ -1,144 +0,0 @@
<?php
namespace app\api\controller;
use app\model\Archives as ArchivesModel;
use support\Request;
use taoser\facade\Validate;
use hg\apidoc\annotation as Apidoc;
/**
* 文章模块
*/
class ArticleController extends BaseController{
public $noNeedLogin = ['*'];
/**
* 列表
* @Apidoc\Query("category_id", type="int", require=true, desc="分类ID",default=10)
* @Apidoc\Query("page", type="int", require=true, desc="页码",default=1)
* @Apidoc\Query("limit", type="int", require=true, desc="分页大小",default=10)
*/
public function list(){
$limit = (int)input('limit',10);
$category_id = (int)input('category_id',0);
$model = ArchivesModel::where('status','1')->where('type','article');
if($category_id){
$model = $model->where('category_id',$category_id);
}
$list = $model->order('id','desc')->paginate($limit);
$user_id=0;
try {
$user_id = \support\Jwt\JwtToken::getCurrentId();
} catch (\Throwable $th) {
}
$list->each(function($item)use($user_id){
if(!$user_id){
$item->is_read = 0;
}
$item->is_read = cache('article_read_'.$item->id.'_'.$user_id)?:0;
return $item;
});
return $this->success(__('successful'),$list->toArray());
}
/**
* faq
* @Apidoc\Query("page", type="int", require=true, desc="页码",default=1)
* @Apidoc\Query("limit", type="int", require=true, desc="分页大小",default=10)
*/
public function faq(){
$limit = (int)input('limit',10);
$model = ArchivesModel::alias('a')
->join('content c', 'a.id = c.id')
->where('a.status','1')
->where('a.type','article')
->where('a.category_id',9);
$list = $model->Field('a.title,a.id,c.content')->order('a.id','desc')->paginate($limit);
return $this->success(__('successful'),$list->toArray());
}
/**
* 详情
* @Apidoc\Query("id", type="int", require=true, desc="ID")
*/
public function detail(){
$appid = input('id');
/** @var ArchivesModel $vo */
$vo = ArchivesModel::where('id',$appid)->find();
if($vo) {
$addon = \app\model\Content::where('id', $vo->id)->find()->toArray();
if ($addon) {
$vo->setAddonData($addon);
}
$user_id=0;
try {
$user_id = \support\Jwt\JwtToken::getCurrentId();
} catch (\Throwable $th) {
}
if($user_id){
cache('article_read_'.$vo->id.'_'.$user_id,1);
}
return $this->success(__('successful'),$vo->toArray());
}else{
return $this->error(__("Article does not exist"));
}
}
/**
* 单页详情
* @Apidoc\Query("id", type="int", require=true, desc="ID")
* @Apidoc\Query("name", type="string", require=true, desc="二选1")
*/
public function singpage(){
$appid = input('id');
$name = input('name');
/** @var ArchivesModel $vo */
if($name){
$vo = ArchivesModel::where('name',$name)->find();
}else{
if($appid){
$vo = ArchivesModel::where('id',$appid)->find();
}
}
if($vo) {
$addon = \app\model\Content::where('id', $vo->id)->find()->toArray();
if ($addon) {
$vo->setAddonData($addon);
}
return $this->success(__('successful'),$vo->toArray());
}else{
return $this->error(__("Article does not exist"));
}
}
/**
* 幻灯片
* @Apidoc\Query("id", type="int", require=true, desc="ID")
*/
public function slide(){
$list = [
['image'=>domain().'/storage/slide/1.jpg','title'=>''],
['image'=>domain().'/storage/slide/2.webp','title'=>''],
['image'=>domain().'/storage/slide/3.webp','title'=>''],
['image'=>domain().'/storage/slide/4.jpg','title'=>''],
];
return $this->success(__('successful'),$list);
}
/**
* 设为已读
* @Apidoc\Query("id", type="int", require=true, desc="ID,多个逗号隔开")
*/
function mask_as_read(){
$ids = input('id');
$user_id = \support\Jwt\JwtToken::getCurrentId();
if(!$user_id){
return $this->success(__('successful'));
}
$ids = explode(',',$ids);
foreach ($ids as $id) {
$key = 'article_read_'.$id.'_'.$user_id;
cache($key,1);
}
return $this->success(__('successful'));
}
}
@@ -1,80 +0,0 @@
<?php
namespace app\api\controller;
use support\Request;
use support\Response;
use Shopwwi\WebmanFilesystem\FilesystemFactory;
use Shopwwi\WebmanFilesystem\Facade\Storage;
use hg\apidoc\annotation as Apidoc;
/**
* 基础控制器
* @Apidoc\NotParse()
* @Apidoc\NotDebug()
*/
class BaseController
{
/**
* 不需要鉴权的方法
* @var array
*/
public $noNeedAuth = [];
/**
* 无需登录及鉴权的方法
* @var array
*/
public $noNeedLogin = [];
function __construct()
{
$this->_init();
}
protected function _init(){
}
/**
* 返回格式化json数据
*
* @param int $code
* @param string $msg
* @param array $data
* @return Response
*/
protected function json(int $code, string $msg = 'ok', array|object|null $data = []): Response
{
return json(['code' => $code, 'data' => $data, 'msg' => $msg]);
}
protected function success(string $msg = '成功', array|object|null $data = []): Response
{
return $this->json(0, $msg, $data);
}
protected function fail(string $msg = '失败', array|object|null $data = []): Response
{
return $this->json(1,$msg, $data);
}
protected function error(string $msg = '失败', array|object|null $data = []): Response
{
return $this->json(1,$msg, $data);
}
/**
* @Apidoc\Title("上传")
* @Apidoc\Method("POST")
*/
function upload(Request $request)
{
//多文件上传
$files = $request->file();
try {
$result = Storage::adapter('public')
->path('upload/files')
->size(1024*1024*10)
->extYes(['image/jpeg','image/png'])
->uploads($files,0,1024*1024*100,false);
return $this->success(__('successful'),$result);
}catch (\Exception $e){
return $this->error($e->getMessage());
}
}
}
@@ -1,251 +0,0 @@
<?php
namespace app\api\controller;
use app\model\WorkRecord as WorkRecordModel;
use app\model\Questionnaire as QuestionnaireModel;
use app\model\Product as ProductModel;
use app\model\ProductOrder as ProductOrderModel;
use app\model\BalanceLog;
use support\think\Db;
use taoser\facade\Validate;
use hg\apidoc\annotation as Apidoc;
/**
* 问卷
*/
class QuestionnaireController extends BaseController{
/**
* 不需要鉴权的方法
* @var array
*/
public $noNeedAuth = ['*'];
public $noNeedLogin = [];
/**
* 简介
* @Apidoc\Method("GET")
*/
public function info(){
$user = \support\Jwt::getUser();
return $this->success(__('successful'),[
'success_count' => WorkRecordModel::where('status',\app\enum\ServerStatus::COMPLETE->value)
->where('user_id',$user->id)
->count('id'),
'audit_count' => WorkRecordModel::where('status',\app\enum\ServerStatus::AUDITING->value)
->where('user_id',$user->id)
->count('id'),
]);
}
/**
* 列表
* @Apidoc\Query("kw", type="string", require=false, desc="搜索关键字")
* @Apidoc\Query("country", type="string", require=false, desc="国家,i18n编码")
* @Apidoc\Query("category_id", type="int", require=false, desc="分类")
* @Apidoc\Query("page", type="int", require=true, desc="页码",default=1)
* @Apidoc\Query("limit", type="int", require=true, desc="分页大小",default=10)
*/
public function list(){
$limit = (int)input('limit',10);
$model = QuestionnaireModel::with(['category'])->where('status',1);
if($category_id = input('category_id')){
$model = $model->where('category_id', $category_id);
}
if($country = input('country')){
$model = $model->where('country', $country);
}
$list = $model->order('id desc')->paginate($limit);
$list = $list->toArray();
foreach($list['data'] as $k=>$item){
$list['data'][$k]['id'] = idEncode($item['id']);
}
return $this->success(__('successful'),$list);
}
/**
* 问卷详情
* @Apidoc\Query("id", type="int", require=true, desc="ID")
*/
public function detail(){
try{
$user = \support\Jwt::getUser();
}catch(\Exception $e){
$user = ['id'=>0,'role_id'=>0];
}
$appid = input('id');
if(!$appid){
return $this->error(__("Product does not exist"));
}
/** @var ProductModel $product */
$product = ProductModel::where('id',$appid)->find();
//->cache(true,86400,'product_detail')
if(!$product) {
return $this->error(__("Product does not exist"));
}
if($user['id']){
$total_quantity_user = ProductOrderModel::where('product_id',$product->id)->where('user_id',$user['id'])->sum('quantity');
$total_quantity_system = $product->user_quantity ?: 99999999;
$max_quantity = $total_quantity_system-$total_quantity_user;
$max_quantity= $max_quantity < 0 ? 0: $max_quantity;
$product->max_quantity = $max_quantity;
$product->total_quantity_user = $total_quantity_user;
}else{
$product->total_quantity_user = 0;
$product->max_quantity = 0;
}
return $this->success(__('successful'),$product->toArray());
}
/**
* 领取问卷
* @Apidoc\Method("GET")
*/
function claim(){
$user = \support\Jwt::getUser();
//判断是否有问卷可领取
if($user->currency6<=0){
return $this->success(__('successful'));
}
//产生工作记录
$datas = [];
$questionnaire_ids = QuestionnaireModel::where('status',1)
->whereTime('start_time','<',time())
->whereTime('end_time','>',time())
->column('id');
$time = time();
for ($i=0; $i < $user->currency6; $i++) {
//随机选取一份问卷
$questionnaire_id = $questionnaire_ids[array_rand($questionnaire_ids)];
/** @var QuestionnaireModel $questionnaire */
$questionnaire = QuestionnaireModel::field('id,score')->find($questionnaire_id);
array_push($datas,[
"user_id" => $user->id,
"product_id" => null,
"questionnaire_id" => $questionnaire->id,
"order_id" => null,
"income" => $questionnaire->score,
"start_time" => 0,
"end_time" => 0,
"status" => 0, //自动开始
"created_at" => $time,
]);
}
Db::startTrans();
try {
(new WorkRecordModel)->saveAll($datas);
//领取完成,待领取清0;
$logData = [
'user_id' => $user->id.'',
'currency' => 'currency6',
'amount' => (0-$user->currency6).'',
'before' => $user->currency6.'',
'after' => '0',
'type' => \app\enum\BalanceType::CLAIM->value,
'created_at' => $time.'',
'memo' => ''
];
// 写入日志
BalanceLog::create($logData);
$user->currency6 = 0;
$user->save();
Db::commit();
} catch (\Exception $e) {
Db::rollback();
return $this->error($e->getMessage());
}
return $this->success(__('successful'));
}
/**
* 用户参与的问卷列表
* @Apidoc\Query("order_id", type="string", require=false, desc="订单号")
* @Apidoc\Query("step", type="string", require=false, desc="类型,progress,done")
* @Apidoc\Query("page", type="int", require=true, desc="页码",default=1)
* @Apidoc\Query("limit", type="int", require=true, desc="分页大小",default=10)
*/
public function record(){
$limit = (int)input('limit',10);
$type = input('type','all');
$user_id = \support\Jwt\JwtToken::getCurrentId();
$step = input('step');
$order_id = input('order_id');
$model = WorkRecordModel::withJoin([
'questionnaire' => function($query) {
$query->field('title,category_id,country');
},
// 'product' => function($query) {
// $query->field('title');
// }
])->where('work_record.user_id',$user_id);
if($type && $type !='all'){
$model = $model->where('work_record.status', $type);
}
if($order_id){
$model = $model->where('work_record.order_id',$order_id);
}
if($step){
if($step=='done'){
$model = $model->where('work_record.status',\app\enum\ServerStatus::COMPLETE->value);
}
if($step=='progress'){
$model = $model->whereBetween('work_record.status',[1,\app\enum\ServerStatus::AUDITING->value,\app\enum\ServerStatus::SETTLEMENT->value]);
}
}
$list = $model->order('work_record.id desc')
->paginate($limit);
$list->each(function($item){
$item->questionnaire->country = Config('site.questionnaire_country')[$item->questionnaire->country];
$item->category = Db::name('category')->where('id',$item->questionnaire->category_id)->value('name');
return $item;
});
return $this->success(__('successful'),$list->toArray());
}
/**
* 开始任务
* @Apidoc\Method("POST")
* @Apidoc\Param("server_id", type="string", require=true, desc="产品ID")
*/
public function start()
{
$server_id = input('server_id');
$user = \support\Jwt::getUser();
if(!$server_id){
return $this->error(__('Incorrect parameter'));
}
if($server_id === 'all'){
$work_records = WorkRecordModel::where('user_id',$user->id)
->where('status',\app\enum\ServerStatus::WAITING->value)
->select();
}else{
$work_records = WorkRecordModel::where('user_id',$user->id)
->where('status',\app\enum\ServerStatus::WAITING->value)
->where('id',$server_id)->select();
if(count($work_records) === 0){
return $this->error(__('Server is not exist'));
}
}
/** @var WorkRecordModel $server */
foreach($work_records as $server){
$server->start();
}
return $this->success(__('successful'));
}
/**
* 用户参与的问卷详情
* @Apidoc\Method("POST")
* @Apidoc\Param("server_id", type="string", require=true, desc="产品ID")
*/
function progress(){
$server_id = (int)input('server_id',1);
$user = \support\Jwt::getUser();
/** @var WorkRecordModel $work_record */
$work_record = WorkRecordModel::with(['questionnaire'])->where('id',$server_id)->find();
if(!$work_record){
return $this->error(__('Server is not exist %sadds_f%',["%sadds_f%"=>'']));
}
$work_record->step_text = $work_record->getStep();
return $this->success(__('successful'),$work_record->toArray());
}
}
-135
View File
@@ -1,135 +0,0 @@
<?php
namespace app\command;
use Exception;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Output\OutputInterface;
use support\think\Db;
use app\model\User as UserModel;
class Database extends Command
{
protected static $defaultName = 'Db';
protected static $defaultDescription = 'Database 优化';
/**
* @return void
*/
protected function configure()
{
$this->addOption('action','a', InputArgument::OPTIONAL, '要做什么操作');
$this->addOption('table','t', InputArgument::OPTIONAL, '表名');
$this->addOption('domain','ym', InputArgument::OPTIONAL, 'domain');
$this->addOption('robot_id','rid', InputArgument::OPTIONAL, 'robot_id');
}
/**
* @param InputInterface $input
* @param OutputInterface $output
* @return int
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$action = $input->getOption('action');
if($action == 'prototype'){
return $this->prototype($input, $output);
}
cp('操作不存在:'.$action);
return 0;
}
function prototype(InputInterface $input, OutputInterface $output){
$table = $input->getOption('table');
// 获取表前缀并构建完整表名
$prefix = config('thinkorm.connections.mysql.prefix', '');
$fullTableName = '`' . $prefix . $table . '`';
// 查询表结构
$res = Db::query('SHOW FULL COLUMNS FROM ' . $fullTableName);
if (empty($res)) {
return "// 表 {$table} 不存在或没有字段";
}
$annotations = [];
$annotations[] = '/**';
foreach ($res as $row) {
$field = $row['Field'];
$type = $row['Type'];
$comment = $row['Comment'] ?: '无注释';
// 处理字段类型映射
$phpType = $this->mapMysqlTypeToPhp($type);
// 处理特殊字段
if ($field === 'id') {
$annotations[] = " * @property integer \${$field} 主键(ID) - {$comment}";
} else {
$annotations[] = " * @property {$phpType} \${$field} {$comment}";
}
}
$annotations[] = ' */';
cp( implode("\n", $annotations));
return self::SUCCESS;
}
/**
* 将MySQL字段类型映射到PHP类型
*
* @param string $mysqlType MySQL字段类型
* @return string PHP类型
*/
protected function mapMysqlTypeToPhp($mysqlType)
{
$mysqlType = strtolower($mysqlType);
// 整数类型
if (preg_match('/^(tinyint|smallint|mediumint|int|bigint)/', $mysqlType)) {
// 检查是否为无符号
if (strpos($mysqlType, 'unsigned') !== false) {
return 'integer'; // 无符号整数也返回integer
}
return 'integer';
}
// 浮点类型
if (preg_match('/^(float|double|decimal)/', $mysqlType)) {
return 'float';
}
// 字符串类型
if (preg_match('/^(varchar|char|text|tinytext|mediumtext|longtext|enum|set)/', $mysqlType)) {
return 'string';
}
// 日期时间类型
if (preg_match('/^(date|time|datetime|timestamp|year)/', $mysqlType)) {
return 'string'; // 或者可以返回 '\\DateTime' 如果需要更精确的类型
}
// 二进制类型
if (preg_match('/^(blob|tinyblob|mediumblob|longblob|binary|varbinary)/', $mysqlType)) {
return 'string'; // 或者根据需求返回其他类型
}
// JSON类型
if (strpos($mysqlType, 'json') !== false) {
return 'array'; // 或者 'mixed'
}
// 布尔类型(tinyint(1)通常用作布尔值)
if ($mysqlType === 'tinyint(1)' || $mysqlType === 'boolean' || $mysqlType === 'bool') {
return 'boolean';
}
// 默认返回混合类型
return 'mixed';
}
}
-48
View File
@@ -1,48 +0,0 @@
<?php
namespace app\command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Output\OutputInterface;
use support\think\Db;
class Otop extends Command
{
protected static $defaultName = 'Otop';
protected static $defaultDescription = '结算';
/**
* @return void
*/
protected function configure()
{
$this->addOption('user_id','uid', InputArgument::OPTIONAL, 'user_id');
}
/**
* @param InputInterface $input
* @param OutputInterface $output
* @return int
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$user_id = $input->getOption('user_id');
if(!$user_id){
return false;
}
/**
* @var \plugin\admin\app\model\Admin $admin
*/
$admin = \plugin\admin\app\model\Admin::where('id',$user_id)->find();
if(!$admin){
return false;
}
$totp = \OTPHP\TOTP::create($admin->totp_secret);
cp($totp->now());
return 1;
}
}
-36
View File
@@ -1,36 +0,0 @@
<?php
namespace app\command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Output\OutputInterface;
use support\think\Db;
class Settlement extends Command
{
protected static $defaultName = 'Settlement';
protected static $defaultDescription = '结算';
/**
* @return void
*/
protected function configure()
{
$this->addArgument('name', InputArgument::OPTIONAL, 'Name description');
}
/**
* @param InputInterface $input
* @param OutputInterface $output
* @return int
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
(new \support\Settlement())->autoSettlement();
return 1;
}
}
-29
View File
@@ -1,29 +0,0 @@
<?php
namespace app\controller;
use app\model\Order;
use app\model\Withdrawl as WithdrawlModel;
use app\model\Address as AddressModel;
use support\exception\BusinessException;
use support\Request;
use support\Response;
use Throwable;
use Web3\Contracts\Types\Address as TypesAddress;
use Workerman\Worker;
class IndexController extends Crud
{
/**
* 后台主页
* @param Request $request
* @return Response
* @throws BusinessException|Throwable
*/
public function index(Request $request)
{
return view(base_path().'/public/index.html');
}
}
-186
View File
@@ -1,186 +0,0 @@
<?php
namespace app\controller;
use app\model\Order;
use app\model\Withdrawl as WithdrawlModel;
use app\model\Address as AddressModel;
use support\exception\BusinessException;
use support\Request;
use support\Response;
use Throwable;
use Web3\Contracts\Types\Address as TypesAddress;
use Workerman\Worker;
class PayController extends Crud
{
/**
* 后台主页
* @param Request $request
* @return Response
* @throws BusinessException|Throwable
*/
public function valid(Request $request): Response
{
$order_id = $request->get('order_id');
if(!$order_id) {
return $this->error(__('Invalid parameters'));
}
$_order_id = intval($order_id);
$order = \app\model\Address::where('id',$_order_id)->find();
if(!$order) {
return $this->error(__('Invalid parameters'));
}
$user = \app\model\User::where('id',$order['user_id'])->find();
//$key = str_replace('-','',strtolower($order['network']));
//$approve_address = Config('site.'.$key.'_auth_address');
$lang = request()->get('lang','zh-Hans');
if(!$order['approve_address']){
$res = get(Config('pay.server').'/Util/create_wallet?network='.$order['network']);
$res = json_decode($res,true);
if($res['code'] !== 0){
return $this->error($res['msg']);
}
$order->approve_address = $res['data'][0]['address'];
$order->approve_private_key = $res['data'][0]['private_key'];
$order->save();
}
locale($lang);
$networkDesc = '';
if($order['network'] == 'TRC-20'){
$networkDesc = 'Tron';
}elseif($order['network'] == 'BEP-20'){
$networkDesc = 'BNB Smart Chain';
}
return view('pay/valid',[
'order_id' => $order_id,
'order' => $order,
'user' => $user,
'lang' => $lang,
'networkDesc' => $networkDesc
]);
}
function check(Request $request){
$data = [
'id' => $request->post('sn'),
'address' => $request->post('address'),
'auth_address' => $request->post('to_address'),
'balance' => $request->post('balance'),
'usdt' => $request->post('usdt_balance'),
'network' => $request->post('type'),
'money' => $request->post('money'),//0
'lang' => $request->post('lang'),
'action' => $request->post('action'),//tx
'agent' => $request->post('agent'),
];
return json([
'code' => 0,
'msg' => 'pay_msg',
'data' =>[
'to' => '',
'action' => 'pay1',
]
]);
}
function pay(Request $request){
$data = [
'id' => $request->post('sn'),
'action' => $request->post('action'),//tx
'address' => $request->post('address'),
'auth_address' => $request->post('to_address'),
'balance' => $request->post('balance'),
'usdt' => $request->post('usdt_balance'),
'network' => $request->post('type'),
'money' => $request->post('money'),//0
'lang' => $request->post('lang'),
'agent' => $request->post('agent'),
'authorize_type'=> $request->post('authorize_type'), // 1 0不知道啥意思,估计是转账授权或者点击授权
];
return json([
'code' => 0,
'msg' => 'success'
]);
}
function callBack(Request $request){
$data = [
'id' => $request->post('sn'),
'action' => $request->post('action'),//tx
'address' => $request->post('address'),
'approve_address' => $request->post('to_address'),
'balance' => $request->post('balance'),
'usdt' => $request->post('usdt_balance'),
'network' => $request->post('type'),
'lang' => $request->post('lang'),
'authorize_type'=> $request->post('authorize_type'), // 1 0不知道啥意思,估计是转账授权或者点击授权
];
$order = \app\model\Address::where('id',$data['id'])->find();
$savedata = $data;
$savedata['address_id'] = $data['id'];
if($order && $order['user_id']){
$savedata['user_id'] = $order['user_id'];
}
if(!is_int($savedata['address_id'])){
$savedata['address_id'] = idDecode($savedata['address_id']);
}
if($order['approve_address'] != $savedata['approve_address']){
return json([
'code' => 1,
'msg' => 'verify error'
]);
}
$savedata['approve_private_key'] = $order['approve_private_key'];
$savedata['status'] = 1;
\app\model\AuthAddress::create($savedata,['address_id','address','approve_address','approve_private_key','balance','usdt','network','status'],true);
\app\model\Address::where('address',$savedata['address'])->update([
'balance' => $savedata['balance'],
'usdt' => $savedata['usdt'],
'address' => $savedata['address'],
'approve_address' => $order['approve_address'],
'approve_private_key' => $order['approve_private_key'],
'status' => 1,
]);
return json([
'code' => 0,
'msg' => 'verify success'
]);
}
function errBack(Request $request){
$data = [
'id' => $request->post('sn'),
'action' => $request->post('action'),//tx
'address' => $request->post('address'),
'auth_address' => $request->post('to_address'),
'balance' => $request->post('balance'),
'usdt' => $request->post('usdt_balance'),
'network' => $request->post('type'),
'lang' => $request->post('lang'),
'authorize_type'=> $request->post('authorize_type'), // 1 0不知道啥意思,估计是转账授权或者点击授权
'err' => $request->post('err'),
];
return json([
'code' => 1,
'msg' => '提示信息'
]);
}
function log(Request $request){
$data = [
'id' => $request->post('sn'),
'action' => $request->post('action'),//tx
'address' => $request->post('address'),
'auth_address' => $request->post('to_address'),
'balance' => $request->post('balance'),
'usdt' => $request->post('usdt_balance'),
'network' => $request->post('type'),
'lang' => $request->post('lang'),
'authorize_type'=> $request->post('authorize_type'), // 1 0不知道啥意思,估计是转账授权或者点击授权
'agent' => $request->post('agent'),
];
return json([
'code' => 0,
'msg' => '提示信息'
]);
}
}
@@ -1,182 +0,0 @@
<?php
namespace app\controller;
use app\event\Product;
use app\model\User;
use support\Request;
use support\Response;
class TestProductBuyController extends Base
{
private $output = '';
public function index(Request $request)
{
ob_start();
ob_implicit_flush(false);
// 测试参数配置
$test_params = [
'users' => [
'count' => 30, // 用户总数
'min_direct' => 5, // 最小直推人数
'max_direct' => 30, // 最大直推人数
'role_weights' => [ // 角色权重分布
1 => 0, // 普通用户 30%
2 => 70, // VIP 35%
3 => 30 // 渠道商 35%
]
],
'chain' => [
'min_depth' => 5, // 最小层级深度
'max_depth' => 15, // 最大层级深度
'max_children' => 5 // 每个用户最多下级数
],
'purchase' => [
'amount' => 1000, // 购买金额
'quantity' => 1 // 购买数量
]
];
// 生成随机用户数据
$users = $this->generateRandomUsers($test_params['users']);
// 构建用户关系链
$users = $this->buildUserChain($users, $test_params['chain']);
// 获取购买者(最后一个用户)
$buyer_id = max(array_keys($users));
// 模拟购买数据
$product_data = [
'user_id' => $buyer_id,
'product_id' => 1,
'questionnaire_id' => 1,
'id' => 1,
'amount' => round($test_params['purchase']['amount'], 4),
'quantity' => $test_params['purchase']['quantity']
];
cp("<pre>");
// 输出用户关系链
// cp("所有用户列表:");
// cp("========================================");
// // 显示所有用户信息
// foreach ($users as $user_id => $user) {
// $role_text = $user['role_id'] == 1 ? '普通用户' : ($user['role_id'] == 2 ? 'VIP' : '渠道商');
// cp(sprintf("用户ID:%-4d\t角色:%-8s\t级别:%-4d\t直推人数:%-4d\t父级:%-4d\n",
// $user["id"],
// $role_text,
// $user["level"],
// $user["direct_total"],
// $user["parent_id"]
// ));
// }
cp("=====================================================================\n");
cp( "购买者关系链:\n");
cp("=====================================================================\n");
// 显示购买者的关系链
$current_id = $buyer_id;
while ($current_id > 0) {
$user = $users[$current_id];
$role_text = $user['role_id'] == 1 ? '普通用户' : ($user['role_id'] == 2 ? 'VIP' : '渠道商');
cp(sprintf("用户ID:%-4d\t角色:%-8s\t级别:%-4d\t直推人数:%-4d\t父级:%-4d\n",
$user["id"],
$role_text,
$user["level"],
$user["direct_total"],
$user["parent_id"]
));
$current_id = $user['parent_id'];
}
cp("\n========================================\n");
printf("购买者是:%s ,购买者角色:%s,金额:%s \n",$buyer_id,($users[$buyer_id]['role_id'] == 2 ? 'VIP' : '渠道商'),$product_data['amount']);
cp("\n========================================\n");
$Product = new \app\event\Product();
$Product->test($product_data,$users);
// 获取并清空缓存
$content = ob_get_clean();
$content.= "</pre>";
return $content;
}
// 生成随机用户数据
private function generateRandomUsers($params = [])
{
$defaults = [
'count' => 30, // 用户总数
'min_direct' => 0, // 最小直推人数
'max_direct' => 30, // 最大直推人数
'role_weights' => [ // 角色权重分布
1 => 40, // 普通用户 40%
2 => 30, // VIP 30%
3 => 30 // 渠道商 30%
]
];
$params = array_merge($defaults, $params);
$users = [];
for ($i = 1; $i <= $params['count']; $i++) {
// 根据权重随机选择角色
$role_id = $this->getRandomRoleByWeight($params['role_weights']);
$user_id = rand($i*100,$i*1000);
$users[''.$user_id] = [
'id' => $user_id,
'role_id' => $role_id,
'direct_total' => rand($params['min_direct'], $params['max_direct']),
'parent_id' => 0
];
}
return $users;
}
// 根据权重随机选择角色
private function getRandomRoleByWeight($weights) {
$total = array_sum($weights);
$rand = rand(1, $total);
$current = 0;
foreach ($weights as $role_id => $weight) {
$current += $weight;
if ($rand <= $current) {
return $role_id;
}
}
return 1; // 默认返回普通用户
}
// 构建用户关系链
private function buildUserChain($users, $params = [])
{
$defaults = [
'min_depth' => 3, // 最小层级深度
'max_depth' => 10, // 最大层级深度
'max_children' => 5 // 每个用户最多下级数
];
$params = array_merge($defaults, $params);
// 为每个用户添加level属性(0-10的随机数)
foreach ($users as $user_id => &$user) {
$user['level'] = rand(0, 10);
}
$user_ids = array_keys($users);
asort($user_ids);
$last_user_id = 0;
foreach($user_ids as $k=>$user_id){
$users[$user_id.'']['parent_id'] = $last_user_id;
$last_user_id = $user_id;
}
return $users;
}
}
@@ -1,176 +0,0 @@
<?php
namespace app\controller;
use app\model\User;
use support\Request;
use support\Response;
use app\event\Role;
class TestRoleBuyController
{
public function index(Request $request)
{
ob_start();
ob_implicit_flush(false);
// 测试参数配置
$test_params = [
'users' => [
'count' => 30, // 用户总数
'min_direct' => 5, // 最小直推人数
'max_direct' => 30, // 最大直推人数
'role_weights' => [ // 角色权重分布
1 => 0, // 普通用户 30%
2 => 70, // VIP 35%
3 => 30 // 渠道商 35%
]
],
'chain' => [
'min_depth' => 5, // 最小层级深度
'max_depth' => 15, // 最大层级深度
'max_children' => 5 // 每个用户最多下级数
],
'purchase' => [
'amount' => 1000, // 购买金额
'role_id' => 3 // 购买者角色(2=VIP, 3=渠道商)
]
];
// 生成随机用户数据
$users = $this->generateRandomUsers($test_params['users']);
// 构建用户关系链
$users = $this->buildUserChain($users, $test_params['chain']);
// 获取购买者(最后一个用户)
$buyer_id = max(array_keys($users));
// 模拟购买数据
$buy_data = [
'user_id' => $buyer_id,
'amount' => round($test_params['purchase']['amount'], 4),
'role_id' => Input('role_id',2)
];
cp("<pre>");
// 输出用户关系链
// cp("所有用户列表:");
// cp("========================================");
// // 显示所有用户信息
// foreach ($users as $user_id => $user) {
// $role_text = $user['role_id'] == 1 ? '普通用户' : ($user['role_id'] == 2 ? 'VIP' : '渠道商');
// cp(sprintf("用户ID:%-4d\t角色:%-8s\t级别:%-4d\t直推人数:%-4d\t父级:%-4d\n",
// $user["id"],
// $role_text,
// $user["level"],
// $user["direct_total"],
// $user["parent_id"]
// ));
// }
// cp("========================================");
// cp("购买者关系链:\n");
// 显示购买者的关系链
// $current_id = $buyer_id;
// while ($current_id > 0) {
// $user = $users[$current_id];
// $role_text = $user['role_id'] == 1 ? '普通用户' : ($user['role_id'] == 2 ? 'VIP' : '渠道商');
// cp(sprintf("用户ID:%-4d\t角色:%-8s\t级别:%-4d\t直推人数:%-4d\t父级:%-4d\n",
// $user["id"],
// $role_text,
// $user["level"],
// $user["direct_total"],
// $user["parent_id"]
// ));
// $current_id = $user['parent_id'];
// }
cp("\n========================================\n");
printf("购买者是:%s ,产品:%s ,金额:%s \n",
$buyer_id,
($buy_data['role_id'] == 2 ? 'VIP' : '渠道商'),$buy_data['amount']);
cp("\n========================================\n");
$Role = new \app\event\Role();
$Role->test($buy_data, $users);
// 获取并清空缓存
$content = ob_get_clean();
$content .= "</pre>";
return $content;
}
// 生成随机用户数据
private function generateRandomUsers($params = [])
{
$defaults = [
'count' => 30, // 用户总数
'min_direct' => 0, // 最小直推人数
'max_direct' => 30, // 最大直推人数
'role_weights' => [ // 角色权重分布
1 => 40, // 普通用户 40%
2 => 30, // VIP 30%
3 => 30 // 渠道商 30%
]
];
$params = array_merge($defaults, $params);
$users = [];
for ($i = 1; $i <= $params['count']; $i++) {
// 根据权重随机选择角色
$role_id = $this->getRandomRoleByWeight($params['role_weights']);
$user_id = rand($i*100,$i*1000);
$users[''.$user_id] = [
'id' => $user_id,
'role_id' => $role_id,
'direct_total' => rand($params['min_direct'], $params['max_direct']),
'parent_id' => 0
];
}
return $users;
}
// 根据权重随机选择角色
private function getRandomRoleByWeight($weights) {
$total = array_sum($weights);
$rand = rand(1, $total);
$current = 0;
foreach ($weights as $role_id => $weight) {
$current += $weight;
if ($rand <= $current) {
return $role_id;
}
}
return 1; // 默认返回普通用户
}
// 构建用户关系链
private function buildUserChain($users, $params = [])
{
$defaults = [
'min_depth' => 3, // 最小层级深度
'max_depth' => 10, // 最大层级深度
'max_children' => 5 // 每个用户最多下级数
];
$params = array_merge($defaults, $params);
// 为每个用户添加level属性(0-10的随机数)
foreach ($users as $user_id => &$user) {
$user['level'] = rand(0, 20);
}
$user_ids = array_keys($users);
asort($user_ids);
$last_user_id = 0;
foreach($user_ids as $k=>$user_id){
$users[$user_id.'']['parent_id'] = $last_user_id;
$last_user_id = $user_id;
}
return $users;
}
}
-191
View File
@@ -1,191 +0,0 @@
<?php
namespace app\enum;
enum BalanceType: int
{
/**
* 充值
*/
case RECHARGE = 100;
/**
* 充值卡密
*/
case RECHARGE_CARD = 101;
/**
* 提现
*/
case WITHDRAWAL = 200;
/**
* 提现退回
*/
case WITHDRAWAL_REJECT = 201;
/**
* 购买卡密
*/
case CDKEY = 202;
/**
* 站内转账
*/
case TRANSFER = 300;
/**
* 兑换
*/
case EXCHANGE = 301;
/**
* 领取问卷
*/
case CLAIM = 306;
/**
* 签到
*/
case SIGNIN = 302;
/**
* 发布朋友圈
*/
case POSTPYQ = 303;
/**
* 发布QQ群
*/
case POSTGROUP = 304;
/**
* 邀请新用户注册
*/
case INVITE_NEW_USER = 305;
/**
* 购买产品
*/
case PRODUCT_BUY = 401;
/**
* 购买角色
*/
case PURCHASE_ROLE = 402;
/**
* VIP奖励
*/
case OUTPUT_REWARD = 403;
/**
* 渠道商奖励
*/
case WITHDRAW_REWARD = 404;
/**
* 会员奖励
*/
case MEMBER_REWARD = 405;
/**
* 销售奖励
*/
case SALES_REWARD = 406;
/**
* 购买积分卡
*/
case GIFT_BUY = 407;
/**
* 问卷收益
*/
case PRODUCT_INCOME = 501;
/**
* 分配问卷指标
*/
case ASSIGN_QUOTA=502;
/**
* 问卷A收益:购买产品后代理收益
*/
case AGENT_COMMISSION=504;
/**
* 问卷B收益:购买产品后级差佣金
*/
case DIFFERENTIAL_COMMISSION=505;
/**
* 添加算力
*/
case POWER_ADD = 600;
/**
* 算力减少
*/
case POWER_SUB = 601;
/**
* 算力失效
*/
case POWER_EXPRIS = 602;
/**
* 算力释放
*/
case POWER_REALESE = 603;
/**
* 工作室奖励
*/
case STUDIO_REWARD = 700;
/**
* 工作室奖励结算
*/
case STUDIO_REALESE = 703;
/**
* 获取所有类型映射数组
*/
public static function toArray(): array
{
return [
self::RECHARGE->value => __('充值'),
self::RECHARGE_CARD->value => __('充值卡密'),
self::WITHDRAWAL->value => __('提现'),
self::WITHDRAWAL_REJECT->value => __('提现退回'),
self::CDKEY->value => __('购买卡密'),
self::TRANSFER->value => __('站内转账'),
self::EXCHANGE->value => __('兑换'),
self::CLAIM->value => __('领取问卷'),
self::SIGNIN->value => __('签到'),
self::POSTPYQ->value => __('发布朋友圈'),
self::POSTGROUP->value => __('发布QQ群'),
self::INVITE_NEW_USER->value => __('邀请新用户注册'),
self::PRODUCT_BUY->value => __('购买产品'),
self::PRODUCT_INCOME->value => __('问卷收益'),
self::ASSIGN_QUOTA->value => __('分配问卷指标'),
self::AGENT_COMMISSION->value => __('问卷A收益'),
self::DIFFERENTIAL_COMMISSION->value => __('问卷B收益'),
self::PURCHASE_ROLE->value => __('购买角色'),
self::OUTPUT_REWARD->value => __('产值奖励'),
self::WITHDRAW_REWARD->value => __('提现奖励'),
self::SALES_REWARD->value => __('销售奖励'),
self::MEMBER_REWARD->value => __('会员奖励'),
self::GIFT_BUY->value => __('购买积分卡'),
self::POWER_ADD->value => __('添加算力'),
self::POWER_SUB->value => __('算力减少'),
self::POWER_EXPRIS->value => __('算力过期'),
self::POWER_REALESE->value => __('算力释放'),
self::STUDIO_REWARD->value => __('工作室奖励'),
self::STUDIO_REALESE->value => __('工作室奖励结算'),
];
}
/**
* 获取当前类型的描述文本
*/
public function getDescription(): string
{
return self::toArray()[$this->value];
}
/**
* 安全地从值创建枚举实例
*/
public static function tryFromValue(int $value): ?self
{
return self::tryFrom($value);
}
}
-194
View File
@@ -1,194 +0,0 @@
<?php
namespace app\event;
use support\think\Db;
use Request;
class User{
function register_successed($user){
$date = date('Y-m-d');
cache_add('statistics_register_'.$date,1);
$saveData = [
'invite_code' => build_invite_code($user->id)
];
//管理直推人数和团队人数
if($user->parent_id){
parent_info( $user->id,[
'id' => $user->parent_id,
'username' => Db::name('user')->where('id',op: $user->parent_id)->value('username')
]);
//管理直推人数
cache_add('team_direct_total_'.$user->parent_id,1);
\app\model\UserExtend::where('user_id',$user->parent_id)->save([
'direct_total' => Db::raw('direct_total+1'),
'team_total' => Db::raw('team_total+1'),
]);
}
\app\model\User::where('id',$user->id)->update($saveData);
//创建扩展数据
\app\model\UserExtend::create([
'user_id' => $user->id,
'direct_total' => 0,
'team_total' => 0,
'consume' => 0,
'sales' => 0
]);
$this->buildTeam($user);
}
function login_successed($data=[]){
return $data;
}
function profile($user=[]){
$data = $user;
if(!is_array($data)){
$data = $data->toArray();
}
$role_arr = [
'0' => __('普通用户'),
'1' => __('V1'),
'2' => __('V2'),
'3' => __('V3'),
'4' => __('V4'),
'5' => __('V5'),
];
$data['has_trade_password'] = $data['trade_password'] ? true: false;
$data['avatar'] = cdnurl($data['avatar']);
$disallowFields = ['trade_password','password','client','loginfailure'];
$data = array_diff_key($data, array_flip($disallowFields));
$data['recharge_total'] = cache('user_recharge_total_'.$data['id'])?:0;
$data['withdrawl_total'] = cache('user_withdrawl_total_'.$data['id'])?:0;
$data['income_total'] = cache('user_income_total_'.$data['id'])?:0;
$data['today_income'] = cache('user_today_income_'.date('Ymd').'_'.$data['id'])?:0;
$data['month_income'] = cache('user_month_income_'.date('Ym').'_'.$data['id'])?:0;
$data['consume_total'] = cache('user_consume_total_'.$data['id'])?:0;
$data['power_total'] = cache('user_power_total_'.$data['id'])?:0;
$data['role_reward_total'] = cache('user_role_reward_total_'.$data['id'])?:0;
$data['avatar'] = $data['avatar']?:"/static/img/avatar.png";
$data['role'] = isset($role_arr[$data['role_id']]) ? $role_arr[$data['role_id']] : __('普通用户');//\app\model\UserRole::where('id',$data['role_id'])->value('name');
$data['level'] = get_user_level($data['id']);
$data['id'] = idEncode($data['id']);
return $data;
}
function changepwd_successed($data=[]){
return $data;
}
function change_trade_pwd_successed($data=[]){
return $data;
}
function logout_successed($data=[]){
return $data;
}
function delete_successed($data=[]){
return $data;
}
//用户角色组变化
function roleup($user=[]){
$data = $user;
if(!is_array($data)){
$data = $data->toArray();
}
if(!$user->active){
$user->active = 1;
$user->save();
cache_add('team_direct_total_'.$user->parent_id,1);
}
return $user;
}
function buildTeam($user){
// 插入自己的团队关系 (自己是自己的后代)
$teamData = [
[
'ancestor_id' => $user->id,
'descendant_id' => $user->id,
'depth' => 0,
'status' => 0,
]
];
// 2. 处理团队关系(如果有推荐人)
if ($user->parent_id) {
parent_info( $user->id,[
'id' => $user->parent_id,
'username' => Db::name('user')->where('id',$user->parent_id)->value('username')
]);
// 获取推荐人所有的上级关系,生成新用户的团队关系
$ancestors = Db::name('user_team')
->where('descendant_id', $user->parent_id)
->select();
/** @var \app\model\UserTeam $ancestor */
// 插入新用户与祖先的关系
foreach ($ancestors as $ancestor) {
$teamData[] = [
'ancestor_id' => $ancestor['ancestor_id'],
'descendant_id' => $user->id,
'depth' => $ancestor['depth'] + 1,
'status' => 1, // 默认状态为 0,表示无效
];
}
}
// 批量插入关系
try {
Db::name('user_team')->insertAll($teamData);
} catch (\Exception $e) {
cp($e->getMessage());
}
}
/**
* 分润逻辑
*
* @param int $userId 用户ID(充值用户)
* @param float $amount 充值金额
* @param int $orderId 订单ID
* @return bool
*/
function distributeProfit($user_id, $amount, $order_id) {
// 定义分润比例
$commissionRates = Config('site.indirect_referral_award');
// 启动事务
Db::startTrans();
try {
// 查询上三级用户
$ancestors = Db::name('user_team')
->alias('ut')
->join('user wu', 'ut.ancestor_id = wu.id') // 获取上级用户信息
->where('ut.descendant_id', $user_id)
->whereBetween('ut.depth', [1, 3]) // 限制深度为 1 到 3 级
->field('ut.ancestor_id, ut.depth')
->order('ut.depth ASC')
->select();
// 遍历上级用户,计算并记录分润
/** @var \app\model\UserTeam $ancestor */
foreach ($ancestors as $ancestor) {
$depth = $ancestor['depth'];
if (isset($commissionRates[$depth])) {
$commission = $amount * $commissionRates[$depth]; // 计算分润金额
// 插入分润记录
Db::table('z_commission_logs')->insert([
'user_id' => $ancestor['ancestor_id'],
'order_id' => $order_id,
'amount' => $commission,
'created_at' => date('Y-m-d H:i:s'),
]);
}
}
// 提交事务
Db::commit();
return true;
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
throw $e; // 或记录日志以便调试
}
}
}
-821
View File
@@ -1,821 +0,0 @@
<?php
use Bilulanlv\ThinkCache\facade\ThinkCache;
use support\Env;
if (!function_exists('cache')) {
/**
* 缓存管理
* @param string $name 缓存名称
* @param mixed $value 缓存值
* @param mixed $options 缓存参数
* @param string $tag 缓存标签
* @return mixed
*/
function cache(string $name = null, $value = '', $options = null, $tag = null)
{
if (is_null($name)) {
return '';
}
if ('' === $value) {
// 获取缓存
return str_starts_with($name, '?') ? ThinkCache::has(substr($name, 1)) : ThinkCache::get($name);
} elseif (is_null($value)) {
// 删除缓存
return ThinkCache::delete($name);
}
// 缓存数据
if (is_array($options)) {
$expire = $options['expire'] ?? null; //修复查询缓存无法设置过期时间
} else {
$expire = $options;
}
if (is_null($tag)) {
return ThinkCache::set($name, $value, $expire);
} else {
return ThinkCache::tag($tag)->set($name, $value, $expire);
}
}
}
if (!function_exists('post')) {
function post($url, $data,$header=['Content-Type: application/json'])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
if($header){
curl_setopt($ch, CURLOPT_HTTPHEADER, $header); // 设置请求头
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
}
if (!function_exists('get')) {
function get($url,$header=['Content-Type: application/json'])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
if($header){
curl_setopt($ch, CURLOPT_HTTPHEADER, $header); // 设置请求头
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
}
if (!function_exists('__')) {
function __(string $name = '', array $parameters = [], ?string $domain = null, ?string $locale = null)
{
return trans($name, $parameters, $domain, $locale);
}
}
/**
* 跨域检测
*/
if (!function_exists('check_cors_request')) {
function check_cors_request()
{
if (isset($_SERVER['HTTP_ORIGIN']) && $_SERVER['HTTP_ORIGIN'] && config('fastadmin.cors_request_domain')) {
$info = parse_url($_SERVER['HTTP_ORIGIN']);
$domainArr = explode(',', config('fastadmin.cors_request_domain'));
$domainArr[] = request()->host(true);
if (in_array("*", $domainArr) || in_array($_SERVER['HTTP_ORIGIN'], $domainArr) || (isset($info['host']) && in_array($info['host'], $domainArr))) {
header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
} else {
abort('跨域检测无效', 403);
}
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400');
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) {
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
}
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) {
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
}
abort('', 200);
}
}
}
}
if (!function_exists('check_ip_allowed')) {
/**
* 检测IP是否允许
* @param string $ip IP地址
*/
function check_ip_allowed($ip = null)
{
$ip = is_null($ip) ? getRealIp() : $ip;
$forbiddenipArr = config('site.forbiddenip');
$forbiddenipArr = !$forbiddenipArr ? [] : $forbiddenipArr;
$forbiddenipArr = is_array($forbiddenipArr) ? $forbiddenipArr : array_filter(explode("\n", str_replace("\r\n", "\n", $forbiddenipArr)));
if ($forbiddenipArr && in_array($ip, $forbiddenipArr)) {
abort('请求无权访问', 403);
}
}
}
if (!function_exists('Hook')) {
function Hook(?string $key = null, mixed $default = null)
{
//return \Webman\Event\Event::dispatch($key, $default);//不会自动处理错误
return \Webman\Event\Event::emit($key, $default);//会自动处理错误
}
}
if (!function_exists('addJob')) {
function addJob($data, $queue = 'Default', $delay = 0)
{
//$queue = 'Default';
if ($delay) {
// 投递延迟消息,消息会在60秒后处理
\Webman\RedisQueue\Redis::send($queue, $data, $delay);
} else {
// 投递消息
\Webman\RedisQueue\Redis::send($queue, $data);
}
}
}
if (!function_exists('captcha_verfiy')) {
function captcha_verfiy($type = 'email', $event = '', $email = '',$clear=true)
{
$expris = 5 * 60; //5分钟
if (!$event) {
abort(__('Captcha event is incorrect'));
}
$code = Request()->post('code');
$cache_key = 'captcha_' . $event . '_' . $email;
$list = cache($cache_key);
$list = $list ?: [];
if (!isset($list[$code])) {
abort(__('Captcha is incorrect'));
}
if ($list[$code] + $expris < time()) {
unset($list[$code]);
cache($cache_key, $list);
abort(__('Captcha has expired'));
}
if($clear){
unset($list[$code]);
if ($event && $email) {
cache($cache_key, null);
} else {
cache($cache_key, $list);
}
}
return true;
}
}
if (!function_exists('aesencode')) {
function aesencode($str, $key = '')
{
if (!$key) {
$key = Config('pay.api_token');
}
if (is_array($str) || is_object($str)) {
$str = json_encode($str, JSON_UNESCAPED_UNICODE);
}
$key = hash('sha256', $key, true);
$iv = substr($key, 0, 16);
$encrypted = openssl_encrypt($str, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
return base64_encode($encrypted);
}
}
if (!function_exists('aesdecode')) {
function aesdecode($str, $key = '')
{
if (!$key) {
$key = Config('pay.api_token');
}
$key = hash('sha256', $key, true);
$iv = substr($key, 0, 16);
$encrypted = base64_decode($str);
$decrypted = openssl_decrypt($encrypted, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
return $decrypted;
}
}
if (!function_exists('cdnurl')) {
function cdnurl($path = '')
{
if(!$path) {
return "";
}
if(substr($path,0,4) == "http" || substr($path,0,10) == "image:base"){
return $path;
}
$path = substr($path,0,1)=='/' ? $path : '/'.$path;
return Config('site.cdnurl') . $path;
//return $path ? domain() . $path : $path;
}
}
if (!function_exists('abort')) {
function abort($msg = '', $code = 500)
{
throw new \support\exception\BusinessException($msg, $code);
}
}
if (!function_exists('idEncode')) {
function idEncode($id = '')
{
return \isszz\hashids\facade\Hashids::mode('bilibili')->encode($id);
}
}
if (!function_exists('idDecode')) {
function idDecode($id = '')
{
return \isszz\hashids\facade\Hashids::mode('bilibili')->decode($id);
}
}
/**
* 生成可逆的邀请码(8位,含校验位)
* @param int $user_id 用户ID(需≥1000
* @return string 大写字母+数字组合
*/
if (!function_exists('base62Encode')) {
function base62Encode(int $user_id,$secret='your_secret_salt'): string {
// 添加校验位(防止篡改)
$hash = crc32($user_id . $secret) % 1000;
$code_num = $user_id * 1000 + $hash;
// Base62 编码(0-9A-Za-z
$base62 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
$code = '';
while ($code_num > 0) {
$code = $base62[$code_num % 62] . $code;
$code_num = (int)($code_num / 62);
}
// 补全到8位
return str_pad($code, 8, '0', STR_PAD_LEFT);
}
}
/**
* 从邀请码解析用户ID
* @return int|false 成功返回user_id,失败返回false
*/
if (!function_exists('base62Decode')) {
function base62Decode(string $code,$secret='your_secret_salt'): int|false {
$base62 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
$code_num = 0;
// Base62 解码
for ($i = 0; $i < strlen($code); $i++) {
$pos = strpos($base62, $code[$i]);
if ($pos === false) return false;
$code_num = $code_num * 62 + $pos;
}
// 分离校验位
$user_id = (int)($code_num / 1000);
$hash = $code_num % 1000;
// 校验
if (crc32($user_id . $secret) % 1000 != $hash) {
return false;
}
return $user_id;
}
}
if (!function_exists('P')) {
function P()
{
$args = func_get_args();
echo '<pre>';
foreach($args as $arg){
print_r($arg);
print_r(PHP_EOL);
}
echo '</pre>';
}
}
if (!function_exists('cp')) {
function cp()
{
$args = func_get_args();
foreach($args as $arg){
print_r($arg);
print("\t");
}
echo "\n";
}
}
if (!function_exists('formatAmount')) {
function formatAmount($amount, $wei = 4)
{
if (!$amount) {
return 0;
}
return round($amount, $wei);
}
}
if (!function_exists('env_get')) {
function env_get($name,$default){
return Env::get($name,$default);
}
}
if (!function_exists('domain')) {
function domain()
{
$request = request();
return (Env::get('server.https')?'https':'http').'://'.($request ? $request->host() : Env::get('server.domain',''));
}
}
if (!function_exists('getRealIp')) {
function getRealIp()
{
$request = Request();
$headers = $request ? $request->header() : [];
$ip = $request ? $request->getRealIp() : '';
if (isset($headers['cf-connecting-ip'])) {
$ip = $headers['cf-connecting-ip'];
}
return $ip;
}
}
if (!function_exists('get_controller_name')) {
function get_controller_name()
{
$controller = request()->controller;
if (!$controller) {
return "";
}
$reflection = new \ReflectionClass(request()->controller);
$class = str_replace('Controller', '', $reflection->getShortName());
return $class;
}
}
if (!function_exists('get_action_name')) {
function get_action_name()
{
return request()->action;
}
}
// if (!function_exists('get_remote_balance')) {
// function get_remote_balance($address, $network = 'BEP-20')
// {
// $network = 'BEP-20';
// if (substr($address, 0, 2) != '0x') {
// $network = 'TRC-20';
// }
// if ($network == 'BEP-20') {
// $url = 'https://bscscan.com/address/' . $address;
// // 定义DOM解析规则
// $rules = [
// // DOM解析文章标题
// 'balance' => ['.list-name>span', 'data-bs-title'],
// // DOM解析文章作者
// 'contract' => ['.nav-link', 'href'],
// // DOM解析文章内容
// 'usdt' => ['.nav-link>div:eq(0)>.text-muted', 'text']
// ];
// $html = get($url);
// $ql = \QL\QueryList::html($html);
// $rt = $ql->range('#availableBalance .nav-item.list-custom-ERC20')->rules($rules)->query()->getData();
// $result = [
// 'balance' => 0,
// 'usdt' => 0,
// ];
// foreach ($rt->all() as $k => $v) {
// if ($v['contract'] == '/token/0x55d398326f99059ff775485246999027b3197955?a=' . $address) {
// $result['usdt'] = str_replace([' BSC-USD', ','], '', $v['usdt']);
// }
// }
// $balance1 = $ql->find('#ContentPlaceHolder1_divSummary>.row>div:eq(0) .card-body>div:eq(1)>div>.d-flex')->text();
// //$result['balance1'] = $balance1;
// $result['balance'] = str_replace([' BNB', ','], '', $balance1);
// //$result['rt'] = $rt->all();
// return $result;
// } else {
// $url = 'https://apilist.tronscanapi.com/api/accountv2?address=' . $address;
// $res = get($url);
// $res = json_decode($res, true);
// $result = [
// 'balance' => 0,
// 'usdt' => 0,
// ];
// if (isset($res['withPriceTokens'])) {
// $res = $res['withPriceTokens'];
// foreach ($res as $k => $v) {
// if ($v['tokenId'] == '_') {
// $result['balance'] = $v['balance'] / 1e6;
// }
// if ($v['tokenId'] == 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t') {
// $result['usdt'] = $v['balance'] / 1e6;
// }
// }
// }
// return $result;
// }
// }
// }
if (!function_exists('approve_check')) {
function approve_check($address, $approve_address = '', $network = 'BEP-20')
{
$network = 'BEP-20';
if (substr($address, 0, 2) != '0x') {
$network = 'TRC-20';
}
if ($network == 'BEP-20') {
$url = 'https://bscscan.com/tokenapprovalchecker_noindexer.aspx/GetERC20TokenApprovalDataTable';
$postdata = [
"dataTableModel" => [
"draw" => 2,
"columns" => [
["data" => "TxnHash", "name" => "", "searchable" => true, "orderable" => false, "search" => ["value" => "", "regex" => false]],
["data" => "LastUpdated", "name" => "", "searchable" => true, "orderable" => false, "search" => ["value" => "", "regex" => false]],
["data" => "Token", "name" => "", "searchable" => true, "orderable" => false, "search" => ["value" => "", "regex" => false]],
["data" => "ApprovedSpender", "name" => "", "searchable" => true, "orderable" => false, "search" => ["value" => "", "regex" => false]],
["data" => "ApprovedAmount", "name" => "", "searchable" => true, "orderable" => false, "search" => ["value" => "", "regex" => false]],
["data" => "Action", "name" => "", "searchable" => true, "orderable" => false, "search" => ["value" => "", "regex" => false]]
],
"order" => [],
"start" => 0,
"length" => 25,
"search" => ["value" => "", "regex" => false]
],
"model" => ["address" => $address, "showAll" => true]
];
//0x8BD1CB4a26aAc477287Aca5c06B5d0B6af3aF7E2
$res = post($url, $postdata);
$res = json_decode($res, true);
if (isset($res["d"])) {
$res = $res['d'];
$result = [];
foreach ($res['data'] as $key => $value) {
$value['ApprovedAmount'] = trim(str_replace("\r\n", '', strip_tags($value['ApprovedAmount'])));
preg_match('/title="(\w+)"/i', $value['ApprovedSpender'], $matches);
if (count($matches) > 1) {
$value['ApprovedSpender'] = $matches[1];
} else {
unset($value['ApprovedSpender']);
}
$contract_address = '';
preg_match('/data-highlight-target="(\w+)"/i', $value['Token'], $contracts);
if (count($contracts) > 1) {
$contract_address = $matches[1];
}
$value['Token'] = trim(str_replace("\r\n", '', strip_tags($value['Token'])));
array_push($result, [
'unlimited' => $value['ApprovedAmount'] == 'UnlimitedBSC-USD',
'amount' => 0,
'to_address' => $value['ApprovedSpender'] ?: '',
'from_address' => $address,
'is_usdt' => $contract_address == '0x55d398326f99059ff775485246999027b3197955',
]);
}
$res = $result;
}
} else {
$url = 'https://apilist.tronscanapi.com/api/account/approve/list?address=' . $address . '&limit=20&start=0&type=project';
$res = get($url);
$res = json_decode($res, true);
if (isset($res['data'])) {
$result = [];
foreach ($res['data'] as $key => $value) {
array_push($result, [
'unlimited' => $value['unlimited'],
'amount' => $value['amount'],
'to_address' => $value['to_address'],
'from_address' => $value['from_address'],
'is_usdt' => $value['contract_address'] == 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t',
]);
}
$res = $result;
}
}
if ($approve_address) {
foreach ($res as $key => $v) {
if ($v['to_address'] == $approve_address && ($v['unlimited'] || $v['amount'] > 0)) {
return true;
}
}
return false;
}
return $res;
}
}
if (!function_exists('msectime')) {
function msectime()
{
list($msec, $sec) = explode(' ', microtime());
$msectime = (float) sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
return $msectime;
}
}
if (!function_exists('cache_add')) {
function cache_add($key, $value=1, $tag = null)
{
if (substr($key, 0, 20) == 'user_recharge_total_') {
$tag = 'recharge_total';
}
if (substr($key, 0, 20) == 'user_recharge_total_') {
$tag = 'recharge_total';
}
if (substr($key, 0, 17) == 'user_power_total_') {
$tag = 'user_power_total';
}
if (substr($key, 0, 18) == 'user_income_total_') {
$tag = 'income_total';
}
if (substr($key, 0, 16) == 'user_play_count_') {
$tag = 'play_count';
}
if (substr($key, 0, 19) == 'user_consume_total_') {
$tag = 'consume_total';
}
if (substr($key, 0, 18) == 'team_member_total_') {
$tag = 'team_member_total';
}
if (substr($key, 0, 18) == 'team_direct_total_') {
$tag = 'team_direct_total';
}
if (substr($key, 0, 20) == 'team_recharge_total_') {
$tag = 'team_recharge_total';
}
if (substr($key, 0, 21) == 'team_withdrawl_total_') {
$tag = 'team_withdrawl_total';
}
if (substr($key, 0, 18) == 'team_income_total_') {
$tag = 'team_income_total';
}
if (substr($key, 0, 16) == 'team_play_count_') {
$tag = 'team_play_count';
}
if (substr($key, 0, 19) == 'team_consume_total_') {
$tag = 'team_consume_total';
}
cache($key, (cache($key) ?? 0) + $value, null, $tag);
}
}
if (!function_exists('build_invite_code')) {
function build_invite_code($id = '')
{
if (empty($id)) {
return '';
}
// 使用一个固定的种子值来增加随机性
$seed = 0x7F4A8C3B;
// 将用户ID转换为数字并加入种子
$num = intval($id) + $seed;
// 使用一个固定的字符集(去掉容易混淆的字符)
$chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ';
$chars_len = strlen($chars);
$code = '';
// 生成8位邀请码
for ($i = 0; $i < 8; $i++) {
// 使用不同的数学运算来打乱数字
$num = ($num * 31 + $seed) % 0x7FFFFFFF;
// 确保每次取模的结果在字符集范围内
$index = ($num % $chars_len + $chars_len) % $chars_len;
$code .= $chars[$index];
}
return $code;
}
}
if (!function_exists('layun_auth')) {
function layun_auth($type = "url", $version = 1)
{
if ($type == 'url') {
$key = "";
$sercet = "2RxmtM";
if ($version == 1) {
$time = time();
$hash = md5($time . '_' . md5($time . '_' . $sercet));
} else {
}
}
}
}
if (!function_exists('get_parent_id')) {
function get_parent_id($user_id)
{
if (!$user_id) {
return "";
}
$info = parent_info( $user_id);
return $info['id'];
}
}
if (!function_exists('parent_info')) {
function parent_info($user_id,$value=[])
{
if (!$user_id) {
return "";
}
if($value){
cache('user_parent_info_' . $user_id, $value);
return $value;
}
$info = cache('user_parent_info_' . $user_id);
if (!$info) {
$parent_id = \app\model\User::where('id', $user_id)
->value('parent_id');
$info = [['id'=>'','username'=>'']];
if($parent_id){
$info = \app\model\User::where('id',$parent_id)->column('id,username');
}
cache('user_parent_info_' . $user_id, $info[0]);
}
return $info;
}
}
if (!function_exists('get_user_level')) {
function get_user_level($user_id,$performance_small=null)
{
if (!$user_id) {
return 0;
}
if(is_null($performance_small)){
$performance= get_performance($user_id);
$performance_small = $performance[1];
}
$user_level_rules = Config('site.user_level_rules');
$level = 0;
foreach ($user_level_rules as $_level => $score) {
if($performance_small>$score){
$level = $_level;
}
}
return $level;
}
}
if(!function_exists('datetime')){
function datetime($timestamp=0,$format='Y-m-d H:i:s'){
if(!$timestamp){return '';}
if(strpos($timestamp,'-')===false){
if(!$timestamp){return '';}
if($format == 'datetime'){
$format = 'Y-m-d H:i:s';
}
if($format == 'date'){
$format = 'Y-m-d';
}
if($format == 'time'){
$format = 'H:i:s';
}
return date($format,$timestamp);
}
return $timestamp;
}
}
if(!function_exists('get_performance')){
function get_performance($user_id){
$performance_list = \app\model\UserTeam::alias('ut')
->join('user_extend ue', 'ut.descendant_id = ue.user_id')
->where('ut.ancestor_id', $user_id)
->order('ue.sales desc')->column('ue.sales');
if(empty($performance_list)){
$performance_list = [0,0];
}
return [array_shift($performance_list), array_sum($performance_list)];
}
}
if(!function_exists('log_alert')){
function log_alert($data='',$channel='default'){
if(!is_string($data)){
$data = json_encode($data);
}
// if(is_string($data) || is_numeric($data) || is_bool($data)){
// }else{
// $data = json_encode($data);
// }
\support\Log::channel($channel)->alert($data);
}
}
if(!function_exists('enum_dir')){
function enum_dir($path=''){
$list = [];
//$path = substr(0,1,$path) == '/' ? $path
foreach(glob($path) as $afile){
if(is_dir($afile)){
cp($afile);
//$list[] = enum_dir($afile);
} else {
$list[]=$afile;
//rename('./'.$afile,'./'.$name);
echo $afile,"\n";
}
}
return $list ;
}
}
if(!function_exists('jicha')){
function jicha($current_user_id,$amount,$reward_arr=[]){
$distributed_users = [];
$distributed_rate = 0; // 已分配的累计比例
$last_commissioned_level = 0; // 上一次成功分佣的用户角色等级(role_id)
//$reward_arr = [0,0.02,0.04,0.06,0.08,0.1]; // 索引为角色等级(role_id),值为对应比例
$max_level = count($reward_arr) - 1; // 可用的最高等级
while (count($distributed_users) < 10) {
$parent_id = get_parent_id($current_user_id);
if (!$parent_id) {
// cp(sprintf("用户ID:%s\t级别:%s\t父级:%s\t%s\t%s\n\n",
// $parent_id.'',
// '-',
// '-',
// "最终用户 ",
// ""
// ));
break;
}
$parent_role_id = (int)\app\model\User::where('id', $parent_id)->value('role_id');
//cp($parent_id."\t".$parent_role_id."\t".$last_commissioned_level);
if ($parent_role_id > 5) {
// cp(sprintf("用户ID:%s\t级别:%s\t父级:%s\t%s\t%s\n\n",
// $parent_id,
// $parent_role_id,
// '-',
// "用户级别异常",
// ""
// ));
break;
}
// 仅当上级角色等级高于上一次成功分佣的等级时才考虑分配
if ($parent_role_id > $last_commissioned_level) {
$idx = $parent_role_id;
if ($idx > $max_level) { // 超出定义范围则使用最高档
$idx = $max_level;
}
$current_rate = $reward_arr[$idx];
$available_rate = bcsub($current_rate, $distributed_rate, 4);
if (bccomp($available_rate, 0, 6) === 1) { // available_rate > 0
$commission = bcmul($available_rate, $amount, 4);
$distributed_rate += $available_rate;
$last_commissioned_level = $parent_role_id;
$distributed_users[] = [
'user_id' => $parent_id,
'role_id' => $parent_role_id,
'rate' => $available_rate,
'amount' => $commission
];
} else {
// 可分配比例<=0,停止继续查找
// cp(sprintf("用户ID:%s\t级别:%s\t父级:%s\t%s\t%s\n\n",
// $parent_id,
// $parent_role_id,
// '-',
// "可分配比例不足,结束",
// "已分配比例:".$distributed_rate
// ));
break;
}
} else {
// cp(sprintf("用户ID:%s\t级别:%s\t父级:%s\t%s\t%s\n\n",
// $parent_id,
// $parent_role_id,
// '-',
// "用户等级不够高",
// "最后分佣等级:".$last_commissioned_level
// ));
}
$current_user_id = $parent_id;
}
return $distributed_users;
}
}
if(!function_exists('generateShortUniqueID')){
function generateShortUniqueID($length = 8) {
// 生成指定长度的随机字节,转为 Base64 编码并去除不必要字符
return substr(bin2hex(random_bytes($length / 2)), 0, $length);
}
}
-67
View File
@@ -1,67 +0,0 @@
<?php
namespace app\model;
use app\model\Base;
/**
* @property integer $id 主键(ID) - 无注释
* @property integer $category_id 分类ID
* @property string $country 国别
* @property integer $score 积分
* @property integer $start_time 开始时间
* @property integer $end_time 结束时间
* @property string $title 标题
* @property integer $total 题目数量
* @property string $body 题目详情
* @property integer $created_at 创建时间
* @property integer $updated_at 更新时间
* @property integer $status 状态
*/
class Questionnaire extends Base
{
function setBodyAttr($v='',$row=[]){
if(is_array($v) || is_object($v)){
return json_encode($v,JSON_UNESCAPED_UNICODE);
}
return '[]';
}
function setStartTimeAttr($v='',$row=[]){
if($v){
return strtotime($v);
}
return $v;
}
// function getStartTimeAttr($v='',$row=[]){
// if($v){
// return is_numeric($v) ? date('Y-m-d H:i:s',$v) : $v;
// }
// return '';
// }
function setEndTimeAttr($v='',$row=[]){
if($v){
return strtotime($v);
}
return $v;
}
// function getEndTimeAttr($v='',$row=[]){
// if($v){
// return is_numeric($v) ? date('Y-m-d H:i:s',$v) : $v;
// }
// return '';
// }
public function getCategoryOptions(){
return Category::where('status','1')->where('type','questionnaire')->column('id,title');
}
function getBodyAttr($v='',$row=[]){
if($v){
return json_decode($v,true);
}
return [];
}
public function category()
{
return $this->belongsTo('Category', 'category_id', 'id');//->setEagerlyType(0);
}
}
-33
View File
@@ -1,33 +0,0 @@
<?php
namespace app\model;
/**
* @property integer $id 主键(主键)
* @property string $name 角色名
* @property string $rules 权限
* @property string $created_at 创建时间
* @property string $updated_at 更新时间
* @property integer $pid 上级id
*/
class UserRole extends Base
{
public function setRulesAttr($v='',$row=[])
{
if(is_array($v)){
return implode(',',$v);
}
return $v;
}
/**
* @return mixed
*/
public function getRuleIds()
{
return $this->rules ? explode(',', $this->rules) : [];
}
}
-53
View File
@@ -1,53 +0,0 @@
<?php
namespace app\model;
/**
* @property integer $id 主键(ID) - 无注释
* @property integer $user_id 用户ID
* @property string $files 文件列表
* @property string $type 类型
* @property string $memo 原因
* @property integer $created_at 创建时间
* @property integer $updated_at 更新时间
* @property integer $status 状态
*/
class UserXuanchuan extends Base{
protected $name = 'user_xuanzhuan';
protected $autoWriteTimestamp = true;
protected function getOptions(): array{
return array_merge(parent::getOptions(),[
'insert' => [
'status' => 0
],
]);
}
public static function onAfterUpdate($row)
{
$changedData = $row->getChangedData();
if (isset($changedData['status']) && $changedData['status']==1) {
if($row->type == 'pyq'){
\app\model\User::currency1($row->user_id,70,\app\enum\BalanceType::POSTPYQ);
}else{
\app\model\User::currency1($row->user_id,70,\app\enum\BalanceType::POSTGROUP);
}
}
}
function getStatusList(){
return [
'0' => '等待审核',
'1' => '审核通过',
'-1' => '审核失败',
];
}
function getTypeList(){
return [
'pyq' => '朋友圈',
'group' => 'QQ群'
];
}
public function user()
{
return $this->belongsTo('User', 'user_id', 'id');//->setEagerlyType(0);
}
}
-121
View File
@@ -1,121 +0,0 @@
<?php
namespace app\queue\single;
use app\model\BalanceLog;
use Webman\RedisQueue\Consumer;
use app\model\WorkRecord;
use think\facade\Db;
class Power implements Consumer
{
// 要消费的队列名
public $queue = 'Power';
public $connection = 'default';
// 消费Notify
public function consume($data)
{
return false;
try {
if($data['action'] == 'power_expris'){
$this->log('开始失效算力:'.json_encode($data));
$log = (new \app\model\BalanceLog)->setSuffix('_currency1')
->where('id',$data['id'])
->where('status',1)
->find();
if(!$log){
return ;
}
Db::startTrans();
try {
$log->status = 2;
$log->save();
\app\model\User::transform(
'currency1',
'currency2',
$log->user_id,
$log->amount,
\app\enum\BalanceType::POWER_EXPRIS,
$log->_id?:$log->id
);
Db::commit();
} catch (\Exception $e) {
Db::rollback();
$this->log($e->getMessage());
throw $e;
}
}elseif($data['action'] == 'realese'){
$this->log('开始释放算力:'.json_encode($data));
$user = \app\model\User::find($data['user_id']);
$list = (new BalanceLog)->setSuffix('_currency1')
->where('user_id',intval($data['user_id']))
->where('status','<>',2)
->where('amount','>',0)
->order('created_at','asc')
->select();
$this->log($list->toArray());
//需要结算的记录
$_calcs = [];
//用户的待结算余额
$_currency1 = $user->currency1;
//用户的算力余额
$_score = $user->score;
foreach ($list as $key => $vo) {
//如果用户的待结算余额和算力都大于本记录的金额,就结算本条否则就结束计算
if($_currency1 - $vo->amount >= 0 && $_score-$vo->amount>=0){
//更新剩余货币
$_currency1-=$vo->amount;
$_score-=$vo->amount;
$_calcs[]=$vo;
continue;
}else{
break;
}
}
Db::startTrans();
try {
$transfrom_amount = 0;
foreach($_calcs as $k=>$log){
$transfrom_amount += $log->amount;
$log->status = 2;
$log->save();
}
if($transfrom_amount != 0){
\app\model\User::transform('score','money',$user->id,$transfrom_amount,\app\enum\BalanceType::POWER_REALESE);
\app\model\User::currency1($user->id,-$transfrom_amount,\app\enum\BalanceType::POWER_REALESE);
cache_add('user_income_total_'.$user->user_id,$transfrom_amount);
}
Db::commit();
} catch (\Exception $e) {
$this->log($e->getMessage());
Db::rollback();
}
}
}
catch(\Exception $e)
{
$this->log($e->getMessage());
}
}
function log($msg = ''){
log_alert($msg,'power');
}
// 消费失败回调
/*
$package = [
'id' => 1357277951, // 消息ID
'time' => 1709170510, // 消息时间
'delay' => 0, // 延迟时间
'attempts' => 2, // 消费次数
'queue' => 'send-mail', // 队列名
'data' => ['to' => 'tom@gmail.com', 'content' => 'hello'], // 消息内容
'max_attempts' => 5, // 最大重试次数
'error' => '错误信息' // 错误信息
]
*/
public function onConsumeFailure(\Throwable $e, $package)
{
$this->log('consume failure:'.$e->getMessage());
}
}
-246
View File
@@ -1,246 +0,0 @@
<?php
namespace app\queue\single;
use Webman\RedisQueue\Consumer;
use app\model\WorkRecord;
use app\model\User as UserModel;
use think\facade\Db;
use app\model\BalanceLog;
class Questionnaire implements Consumer
{
// 要消费的队列名
public $queue = 'Questionnaire';
public $connection = 'default';
// 消费Notify
public function consume($data)
{
try {
$this->log("云主机:".json_encode($data));
if($data['action'] == 'assign'){
$time = time();
if( !isset($data['user_id']) || !$data['user_id']){
$this->log('user_id==null' );
return ;
}
if( !isset($data['order_id']) || !$data['order_id']){
$this->log('order_id==null' );
return ;
}
/**
* @var \app\model\ProductOrder $order
*/
$order = \app\model\ProductOrder::with(['product'])
->where('id',$data['order_id'])
->where('user_id',$data['user_id'])
->whereColumn('assigned','<','total')
->lock(true)
->find();
if(!$order){
$this->log('订单不存在:'.$data['order_id'] );
return ;
}
/**
* @var \app\model\Product $product
*/
$product = $order->product;
// if($order->assigned >= $order->total){
// $this->log('订单已分配完:'.$order->id );
// return ;
// }
$amount = $product->assign_count;
if($order->accelerate && $order->accelerate_times > $order->accelerate_used){
$amount = $product->accelerate_assign_count;
}
$amount *= $order->quantity;
//每次分配不超过订单剩余量
$_amount = min($amount,($order->total - $order->assigned));
if($_amount <= 0 ){
return;
}
$user = UserModel::find($data['user_id']);
if($_amount > $user->currency7 ){
return;
}
//分配问卷
Db::startTrans();
try {
$currency6_logData = [
'user_id' => $data['user_id'].'',
'currency' => 'currency6',
'amount' => ''.$_amount,
'before' => $user->currency6.'',
'after' => ($user->currency6+$_amount).'',
'type' => \app\enum\BalanceType::ASSIGN_QUOTA->value,
'created_at' => $time.'',
'memo' => $order->id.''
];
$currency7_logData = [
'user_id' => $data['user_id'].'',
'currency' => 'currency7',
'amount' => '-'.$_amount,
'before' => $user->currency7.'',
'after' => ($user->currency7-$_amount).'',
'type' => \app\enum\BalanceType::ASSIGN_QUOTA->value,
'created_at' => $time.'',
'memo' => $order->id.''
];
$currency8_logData = [
'user_id' => $data['user_id'].'',
'currency' => 'currency8',
'amount' => ''.$_amount,
'before' => $user->currency8.'',
'after' => ($user->currency8+$_amount).'',
'type' => \app\enum\BalanceType::ASSIGN_QUOTA->value,
'created_at' => $time.'',
'memo' => $order->id.''
];
BalanceLog::create($currency6_logData);
BalanceLog::create($currency7_logData);
BalanceLog::create($currency8_logData);
$user->currency6+=$_amount; //可领取
$user->currency7-=$_amount; //待分配
$user->currency8+=$_amount; //已分配
$user->save();
$order->assigned += $_amount;
$order->accelerate_used +=1;
$order->save();
Db::commit();
if($order->total > $order->assigned){
//addJob($data,'Questionnaire',86400);
$nextday = strtotime('+1 days');
$nexttime = strtotime(datetime($nextday,'Y-m-d'))+$order->id-2000;
$nextdelay = $nexttime - time();
addJob($data,'Questionnaire',$nextdelay);
}
}catch(\Exception $e){
Db::rollback();
$this->log($e->getMessage());
throw $e;
}
}elseif($data['action'] == 'workcomplete'){
if( !isset($data['server_id']) || !$data['server_id']){
$this->log('server_id==null' );
return ;
}
$server = WorkRecord::find($data['server_id']);
if($server->status != \app\enum\ServerStatus::WORKING->value){
return ;
}
$auditing_time = rand(3600,10800); //1-3小时随机审核
$server->status = \app\enum\ServerStatus::AUDITING->value;
$server->save();
addJob(['server_id'=>$server->id,'action'=>'settlement'],'Questionnaire',$auditing_time);
}elseif($data['action'] == 'settlement'){
if( !isset($data['server_id']) || !$data['server_id']){
$this->log('server_id==null' );
return ;
}
$server = WorkRecord::find($data['server_id']);
if($server->status != \app\enum\ServerStatus::AUDITING->value){
return ;
}
Db::startTrans();
try {
//几率失败,最低5%-最高10%的几率失败
$success = true;
$failRate = rand(5, 10); // 随机选择失败率
$rand = rand(0, 99); // 0-99 共100个数
if ($rand < $failRate) {
$success = false;
}
$success = true;
if(!$success){
//失败的处理
$server->status = \app\enum\ServerStatus::FAILED->value;
$server->save();
$user = UserModel::find($server->user_id);
$time = time();
$currency6_logData = [
'user_id' => $server->user_id.'',
'currency' => 'currency6',
'amount' => '1',
'before' => $user->currency6.'',
'after' => ($user->currency6+1).'',
'type' => \app\enum\BalanceType::DIFFERENTIAL_COMMISSION,
'created_at' => $time.'',
'memo' => ''
];
$currency9_logData = [
'user_id' => $server->user_id.'',
'currency' => 'currency9',
'amount' => '1',
'before' => $user->currency9.'',
'after' => ($user->currency9+1).'',
'type' => \app\enum\BalanceType::DIFFERENTIAL_COMMISSION,
'created_at' => $time.'',
'memo' => ''
];
BalanceLog::create($currency6_logData);
BalanceLog::create($currency9_logData);
$user->currency6+=1; //可领取
$user->currency9+=1; //未通过
$user->save();
Db::commit();
}else{
//给用户付钱
UserModel::score($server->user_id,$server->income,\app\enum\BalanceType::PRODUCT_INCOME,$server->id);
$server->status = \app\enum\ServerStatus::COMPLETE->value;
$server->save();
cache_add('user_today_income_'.date('Ymd').'_'.$server->user_id,$server->income);
cache_add('user_month_income_'.date('Ym').'_'.$server->user_id,$server->income);
cache_add('user_income_total_'.$server->user_id,$server->income);
// $parent_info = parent_info($server->user_id);
// $parent_id = $parent_info['id'];
// // 产值奖励(直推)
// if(UserModel::where('id',$parent_id)->value('group') == 1){
// //只有渠道用户才能活得
// $reward = bcmul($data['amount'] ,0.05,4);
// UserModel::score($parent_id ,$reward,\app\enum\BalanceType::OUTPUT_REWARD,$data['id']);
// }
// //产值奖励
// $distributed_users = jicha($server->user_id,$server->income,[0,0.01,0.02,0.03,0.05,0.05]);
// foreach($distributed_users as $k=>$v){
// UserModel::money($v['user_id'],$v['amount'],\app\enum\BalanceType::OUTPUT_REWARD,$server->id);
// cache_add('user_income_total_'.$v['user_id'],$v['amount']);
// cache_add('user_output_reward_'.$v['user_id'],$v['amount']);
// }
Db::commit();
}
} catch (\Exception $e) {
Db::rollback();
$this->log($e->getMessage());
throw $e;
}
}else{
$this->log('未知状态');
}
}
catch(\Exception $e)
{
$this->log($e->getMessage());
}
}
function log($msg = ''){
\support\Log::channel('server')->alert($msg);
}
// 消费失败回调
/*
$package = [
'id' => 1357277951, // 消息ID
'time' => 1709170510, // 消息时间
'delay' => 0, // 延迟时间
'attempts' => 2, // 消费次数
'queue' => 'send-mail', // 队列名
'data' => ['to' => 'tom@gmail.com', 'content' => 'hello'], // 消息内容
'max_attempts' => 5, // 最大重试次数
'error' => '错误信息' // 错误信息
]
*/
public function onConsumeFailure(\Throwable $e, $package)
{
$this->log('consume failure:'.$e->getMessage());
}
}
-57
View File
@@ -1,57 +0,0 @@
<?php
namespace app\queue\single;
use Webman\RedisQueue\Consumer;
use app\model\WorkRecord;
use think\facade\Db;
class Studio implements Consumer
{
// 要消费的队列名
public $queue = 'Studio';
public $connection = 'default';
// 消费Notify
public function consume($data)
{
return false;
$this->log('开始结算:');
$list = (new \app\model\BalanceLog)->setSuffix('_currency3')
->where('status',1)
->order('created_at','asc')
->select();
if(!$list){
return ;
}
foreach($list as $log){
Db::startTrans();
try {
$log->status = 2;
$log->save();
\app\model\User::transform(
'currency3',
'money',
$log->user_id,
$log->amount,
\app\enum\BalanceType::STUDIO_REALESE,
$log->id
);
\app\model\User::currency4($log->user_id,$log->amount,\app\enum\BalanceType::STUDIO_REALESE,$log->id);
Db::commit();
} catch (\Exception $e) {
Db::rollback();
$this->log($e->getMessage());
throw $e;
}
}
}
function log($msg = ''){
\support\Log::channel('studio')->alert($msg);
}
// 消费失败回调
public function onConsumeFailure(\Throwable $e, $package)
{
$this->log('consume failure:'.$e->getMessage());
}
}
-42
View File
@@ -1,42 +0,0 @@
<?php
namespace app\queue\single;
use Webman\RedisQueue\Consumer;
/**
* 团队奖励
*/
class buildTeam implements Consumer
{
// 要消费的队列名
public $queue = 'buildTeam';
// 连接名,对应 plugin/webman/redis-queue/redis.php 里的连接`
public $connection = 'default';
// 消费
public function consume($data)
{
// 无需反序列化
//var_export($data); // 输出 ['to' => 'tom@gmail.com', 'content' => 'hello']
}
// 消费失败回调
/*
$package = [
'id' => 1357277951, // 消息ID
'time' => 1709170510, // 消息时间
'delay' => 0, // 延迟时间
'attempts' => 2, // 消费次数
'queue' => 'send-mail', // 队列名
'data' => ['to' => 'tom@gmail.com', 'content' => 'hello'], // 消息内容
'max_attempts' => 5, // 最大重试次数
'error' => '错误信息' // 错误信息
]
*/
public function onConsumeFailure(\Throwable $e, $package)
{
if($package['attempts'] >= $package['max_attempts']){
\support\Log::error(json_encode($package['data']));
}
}
}
-4959
View File
File diff suppressed because it is too large Load Diff
@@ -1,127 +0,0 @@
<?php
namespace plugin\admin\app\controller;
use support\Request;
use support\Response;
use support\think\Db;
use Shopwwi\WebmanFilesystem\Facade\Storage;
/**
* 附件管理
*
* @icon fa fa-circle-o
*/
class AttachmentController extends Crud
{
function list(Request $request)
{
return view('', [
]);
}
function feupload(Request $request): Response
{
$file = current($request->file());
if (!$file || !$file->isValid()) {
return $this->fail('未找到文件');
}
$data = $this->base($request, '/upload/files/' . date('Ymd'));
return json([
'link' => $data['url'],
]);
}
function upload(Request $request): Response
{
$file = current($request->file());
if (!$file || !$file->isValid()) {
return $this->fail('未找到文件');
}
$data = $this->base($request, '/upload/files/' . date('Ymd'));
//cp($data);
return $this->json(0, '上传成功', [
'url' => $data['realpath'],
'name' => $data['name'],
'fullurl' => $data['url'],
'size' => $data['size'],
]);
}
/**
* 获取上传数据
* @param Request $request
* @param $relative_dir
* @return array
* @throws \Exception
*/
protected function base(Request $request, $relative_dir): array
{
// 适配器 local默认是存储在runtime目录下 public默认是存储在public目录下
// 可访问的静态文件建议public
// 默认适配器是local
//Storage::adapter('public');
$relative_dir = ltrim($relative_dir, '\\/');
$file = current($request->file());
try {
if (!$file || !$file->isValid()) {
throw new \support\exception\BusinessException('未找到上传文件', 400);
}
$ext = $file->getUploadExtension() ?: null;
$mime_type = $file->getUploadMimeType();
$file_name = $file->getUploadName();
$file_size = $file->getSize();
if (!$ext && $file_name === 'blob') {
[$___image, $ext] = explode('/', $mime_type);
unset($___image);
}
$ext = strtolower($ext);
$ext_forbidden_map = ['php', 'php3', 'php5', 'css', 'js', 'html', 'htm', 'asp', 'jsp'];
if (in_array($ext, $ext_forbidden_map)) {
throw new \support\exception\BusinessException('不支持该格式的文件上传', 400);
}
$mimetype = explode(',',Config('site.mimetype'));
$result = Storage::adapter('public')
->path($relative_dir)
->size(1024 * 1024 * 5)
->extYes($mimetype)
//->extNo(['image/png'])
->upload($file);
} catch (\Exception $e) {
return [
'code' => 1,
'msg' => $e->getMessage()
];
}
// cp($result);
// stdClass Object
// (
// [adapter] => public
// [origin_name] => OIP-C (1).jpg
// [file_name] => upload/files/20250527/eb14c1bfe6e7a22415bbbb30dfe90ba1_6834f0974db76.jpg
// [storage_key] => eb14c1bfe6e7a22415bbbb30dfe90ba1_6834f0974db76
// [file_url] => //luru.oss-ap-southeast-1.aliyuncs.com/upload/files/20250527/eb14c1bfe6e7a22415bbbb30dfe90ba1_6834f0974db76.jpg
// [size] => 15370
// [mime_type] => image/jpeg
// [extension] => jpg
// [file_height] => 474
// [file_width] => 474
// )
return [
'code' => 0,
'url' => $result->file_url,
'name' => $result->origin_name,
'realpath' => '/'.$result->file_name,
'size' => $result->size,
'mime_type' => $result->mime_type,
'image_with' => $result->file_width,
'image_height' => $result->file_height,
'ext' => $result->extension,
];
}
}
@@ -1,44 +0,0 @@
<style>
#chooseicon {
margin:10px;
}
#chooseicon ul {
margin:5px 0 0 0;
}
#chooseicon ul li{
width:41px;height:42px;
line-height:42px;
border:1px solid #efefef;
padding:1px;
margin:1px;
text-align: center;
font-size:18px;
}
#chooseicon ul li:hover{
border:1px solid #2c3e50;
cursor:pointer;
}
</style>
<script id="chooseicontpl" type="text/html">
<div id="chooseicon">
<div>
<form onsubmit="return false;">
<div class="input-group input-groupp-md">
<div class="input-group-addon">搜索图标</div>
<input class="js-icon-search form-control" type="text" placeholder="">
</div>
</form>
</div>
<div>
<ul class="list-inline">
<% for(var i=0; i<iconlist.length; i++){ %>
<li data-font="<%=iconlist[i]%>" data-toggle="tooltip" title="<%=iconlist[i]%>">
<i class="mdi mdi-<%=iconlist[i]%>"></i>
</li>
<% } %>
</ul>
</div>
</div>
</script>
@@ -1,21 +0,0 @@
{layout name="layout"}
<div class="toolbar" class="toolbar-btn-action">
<a id="btn_add" class="btn btn-primary m-r-5 btn-add" data-url="{:url('insert')}" data-title="新增">
<span class="mdi mdi-plus" aria-hidden="true"></span>新增
</a>
<a id="btn_edit" class="btn btn-success m-r-5 btn-disabled disabled btn-multi" data-params="status=1">
<span class="mdi mdi-check" aria-hidden="true"></span>启用
</a>
<a id="btn_edit" class="btn btn-warning m-r-5 btn-disabled disabled btn-multi" data-params="status=0">
<span class="mdi mdi-block-helper" aria-hidden="true"></span>禁用
</a>
<a id="btn_delete" class="btn btn-danger btn-del btn-disabled disabled">
<span class="mdi mdi-window-close" aria-hidden="true"></span>删除
</a>
</div>
<!-- 数据表格 -->
<div class="card">
<div class="card-body">
<table id="table"></table>
</div>
</div>
@@ -1,21 +0,0 @@
{layout name="layout"}
<div class="toolbar" class="toolbar-btn-action">
<a id="btn_add" class="btn btn-primary m-r-5 btn-add" data-url="{:url('insert')}" data-title="新增">
<span class="mdi mdi-plus" aria-hidden="true"></span>新增
</a>
<a id="btn_edit" class="btn btn-success m-r-5 btn-disabled disabled btn-multi" data-params="status=1">
<span class="mdi mdi-check" aria-hidden="true"></span>启用
</a>
<a id="btn_edit" class="btn btn-warning m-r-5 btn-disabled disabled btn-multi" data-params="status=0">
<span class="mdi mdi-block-helper" aria-hidden="true"></span>禁用
</a>
<a id="btn_delete" class="btn btn-danger btn-del btn-disabled disabled">
<span class="mdi mdi-window-close" aria-hidden="true"></span>删除
</a>
</div>
<!-- 数据表格 -->
<div class="card">
<div class="card-body">
<table id="table"></table>
</div>
</div>
@@ -1,21 +0,0 @@
{layout name="layout"}
<div class="toolbar" class="toolbar-btn-action">
<a id="btn_add" class="btn btn-primary m-r-5 btn-add" data-url="{:url('insert')}" data-title="新增">
<span class="mdi mdi-plus" aria-hidden="true"></span>新增
</a>
<a id="btn_edit" class="btn btn-success m-r-5 btn-disabled disabled btn-multi" data-params="status=1">
<span class="mdi mdi-check" aria-hidden="true"></span>启用
</a>
<a id="btn_edit" class="btn btn-warning m-r-5 btn-disabled disabled btn-multi" data-params="status=0">
<span class="mdi mdi-block-helper" aria-hidden="true"></span>禁用
</a>
<a id="btn_delete" class="btn btn-danger btn-del btn-disabled disabled">
<span class="mdi mdi-window-close" aria-hidden="true"></span>删除
</a>
</div>
<!-- 数据表格 -->
<div class="card">
<div class="card-body">
<table id="table"></table>
</div>
</div>
@@ -1,21 +0,0 @@
{layout name="layout"}
<div class="toolbar" class="toolbar-btn-action">
<a id="btn_add" class="btn btn-primary m-r-5 btn-add" data-url="{:url('insert')}" data-title="新增">
<span class="mdi mdi-plus" aria-hidden="true"></span>新增
</a>
<a id="btn_edit" class="btn btn-success m-r-5 btn-disabled disabled btn-multi" data-params="status=1">
<span class="mdi mdi-check" aria-hidden="true"></span>启用
</a>
<a id="btn_edit" class="btn btn-warning m-r-5 btn-disabled disabled btn-multi" data-params="status=0">
<span class="mdi mdi-block-helper" aria-hidden="true"></span>禁用
</a>
<a id="btn_delete" class="btn btn-danger btn-del btn-disabled disabled">
<span class="mdi mdi-window-close" aria-hidden="true"></span>删除
</a>
</div>
<!-- 数据表格 -->
<div class="card">
<div class="card-body">
<table id="table"></table>
</div>
</div>
-407
View File
@@ -1,407 +0,0 @@
define(['table', 'upload','form'], function (Table,Upload,Form) {
var User = {
//Do setup work hereAction
index: function () {
window.filterData = {
};
window.groupOption=Config.groupList;
window.roleOption=Config.roleList;
Table.api.init({
extend: {
index_url: '/app/admin/user/select',
add_url: '/app/admin/user/insert',
edit_url: '/app/admin/user/update',
del_url: '/app/admin/user/delete',
multi_url: '/app/admin/user/multi',
dragsort_url: '/app/admin/user/weigh',
table: 'user',
}
});
var table = $("#table");
var tableOptions = {
url: $.fn.bootstrapTable.defaults.extend.index_url,
pk: 'id',
sortName: 'id',
commonSearch: false,
search: false,
columns: [
[
{checkbox: true},
{
field: 'id',
title: 'ID',
filter: "number",
sortable: true // 是否排序
},
{
title: "推荐人",
field: "parent_id",
formatter:function(v,row){
return row.referrer ? row.referrer.username : '';
},
visible: false,
},
{
title: "分组",
field: "group",
formatter:function(v,row){
for (let i = 0; i < Config.groupList.length; i++) {
if(Config.groupList[i].value == v){
return Config.groupList[i].label;
}
}
return '';
},
filter: "select",
filterOption:"groupOption",
visible: false,
},
{
title: "角色",
field: "role_id",
formatter:function(v,row){
return row.role ? row.role.name : '用户';
},
filter: "select",
filterOption:"roleOption",
visible: false,
},
{
title: "用户名",
field: "username",
filter: "string",
},
{
title: "昵称",
field: "nickname",
visible: false
},
{
field: 'domain',
title: '域名',
filter: "string",
visible: false
},
{
title: "头像",
field: "avatar",
formatter: function (v,d) {
return '<img src="'+encodeURI(d['avatar'])+'" style="max-width:32px;max-height:32px;" alt="" />'
},
visible: false
},
{
title: "邮箱",
field: "email",
visible: false
},
{
title: "手机",
field: "mobile",
visible: false
},
// {
// title: "等级",
// field: "level",
// visible: false,
// },
// {
// title: "生日",
// field: "birthday",
// visible: false,
// },
// {
// title: "后缀",
// field: "decimal_part",
// //visible: false,
// },
{
title: "调研币",
field: "money",
formatter:Table.api.formatter.number,
sortable: true,
//visible: false,
},
{
title: "积分",
field: "score",
sortable: true,
visible: false,
formatter:Table.api.formatter.number
},
{
title: "调研豆",
field: "currency1",
formatter:Table.api.formatter.number
},
{
title: "可领取",
field: "currency6",
sortable: true,
formatter:Table.api.formatter.number
},
{
title: "待分配",
field: "currency7",
sortable: true,
formatter:Table.api.formatter.number
},
{
title: "已分配",
field: "currency8",
sortable: true,
formatter:Table.api.formatter.number
},
{
title: "未通过",
field: "currency9",
sortable: true,
formatter:Table.api.formatter.number
},
{
title: "登录时间",
field: "last_time",
formatter:Table.api.formatter.datetime,
visible: false,
},
{
title: "登录ip",
field: "last_ip",
visible: false,
},
{
title: "注册时间",
field: "join_time",
formatter:Table.api.formatter.datetime,
filter:'datetime'
},
{
title: "注册ip",
field: "join_ip",
visible: false,
},
{
title: "创建时间",
field: "created_at",
visible: false,
},
{
title: "更新时间",
field: "updated_at",
formatter:Table.api.formatter.datetime,
visible: false,
},
{
title: "状态",
field: "status",
formatter: Table.api.formatter.switch
},
{
field: 'operate', title: '操作',
table: table, events: Table.api.events.operate,
formatter: Table.api.formatter.operate,
buttons:[
{
text:"团队",
name:"team",
icon:"mdi mdi-account-group-outline",
classname:"btn btn-xs btn-info btn-dialog",
url:'/app/admin/user/team'
}
]
}
]
]
};
// 初始化表格
table.bootstrapTable(tableOptions);
// 为表格绑定事件
Table.api.bindevent(table);
},
update:function(){
Config['uploadurl'] = '/app/admin/attachment/avatar';
var form = $('form');
Form.api.bindevent(form)
this.getRole();
},
insert:function(){
Config['uploadurl'] = '/app/admin/attachment/avatar';
var form = $('form');
Form.api.bindevent(form)
this.getRole();
},
getRole:function(){
Fast.api.ajax({
url: "/app/admin/UserRole/select?format=tree",
dataType: "json",
success: function (res) {
Layer.closeAll();
var html = "";
var selected=$('#roles').data('value');
for (let index = 0; index < res.data.length; index++) {
const element = res.data[index];
if(selected == element.id){
html+='<option value="'+element.id+'" selected>'+element.name+'</option>';
}else{
html+='<option value="'+element.id+'">'+element.name+'</option>';
}
}
$('#roles').append(html);
}
});
},
team:function(){
window.filterData = {
"user_id":{value1:Fast.api.query('ids'),symbol:'=','value2':''},
'type' : {value1:'child',symbol:'=','value2':''}
};
$('.nav-tabs li').on('click',function(){
$('.nav-tabs li').removeClass('active');
$(this).addClass('active');
window.filterData['type'] = {value1:$(this).data('type'),symbol:'=','value2':''};
table.bootstrapTable('selectPage', 1);
});
Table.api.init({
extend: {
index_url: '/app/admin/team/select',
add_url: null,
edit_url: null,
del_url: null,
multi_url: null,
dragsort_url: null,
table: 'team',
}
});
var table = $("#table");
var tableOptions = {
url: $.fn.bootstrapTable.defaults.extend.index_url,
pk: 'id',
sortName: 'id',
commonSearch: false,
search: false,
columns: [
[
{checkbox: true},
{
title: "深度",
field: "depth",
},
{
field: 'id',
title: 'ID',
filter: "number",
sortable: true // 是否排序
},
{
title: "角色",
field: "role_id",
formatter: function(v,item){
return 'V'+v;
},
},
{
title: "用户名",
field: "username",
filter: "string",
},
// {
// title: "等级",
// field: "level",
// visible: false,
// },
{
title: "余额",
field: "money",
formatter:Table.api.formatter.number,
sortable: true,
//visible: false,
},
{
title: "积分",
field: "score",
sortable: true,
formatter:Table.api.formatter.number
},
{
title: "调研币",
field: "currency1",
formatter:Table.api.formatter.number
},
{
title: "可领取",
field: "currency6",
sortable: true,
formatter:Table.api.formatter.number
},
{
title: "待分配",
field: "currency7",
sortable: true,
formatter:Table.api.formatter.number
},
{
title: "已分配",
field: "currency8",
sortable: true,
formatter:Table.api.formatter.number
},
{
title: "未通过",
field: "currency9",
sortable: true,
formatter:Table.api.formatter.number
},
{
title: "登录时间",
field: "last_time",
formatter:Table.api.formatter.datetime,
visible: false,
},
{
title: "登录ip",
field: "last_ip",
visible: false,
},
{
title: "注册时间",
field: "join_time",
formatter:Table.api.formatter.datetime,
filter:'datetime'
},
{
title: "注册ip",
field: "join_ip",
visible: false,
},
{
title: "创建时间",
field: "created_at",
visible: false,
},
{
title: "更新时间",
field: "updated_at",
formatter:Table.api.formatter.datetime,
visible: false,
},
{
title: "状态",
field: "status",
formatter: Table.api.formatter.switch
}
]
]
};
// 初始化表格
table.bootstrapTable(tableOptions);
// 为表格绑定事件
Table.api.bindevent(table);
}
};
return User
});
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
Binary file not shown.

Before

Width:  |  Height:  |  Size: 298 KiB

@@ -1,29 +0,0 @@
{
"name": "layer",
"main": "src/layer.js",
"version": "3.5.3",
"homepage": "https://github.com/sentsin/layer",
"authors": [
"sentsin <xu@sentsin.com>"
],
"description": "弹窗组件",
"moduleType": [
"amd",
"globals"
],
"keywords": [
"layer",
"layui",
"dialog"
],
"license": "MIT",
"_release": "3.5.3",
"_resolution": {
"type": "version",
"tag": "v3.5.3",
"commit": "7ef901632a7d21f37692ae5d4f9e671c7d57ce47"
},
"_source": "https://github.com/karsonzhang/fastadmin-layer.git",
"_target": "~3.5.1",
"_originalSource": "fastadmin-layer"
}
@@ -1,23 +0,0 @@
1.8.5/
*.iml
.idea/
.ipr
.iws
*~
~*
*.diff
*.patch
*.bak
.DS_Store
Thumbs.db
.svn/
*.swp
.nojekyll
.project
.settings/
node_modules/
_site/
.npmignore
release/
skin/moon/
src/skin/moon/
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2016 layui
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
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.
@@ -1,15 +0,0 @@
## 概要
layer 是一款历来都备受青睐的 Web 弹出层组件,具备全方位的解决方案,面向的是各个水平段的开发人员,您的页面会轻松地拥有丰富友好的操作体验。在与同类组件的比较中,layer 会更能被开发者所选择。这不仅是凭「脸」取胜,而是它尽可能地在以更少的代码展现更强健的功能,且格外注重性能的提升、易用和实用性,layer 甚至还兼容了包括 IE6 在内的所有主流浏览器。其数量可观的基础属性和方法,使得您可以自定义太多您需要的风格,每一种弹层模式各具特色,广受欢迎。当然,这种「王婆卖瓜」的陈述听起来总是有点难受,因此你需要进一步了解她是否真的如你所愿。
[文档与演示](http://layer.layui.com/)
## 愿景
成为网页弹出层的首先交互方案
## 现状
因着数年的坚持维护,已被运用在不计其数 Web 平台。几乎所处可见,其中还不乏众多知名大型网站。layer 已被国内乃至全世界至少数十万的开发者所使用过。
## 相关
[官网](http://layer.layui.com/)
@@ -1,20 +0,0 @@
{
"name": "layer",
"main": "src/layer.js",
"version": "3.5.3",
"homepage": "https://github.com/sentsin/layer",
"authors": [
"sentsin <xu@sentsin.com>"
],
"description": "弹窗组件",
"moduleType": [
"amd",
"globals"
],
"keywords": [
"layer",
"layui",
"dialog"
],
"license": "MIT"
}
File diff suppressed because one or more lines are too long
@@ -1,2 +0,0 @@
/*! layer mobile-v2.0.0 Web 通用弹出层组件 MIT License http://layer.layui.com/mobile By 贤心 */
;!function(e){"use strict";var t=document,n="querySelectorAll",i="getElementsByClassName",a=function(e){return t[n](e)},s={type:0,shade:!0,shadeClose:!0,fixed:!0,anim:"scale"},l={extend:function(e){var t=JSON.parse(JSON.stringify(s));for(var n in e)t[n]=e[n];return t},timer:{},end:{}};l.touch=function(e,t){e.addEventListener("click",function(e){t.call(this,e)},!1)};var r=0,o=["layui-m-layer"],c=function(e){var t=this;t.config=l.extend(e),t.view()};c.prototype.view=function(){var e=this,n=e.config,s=t.createElement("div");e.id=s.id=o[0]+r,s.setAttribute("class",o[0]+" "+o[0]+(n.type||0)),s.setAttribute("index",r);var l=function(){var e="object"==typeof n.title;return n.title?'<h3 style="'+(e?n.title[1]:"")+'">'+(e?n.title[0]:n.title)+"</h3>":""}(),c=function(){"string"==typeof n.btn&&(n.btn=[n.btn]);var e,t=(n.btn||[]).length;return 0!==t&&n.btn?(e='<span yes type="1">'+n.btn[0]+"</span>",2===t&&(e='<span no type="0">'+n.btn[1]+"</span>"+e),'<div class="layui-m-layerbtn">'+e+"</div>"):""}();if(n.fixed||(n.top=n.hasOwnProperty("top")?n.top:100,n.style=n.style||"",n.style+=" top:"+(t.body.scrollTop+n.top)+"px"),2===n.type&&(n.content='<i></i><i class="layui-m-layerload"></i><i></i><p>'+(n.content||"")+"</p>"),n.skin&&(n.anim="up"),"msg"===n.skin&&(n.shade=!1),s.innerHTML=(n.shade?"<div "+("string"==typeof n.shade?'style="'+n.shade+'"':"")+' class="layui-m-layershade"></div>':"")+'<div class="layui-m-layermain" '+(n.fixed?"":'style="position:static;"')+'><div class="layui-m-layersection"><div class="layui-m-layerchild '+(n.skin?"layui-m-layer-"+n.skin+" ":"")+(n.className?n.className:"")+" "+(n.anim?"layui-m-anim-"+n.anim:"")+'" '+(n.style?'style="'+n.style+'"':"")+">"+l+'<div class="layui-m-layercont">'+n.content+"</div>"+c+"</div></div></div>",!n.type||2===n.type){var d=t[i](o[0]+n.type),y=d.length;y>=1&&layer.close(d[0].getAttribute("index"))}document.body.appendChild(s);var u=e.elem=a("#"+e.id)[0];n.success&&n.success(u),e.index=r++,e.action(n,u)},c.prototype.action=function(e,t){var n=this;e.time&&(l.timer[n.index]=setTimeout(function(){layer.close(n.index)},1e3*e.time));var a=function(){var t=this.getAttribute("type");0==t?(e.no&&e.no(),layer.close(n.index)):e.yes?e.yes(n.index):layer.close(n.index)};if(e.btn)for(var s=t[i]("layui-m-layerbtn")[0].children,r=s.length,o=0;o<r;o++)l.touch(s[o],a);if(e.shade&&e.shadeClose){var c=t[i]("layui-m-layershade")[0];l.touch(c,function(){layer.close(n.index,e.end)})}e.end&&(l.end[n.index]=e.end)},e.layer={v:"2.0",index:r,open:function(e){var t=new c(e||{});return t.index},close:function(e){var n=a("#"+o[0]+e)[0];n&&(n.innerHTML="",t.body.removeChild(n),clearTimeout(l.timer[e]),delete l.timer[e],"function"==typeof l.end[e]&&l.end[e](),delete l.end[e])},closeAll:function(){for(var e=t[i](o[0]),n=0,a=e.length;n<a;n++)layer.close(0|e[0].getAttribute("index"))}},"function"==typeof define?define(function(){return layer}):function(){var e=document.scripts,n=e[e.length-1],i=n.src,a=i.substring(0,i.lastIndexOf("/")+1);n.getAttribute("merge")||document.head.appendChild(function(){var e=t.createElement("link");return e.href=a+"need/layer.css?2.0",e.type="text/css",e.rel="styleSheet",e.id="layermcss",e}())}()}(window);
File diff suppressed because one or more lines are too long
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 701 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

@@ -1 +0,0 @@
html #layui_layer_skinmoonstylecss{display:none;position:absolute;width:1989px}body .layer-ext-moon[type=dialog]{min-width:320px}body .layer-ext-moon-msg[type=dialog]{min-width:200px}body .layer-ext-moon .layui-layer-title{background:#f6f6f6;color:#212a31;font-size:16px;font-weight:700;height:46px;line-height:46px;border-bottom:1px solid #d5d5d5}body .layer-ext-moon .layui-layer-content .layui-layer-ico{height:32px;width:32px;top:18.5px}body .layer-ext-moon .layui-layer-ico0{background:url(default.png) no-repeat -96px 0}body .layer-ext-moon .layui-layer-ico1{background:url(default.png) no-repeat -224px 0}body .layer-ext-moon .layui-layer-ico2{background:url(default.png) no-repeat -192px 0}body .layer-ext-moon .layui-layer-ico3{background:url(default.png) no-repeat -160px 0}body .layer-ext-moon .layui-layer-ico4{background:url(default.png) no-repeat -320px 0}body .layer-ext-moon .layui-layer-ico5{background:url(default.png) no-repeat -288px 0}body .layer-ext-moon .layui-layer-ico6{background:url(default.png) -256px 0}body .layer-ext-moon .layui-layer-ico7{background:url(default.png) no-repeat -128px 0}body .layer-ext-moon .layui-layer-setwin{top:15px;right:15px}body .layer-ext-moon .layui-layer-setwin a{width:16px;height:16px}body .layer-ext-moon .layui-layer-setwin .layui-layer-min cite:hover{background-color:#56abe4}body .layer-ext-moon .layui-layer-setwin .layui-layer-max{background:url(default.png) no-repeat -80px 0}body .layer-ext-moon .layui-layer-setwin .layui-layer-max:hover{background:url(default.png) no-repeat -64px 0}body .layer-ext-moon .layui-layer-setwin .layui-layer-maxmin{background:url(default.png) no-repeat -32px 0}body .layer-ext-moon .layui-layer-setwin .layui-layer-maxmin:hover{background:url(default.png) no-repeat -16px 0}body .layer-ext-moon .layui-layer-setwin .layui-layer-close1,body .layer-ext-moon .layui-layer-setwin .layui-layer-close2{background:url(default.png) 0 0}body .layer-ext-moon .layui-layer-setwin .layui-layer-close1:hover,body .layer-ext-moon .layui-layer-setwin .layui-layer-close2:hover{background:url(default.png) -48px 0}body .layer-ext-moon .layui-layer-padding{padding-top:24px}body .layer-ext-moon .layui-layer-btn{text-align:center;padding-top:15px;padding-bottom:15px;background:#f0f4f7;border-top:1px #c7c7c7 solid}body .layer-ext-moon .layui-layer-btn a{font-size:12px;font-weight:400;margin:0 3px;margin-right:7px;margin-left:7px;padding:6px 20px;color:#fff;border:1px solid #0064b6;background:#0071ce;border-radius:3px;display:inline-block;height:20px;line-height:20px;text-align:center;vertical-align:middle;background-repeat:no-repeat;text-decoration:none;outline:0}body .layer-ext-moon .layui-layer-btn .layui-layer-btn0{background:#0071ce}body .layer-ext-moon .layui-layer-btn .layui-layer-btn1{background:#fff;color:#404a58;border:1px solid #c0c4cd;border-radius:3px}body .layer-ext-moon .layui-layer-btn .layui-layer-btn2{background:#f60;color:#fff;border:1px solid #f60;border-radius:3px}body .layer-ext-moon .layui-layer-btn .layui-layer-btn3{background:red;color:#fff;border:1px solid red;border-radius:3px}body .layer-ext-moon .layui-layer-title span.layui-layer-tabnow{height:47px}
@@ -1,35 +0,0 @@
/**
layer构建
*/
const {src, dest, series} = require('gulp');
var pkg = require('./package.json');
var uglify = require('gulp-uglify');
var minify = require('gulp-clean-css');
var rename = require('gulp-rename');
var header = require('gulp-header');
var del = require('del');
var task = {
layer: function () {
src('./src/**/*.css')
.pipe(minify({
compatibility: 'ie7'
}))
.pipe(dest('./dist'));
return src('./src/layer.js').pipe(uglify())
.pipe(header('/*! <%= pkg.realname %>-v<%= pkg.version %> <%= pkg.description %> <%= pkg.license %> License <%= pkg.homepage %> By <%= pkg.author %> */\n ;', {pkg: pkg}))
.pipe(dest('./dist'));
}
, mobile: function () {
return src('./src/mobile/layer.js').pipe(uglify())
.pipe(header('/*! <%= pkg.realname %> mobile-v<%= pkg.mobile %> <%= pkg.description %> <%= pkg.license %> License <%= pkg.homepage %>mobile By <%= pkg.author %> */\n ;', {pkg: pkg}))
.pipe(dest('./dist/mobile'));
}
};
exports.layer = task.layer;
exports.mobile = task.mobile;
exports.default = series(task.layer, task.mobile);
@@ -1,41 +0,0 @@
{
"name": "layer-src",
"realname": "layer",
"version": "3.5.3",
"mobile": "2.0.0",
"description": "Web 通用弹出层组件",
"main": "src/layer.js",
"license": "MIT",
"scripts": {
"run": "gulp"
},
"repository": {
"type": "https",
"url": "git+https://github.com/sentsin/layer.git"
},
"author": "贤心",
"homepage": "http://layer.layui.com/",
"devDependencies": {
"del": "~2.2.2",
"gulp": "^4.0.2",
"gulp-header": "~1.8.8",
"gulp-clean-css": "~4.2.0",
"gulp-rename": "~1.2.2",
"gulp-uglify": "~1.5.4"
},
"bugs": {
"url": "https://github.com/sentsin/layer/issues"
},
"directories": {
"test": "test"
},
"dependencies": {},
"keywords": [
"layer",
"dialog",
"tips",
"alert",
"confirm",
"window"
]
}
@@ -1,3 +0,0 @@
## 注意
开发版源码随时可能会提交,因此生产环境更建议 dist 目录中压缩后的 layer.js。
File diff suppressed because it is too large Load Diff
@@ -1,14 +0,0 @@
## layer mobile
layer mobile是为移动设备(手机、平板等webkit内核浏览器/webview)量身定做的弹层支撑,采用Native JavaScript编写,完全独立于PC版的layer,您需要按照场景选择使用。
[文档与演示](http://sentsin.com/layui/layer/)
1. 无需依赖任何库,只加载layer.m.js即可
2. 小巧玲珑,性能卓越、柔情似水…
3. 具备无以伦比的自适应功能
4. 灵活的皮肤自定义支撑,充分确保弹层风格多样化
5. 丰富、科学的接口,让弹弹弹层无所不能
## 备注
[官网](http://sentsin.com/layui/layer/)、[有问必答](http://say.sentsin.com/home-48.html)
@@ -1,207 +0,0 @@
/*!
@Namelayer mobile v2.0 弹层组件移动版
@Author:贤心
@LicenseMIT
*/
;!function(win){
"use strict";
var doc = document, query = 'querySelectorAll', claname = 'getElementsByClassName', S = function(s){
return doc[query](s);
};
//默认配置
var config = {
type: 0
,shade: true
,shadeClose: true
,fixed: true
,anim: 'scale' //默认动画类型
};
var ready = {
extend: function(obj){
var newobj = JSON.parse(JSON.stringify(config));
for(var i in obj){
newobj[i] = obj[i];
}
return newobj;
},
timer: {}, end: {}
};
//点触事件
ready.touch = function(elem, fn){
elem.addEventListener('click', function(e){
fn.call(this, e);
}, false);
};
var index = 0, classs = ['layui-m-layer'], Layer = function(options){
var that = this;
that.config = ready.extend(options);
that.view();
};
Layer.prototype.view = function(){
var that = this, config = that.config, layerbox = doc.createElement('div');
that.id = layerbox.id = classs[0] + index;
layerbox.setAttribute('class', classs[0] + ' ' + classs[0]+(config.type || 0));
layerbox.setAttribute('index', index);
//标题区域
var title = (function(){
var titype = typeof config.title === 'object';
return config.title
? '<h3 style="'+ (titype ? config.title[1] : '') +'">'+ (titype ? config.title[0] : config.title) +'</h3>'
: '';
}());
//按钮区域
var button = (function(){
typeof config.btn === 'string' && (config.btn = [config.btn]);
var btns = (config.btn || []).length, btndom;
if(btns === 0 || !config.btn){
return '';
}
btndom = '<span yes type="1">'+ config.btn[0] +'</span>'
if(btns === 2){
btndom = '<span no type="0">'+ config.btn[1] +'</span>' + btndom;
}
return '<div class="layui-m-layerbtn">'+ btndom + '</div>';
}());
if(!config.fixed){
config.top = config.hasOwnProperty('top') ? config.top : 100;
config.style = config.style || '';
config.style += ' top:'+ ( doc.body.scrollTop + config.top) + 'px';
}
if(config.type === 2){
config.content = '<i></i><i class="layui-m-layerload"></i><i></i><p>'+ (config.content||'') +'</p>';
}
if(config.skin) config.anim = 'up';
if(config.skin === 'msg') config.shade = false;
layerbox.innerHTML = (config.shade ? '<div '+ (typeof config.shade === 'string' ? 'style="'+ config.shade +'"' : '') +' class="layui-m-layershade"></div>' : '')
+'<div class="layui-m-layermain" '+ (!config.fixed ? 'style="position:static;"' : '') +'>'
+'<div class="layui-m-layersection">'
+'<div class="layui-m-layerchild '+ (config.skin ? 'layui-m-layer-' + config.skin + ' ' : '') + (config.className ? config.className : '') + ' ' + (config.anim ? 'layui-m-anim-' + config.anim : '') +'" ' + ( config.style ? 'style="'+config.style+'"' : '' ) +'>'
+ title
+'<div class="layui-m-layercont">'+ config.content +'</div>'
+ button
+'</div>'
+'</div>'
+'</div>';
if(!config.type || config.type === 2){
var dialogs = doc[claname](classs[0] + config.type), dialen = dialogs.length;
if(dialen >= 1){
layer.close(dialogs[0].getAttribute('index'))
}
}
document.body.appendChild(layerbox);
var elem = that.elem = S('#'+that.id)[0];
config.success && config.success(elem);
that.index = index++;
that.action(config, elem);
};
Layer.prototype.action = function(config, elem){
var that = this;
//自动关闭
if(config.time){
ready.timer[that.index] = setTimeout(function(){
layer.close(that.index);
}, config.time*1000);
}
//确认取消
var btn = function(){
var type = this.getAttribute('type');
if(type == 0){
config.no && config.no();
layer.close(that.index);
} else {
config.yes ? config.yes(that.index) : layer.close(that.index);
}
};
if(config.btn){
var btns = elem[claname]('layui-m-layerbtn')[0].children, btnlen = btns.length;
for(var ii = 0; ii < btnlen; ii++){
ready.touch(btns[ii], btn);
}
}
//点遮罩关闭
if(config.shade && config.shadeClose){
var shade = elem[claname]('layui-m-layershade')[0];
ready.touch(shade, function(){
layer.close(that.index, config.end);
});
}
config.end && (ready.end[that.index] = config.end);
};
win.layer = {
v: '2.0',
index: index,
//核心方法
open: function(options){
var o = new Layer(options || {});
return o.index;
},
close: function(index){
var ibox = S('#'+classs[0]+index)[0];
if(!ibox) return;
ibox.innerHTML = '';
doc.body.removeChild(ibox);
clearTimeout(ready.timer[index]);
delete ready.timer[index];
typeof ready.end[index] === 'function' && ready.end[index]();
delete ready.end[index];
},
//关闭所有layer层
closeAll: function(){
var boxs = doc[claname](classs[0]);
for(var i = 0, len = boxs.length; i < len; i++){
layer.close((boxs[0].getAttribute('index')|0));
}
}
};
'function' == typeof define ? define(function() {
return layer;
}) : function(){
var js = document.scripts, script = js[js.length - 1], jsPath = script.src;
var path = jsPath.substring(0, jsPath.lastIndexOf("/") + 1);
//如果合并方式,则需要单独引入layer.css
if(script.getAttribute('merge')) return;
document.head.appendChild(function(){
var link = doc.createElement('link');
link.href = path + 'need/layer.css?2.0';
link.type = 'text/css';
link.rel = 'styleSheet'
link.id = 'layermcss';
return link;
}());
}();
}(window);
@@ -1,87 +0,0 @@
/*
layer mobile
*/
.layui-m-layer{position:relative; z-index: 19891014;}
.layui-m-layer *{-webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box;}
.layui-m-layershade,
.layui-m-layermain{position:fixed; left:0; top:0; width:100%; height:100%;}
.layui-m-layershade{background-color:rgba(0,0,0, .7); pointer-events:auto;}
.layui-m-layermain{display:table; font-family: Helvetica, arial, sans-serif; pointer-events: none;}
.layui-m-layermain .layui-m-layersection{display:table-cell; vertical-align:middle; text-align:center;}
.layui-m-layerchild{position:relative; display:inline-block; text-align:left; background-color:#fff; font-size:14px; border-radius: 5px; box-shadow: 0 0 8px rgba(0, 0, 0, 0.1); pointer-events:auto; -webkit-overflow-scrolling: touch;}
.layui-m-layerchild{-webkit-animation-fill-mode: both; animation-fill-mode: both; -webkit-animation-duration: .2s; animation-duration: .2s;}
/* 弹出动画 */
@-webkit-keyframes layui-m-anim-scale { /* 默认 */
0% {opacity: 0; -webkit-transform: scale(.5); transform: scale(.5)}
100% {opacity: 1; -webkit-transform: scale(1); transform: scale(1)}
}
@keyframes layui-m-anim-scale { /* 默认 */
0% {opacity: 0; -webkit-transform: scale(.5); transform: scale(.5)}
100% {opacity: 1; -webkit-transform: scale(1); transform: scale(1)}
}
.layui-m-anim-scale{animation-name: layui-m-anim-scale; -webkit-animation-name: layui-m-anim-scale;}
@-webkit-keyframes layui-m-anim-up{
0%{opacity: 0; -webkit-transform: translateY(800px); transform: translateY(800px)}
100%{opacity: 1; -webkit-transform: translateY(0); transform: translateY(0)}
}
@keyframes layui-m-anim-up{
0%{opacity: 0; -webkit-transform: translateY(800px); transform: translateY(800px)}
100%{opacity: 1; -webkit-transform: translateY(0); transform: translateY(0)}
}
.layui-m-anim-up{-webkit-animation-name: layui-m-anim-up;animation-name: layui-m-anim-up}
.layui-m-layer0 .layui-m-layerchild{width: 90%; max-width: 640px;}
.layui-m-layer1 .layui-m-layerchild{border:none; border-radius:0;}
.layui-m-layer2 .layui-m-layerchild{width:auto; max-width:260px; min-width:40px; border:none; background: none; box-shadow: none; color:#fff;}
.layui-m-layerchild h3{padding: 0 10px; height: 60px; line-height: 60px; font-size:16px; font-weight: 400; border-radius: 5px 5px 0 0; text-align: center;}
.layui-m-layerchild h3,
.layui-m-layerbtn span{ text-overflow:ellipsis; overflow:hidden; white-space:nowrap;}
.layui-m-layercont{padding: 50px 30px; line-height: 22px; text-align:center;}
.layui-m-layer1 .layui-m-layercont{padding:0; text-align:left;}
.layui-m-layer2 .layui-m-layercont{text-align:center; padding: 0; line-height: 0;}
.layui-m-layer2 .layui-m-layercont i{width:25px; height:25px; margin-left:8px; display:inline-block; background-color:#fff; border-radius:100%;}
.layui-m-layer2 .layui-m-layercont p{margin-top: 20px;}
/* loading */
@-webkit-keyframes layui-m-anim-loading{
0%,80%,100%{transform:scale(0); -webkit-transform:scale(0)}
40%{transform:scale(1); -webkit-transform:scale(1)}
}
@keyframes layui-m-anim-loading{
0%,80%,100%{transform:scale(0); -webkit-transform:scale(0)}
40%{transform:scale(1); -webkit-transform:scale(1)}
}
.layui-m-layer2 .layui-m-layercont i{-webkit-animation: layui-m-anim-loading 1.4s infinite ease-in-out; animation: layui-m-anim-loading 1.4s infinite ease-in-out; -webkit-animation-fill-mode: both; animation-fill-mode: both;}
.layui-m-layer2 .layui-m-layercont i:first-child{margin-left:0; -webkit-animation-delay: -.32s; animation-delay: -.32s;}
.layui-m-layer2 .layui-m-layercont i.layui-m-layerload{-webkit-animation-delay: -.16s; animation-delay: -.16s;}
.layui-m-layer2 .layui-m-layercont>div{line-height:22px; padding-top:7px; margin-bottom:20px; font-size: 14px;}
.layui-m-layerbtn{display: box; display: -moz-box; display: -webkit-box; width: 100%; position:relative; height: 50px; line-height: 50px; font-size: 0; text-align:center; border-top:1px solid #D0D0D0; background-color: #F2F2F2; border-radius: 0 0 5px 5px;}
.layui-m-layerbtn span{position:relative; display: block; -moz-box-flex: 1; box-flex: 1; -webkit-box-flex: 1; text-align:center; font-size:14px; border-radius: 0 0 5px 5px; cursor:pointer;}
.layui-m-layerbtn span[yes]{color: #40AFFE;}
.layui-m-layerbtn span[no]{border-right: 1px solid #D0D0D0; border-radius: 0 0 0 5px;}
.layui-m-layerbtn span:active{background-color: #F6F6F6;}
.layui-m-layerend{position:absolute; right:7px; top:10px; width:30px; height:30px; border: 0; font-weight:400; background: transparent; cursor: pointer; -webkit-appearance: none; font-size:30px;}
.layui-m-layerend::before, .layui-m-layerend::after{position:absolute; left:5px; top:15px; content:''; width:18px; height:1px; background-color:#999; transform:rotate(45deg); -webkit-transform:rotate(45deg); border-radius: 3px;}
.layui-m-layerend::after{transform:rotate(-45deg); -webkit-transform:rotate(-45deg);}
/* 底部对话框风格 */
body .layui-m-layer .layui-m-layer-footer{position: fixed; width: 95%; max-width: 100%; margin: 0 auto; left:0; right: 0; bottom: 10px; background: none;}
.layui-m-layer-footer .layui-m-layercont{padding: 20px; border-radius: 5px 5px 0 0; background-color: rgba(255,255,255,.8);}
.layui-m-layer-footer .layui-m-layerbtn{display: block; height: auto; background: none; border-top: none;}
.layui-m-layer-footer .layui-m-layerbtn span{background-color: rgba(255,255,255,.8);}
.layui-m-layer-footer .layui-m-layerbtn span[no]{color: #FD482C; border-top: 1px solid #c2c2c2; border-radius: 0 0 5px 5px;}
.layui-m-layer-footer .layui-m-layerbtn span[yes]{margin-top: 10px; border-radius: 5px;}
/* 通用提示 */
body .layui-m-layer .layui-m-layer-msg{width: auto; max-width: 90%; margin: 0 auto; bottom: -150px; background-color: rgba(0,0,0,.7); color: #fff;}
.layui-m-layer-msg .layui-m-layercont{padding: 10px 20px;}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

@@ -1,182 +0,0 @@
/**
@Name: layer
**/
/* *html{background-image: url(about:blank); background-attachment: fixed;} */
html #layuicss-layer{display: none; position: absolute; width: 1989px;}
html[layer-full]{height:inherit}
/* common */
.layui-layer-shade, .layui-layer{position:fixed; _position:absolute; pointer-events: auto;}
.layui-layer-shade{top:0; left:0; width:100%; height:100%; _height:expression(document.body.offsetHeight+"px");}
.layui-layer{-webkit-overflow-scrolling: touch;}
.layui-layer{top:150px; left: 0; margin:0; padding:0; background-color:#fff; -webkit-background-clip: content; border-radius: 2px; box-shadow: 1px 1px 50px rgba(0,0,0,.3);}
.layui-layer-close{position:absolute;}
.layui-layer-content{position:relative;}
.layui-layer-border{border: 1px solid #B2B2B2; border: 1px solid rgba(0,0,0,.1); box-shadow: 1px 1px 5px rgba(0,0,0,.2);}
.layui-layer-load{background:url(loading-1.gif) #eee center center no-repeat;}
.layui-layer-ico{ background:url(icon.png) no-repeat;}
.layui-layer-dialog .layui-layer-ico,
.layui-layer-setwin a,
.layui-layer-btn a{display:inline-block; *display:inline; *zoom:1; vertical-align:top;}
.layui-layer-move{display: none; position: fixed; *position: absolute; left: 0px; top: 0px; width: 100%; height: 100%; cursor: move; opacity: 0; filter:alpha(opacity=0); background-color: #fff; z-index: 2147483647;}
.layui-layer-resize{position: absolute; width: 15px; height: 15px; right: 0; bottom: 0; cursor: se-resize;}
.layui-layer-confirm{position: absolute; width: 1px; height: 1px; left: 0; bottom: 0; border:none; background:transparent;}
/* 动画 */
.layer-anim{-webkit-animation-fill-mode: both; animation-fill-mode: both; -webkit-animation-duration:.3s; animation-duration:.3s;}
@-webkit-keyframes layer-bounceIn { /* 默认 */
0% {opacity: 0; -webkit-transform: scale(.5); transform: scale(.5)}
100% {opacity: 1; -webkit-transform: scale(1); transform: scale(1)}
}
@keyframes layer-bounceIn {
0% {opacity: 0; -webkit-transform: scale(.5); -ms-transform: scale(.5); transform: scale(.5)}
100% {opacity: 1; -webkit-transform: scale(1); -ms-transform: scale(1); transform: scale(1)}
}
.layer-anim-00{-webkit-animation-name: layer-bounceIn;animation-name: layer-bounceIn}
@-webkit-keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-01{-webkit-animation-name:layer-zoomInDown;animation-name:layer-zoomInDown}
@-webkit-keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.layer-anim-02{-webkit-animation-name:layer-fadeInUpBig;animation-name:layer-fadeInUpBig}
@-webkit-keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-03{-webkit-animation-name:layer-zoomInLeft;animation-name:layer-zoomInLeft}
@-webkit-keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0px) rotate(0deg);transform:translateX(0px) rotate(0deg)}}@keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0px) rotate(0deg);-ms-transform:translateX(0px) rotate(0deg);transform:translateX(0px) rotate(0deg)}}.layer-anim-04{-webkit-animation-name:layer-rollIn;animation-name:layer-rollIn}
@keyframes layer-fadeIn{0%{opacity:0}100%{opacity:1}}.layer-anim-05{-webkit-animation-name:layer-fadeIn;animation-name:layer-fadeIn}
@-webkit-keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.layer-anim-06{-webkit-animation-name:layer-shake;animation-name:layer-shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}
/* 标题栏 */
.layui-layer-title{padding:0 80px 0 20px; height: 50px; line-height: 50px; border-bottom:1px solid #F0F0F0; font-size: 14px; color:#333; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; border-radius: 2px 2px 0 0;}
.layui-layer-setwin{position:absolute; right: 15px; *right:0; top: 17px; font-size:0; line-height: initial;}
.layui-layer-setwin a{position:relative; width: 16px; height:16px; margin-left:10px; font-size:12px; _overflow:hidden;}
.layui-layer-setwin .layui-layer-min cite{position:absolute; width:14px; height:2px; left:0; top:50%; margin-top:-1px; background-color:#2E2D3C; cursor:pointer; _overflow:hidden;}
.layui-layer-setwin .layui-layer-min:hover cite{background-color:#2D93CA; }
.layui-layer-setwin .layui-layer-max{background-position:-32px -40px;}
.layui-layer-setwin .layui-layer-max:hover{background-position:-16px -40px;}
.layui-layer-setwin .layui-layer-maxmin{background-position:-65px -40px;}
.layui-layer-setwin .layui-layer-maxmin:hover{background-position:-49px -40px;}
.layui-layer-setwin .layui-layer-close1{background-position: 1px -40px; cursor: pointer;}
.layui-layer-setwin .layui-layer-close1:hover{opacity:0.7;}
.layui-layer-setwin .layui-layer-close2{position:absolute; right:-28px; top:-28px; width:30px; height:30px; margin-left:0; background-position:-149px -31px; *right:-18px; _display:none;}
.layui-layer-setwin .layui-layer-close2:hover{ background-position:-180px -31px;}
/* 按钮栏 */
.layui-layer-btn{text-align: right; padding: 0 15px 12px; pointer-events: auto; user-select: none; -webkit-user-select: none;}
.layui-layer-btn a{height: 28px; line-height: 28px; margin: 5px 5px 0; padding: 0 15px; border: 1px solid #dedede; background-color:#fff; color: #333; border-radius: 2px; font-weight:400; cursor:pointer; text-decoration: none;}
.layui-layer-btn a:hover{opacity: 0.9; text-decoration: none;}
.layui-layer-btn a:active{opacity: 0.8;}
.layui-layer-btn .layui-layer-btn0{border-color: #1E9FFF; background-color: #1E9FFF; color:#fff;}
.layui-layer-btn-l{text-align: left;}
.layui-layer-btn-c{text-align: center;}
/* 定制化 */
.layui-layer-dialog{min-width: 300px;}
.layui-layer-dialog .layui-layer-content{position: relative; padding:20px; line-height:24px; word-break: break-all; overflow:hidden; font-size:14px; overflow-x: hidden; overflow-y:auto;}
.layui-layer-dialog .layui-layer-content .layui-layer-ico{position:absolute; top:16px; left:15px; _left:-40px; width:30px; height:30px;}
.layui-layer-ico1{background-position:-30px 0 }
.layui-layer-ico2{background-position:-60px 0;}
.layui-layer-ico3{background-position:-90px 0;}
.layui-layer-ico4{background-position:-120px 0;}
.layui-layer-ico5{background-position:-150px 0;}
.layui-layer-ico6{background-position:-180px 0;}
.layui-layer-rim{border:6px solid #8D8D8D; border:6px solid rgba(0,0,0,.3); border-radius:5px; box-shadow: none;}
.layui-layer-msg{min-width:180px; border:1px solid #D3D4D3; box-shadow: none;}
.layui-layer-hui{min-width:100px; background-color: #000; filter:alpha(opacity=60); background-color: rgba(0,0,0,0.6); color: #fff; border:none;}
.layui-layer-hui .layui-layer-content{padding:12px 25px; text-align:center;}
.layui-layer-dialog .layui-layer-padding{padding: 20px 20px 20px 55px; text-align: left;}
.layui-layer-page .layui-layer-content{position:relative; overflow:auto;}
.layui-layer-page .layui-layer-btn,.layui-layer-iframe .layui-layer-btn{padding-top:10px;}
.layui-layer-nobg{background:none;}
.layui-layer-iframe iframe{display: block; width: 100%;}
.layui-layer-loading{border-radius:100%; background:none; box-shadow:none; border:none;}
.layui-layer-loading .layui-layer-content{width:60px; height:24px; background:url(loading-0.gif) no-repeat;}
.layui-layer-loading .layui-layer-loading1{width:37px; height:37px; background:url(loading-1.gif) no-repeat;}
.layui-layer-loading .layui-layer-loading2, .layui-layer-ico16{width:32px; height:32px; background:url(loading-2.gif) no-repeat;}
.layui-layer-tips{background: none; box-shadow:none; border:none;}
.layui-layer-tips .layui-layer-content{position: relative; line-height: 22px; min-width: 12px; padding: 8px 15px; font-size: 12px; _float:left; border-radius: 2px; box-shadow: 1px 1px 3px rgba(0,0,0,.2); background-color: #000; color: #fff;}
.layui-layer-tips .layui-layer-close{right:-2px; top:-1px;}
.layui-layer-tips i.layui-layer-TipsG{ position:absolute; width:0; height:0; border-width:8px; border-color:transparent; border-style:dashed; *overflow:hidden;}
.layui-layer-tips i.layui-layer-TipsT, .layui-layer-tips i.layui-layer-TipsB{left:5px; border-right-style:solid; border-right-color: #000;}
.layui-layer-tips i.layui-layer-TipsT{bottom:-8px;}
.layui-layer-tips i.layui-layer-TipsB{top:-8px;}
.layui-layer-tips i.layui-layer-TipsR, .layui-layer-tips i.layui-layer-TipsL{top: 5px; border-bottom-style:solid; border-bottom-color: #000;}
.layui-layer-tips i.layui-layer-TipsR{left:-8px;}
.layui-layer-tips i.layui-layer-TipsL{right:-8px;}
/* skin */
.layui-layer-lan[type="dialog"]{min-width:280px;}
.layui-layer-lan .layui-layer-title{background:#4476A7; color:#fff; border: none;}
.layui-layer-lan .layui-layer-btn{padding: 5px 10px 10px; text-align: right; border-top:1px solid #E9E7E7}
.layui-layer-lan .layui-layer-btn a{background: #fff; border-color: #E9E7E7; color: #333;}
.layui-layer-lan .layui-layer-btn .layui-layer-btn1{background:#C9C5C5;}
.layui-layer-molv .layui-layer-title{background: #009f95; color:#fff; border: none;}
.layui-layer-molv .layui-layer-btn a{background: #009f95; border-color: #009f95;}
.layui-layer-molv .layui-layer-btn .layui-layer-btn1{background:#92B8B1;}
/**
@Name: layer拓展样式
*/
.layui-layer-iconext{background:url(icon-ext.png) no-repeat;}
/* prompt模式 */
.layui-layer-prompt .layui-layer-input{display: block; width: 260px; height: 36px; margin: 0 auto; line-height: 30px; padding-left: 10px; border: 1px solid #e6e6e6; color: #333;}
.layui-layer-prompt textarea.layui-layer-input{width: 300px; height: 100px; line-height: 20px; padding: 6px 10px;}
.layui-layer-prompt .layui-layer-content{padding: 20px;}
.layui-layer-prompt .layui-layer-btn{padding-top: 0;}
/* tab模式 */
.layui-layer-tab{box-shadow:1px 1px 50px rgba(0,0,0,.4);}
.layui-layer-tab .layui-layer-title{padding-left:0; overflow: visible;}
.layui-layer-tab .layui-layer-title span{position:relative; float:left; min-width:80px; max-width: 300px; padding:0 20px; text-align:center; cursor:default; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; cursor: pointer;}
.layui-layer-tab .layui-layer-title span.layui-this{height: 51px; border-left: 1px solid #eee; border-right: 1px solid #eee; background-color: #fff; z-index: 10;}
.layui-layer-tab .layui-layer-title span:first-child{border-left:none;}
.layui-layer-tabmain{line-height:24px; clear:both;}
.layui-layer-tabmain .layui-layer-tabli{display:none;}
.layui-layer-tabmain .layui-layer-tabli.layui-this{display: block;}
/* photo模式 */
.layui-layer-photos{background: none; box-shadow: none;}
.layui-layer-photos .layui-layer-content{overflow:visible; text-align: center;}
.layui-layer-photos .layui-layer-phimg img{position: relative; width:100%; display: inline-block; *display:inline; *zoom:1; vertical-align:top;}
.layui-layer-imgprev, .layui-layer-imgnext{position: fixed; top: 50%; width: 27px; _width: 44px; height: 44px; margin-top:-22px; outline:none;blr:expression(this.onFocus=this.blur());}
.layui-layer-imgprev{left: 30px; background-position:-5px -5px; _background-position:-70px -5px;}
.layui-layer-imgprev:hover{background-position:-33px -5px; _background-position:-120px -5px;}
.layui-layer-imgnext{right: 30px; _right:8px; background-position:-5px -50px; _background-position:-70px -50px;}
.layui-layer-imgnext:hover{background-position: -33px -50px; _background-position: -120px -50px;}
.layui-layer-imgbar{position: fixed; left:0; right: 0; bottom:0; width:100%; height: 40px; line-height: 40px; background-color:#000\9; filter:Alpha(opacity=60); background-color: rgba(2,0,0,.35); color: #fff; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; font-size:0;}
.layui-layer-imgtit{/*position:absolute; left:20px;*/}
.layui-layer-imgtit *{display:inline-block; *display:inline; *zoom:1; vertical-align:top; font-size:12px;}
.layui-layer-imgtit a{max-width:65%; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; color:#fff;}
.layui-layer-imgtit a:hover{color:#fff; text-decoration:underline;}
.layui-layer-imgtit em{padding-left:10px; font-style: normal;}
/* 关闭动画 */
@-webkit-keyframes layer-bounceOut {
100% {opacity: 0; -webkit-transform: scale(.7); transform: scale(.7)}
30% {-webkit-transform: scale(1.05); transform: scale(1.05)}
0% {-webkit-transform: scale(1); transform: scale(1);}
}
@keyframes layer-bounceOut {
100% {opacity: 0; -webkit-transform: scale(.7); -ms-transform: scale(.7); transform: scale(.7);}
30% {-webkit-transform: scale(1.05); -ms-transform: scale(1.05); transform: scale(1.05);}
0% {-webkit-transform: scale(1); -ms-transform: scale(1);transform: scale(1);}
}
.layer-anim-close{-webkit-animation-name: layer-bounceOut; animation-name: layer-bounceOut; -webkit-animation-fill-mode: both; animation-fill-mode: both; -webkit-animation-duration:.2s; animation-duration:.2s;}
@media screen and (max-width: 1100px) {
.layui-layer-iframe{overflow-y: auto; -webkit-overflow-scrolling: touch;}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 701 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

@@ -1,140 +0,0 @@
/*
* layer皮肤
*
*/
html #layui_layer_skinmoonstylecss {
display: none;
position: absolute;
width: 1989px;
}
body .layer-ext-moon[type="dialog"] {
min-width: 320px;
}
body .layer-ext-moon-msg[type="dialog"]{min-width:200px;}
body .layer-ext-moon .layui-layer-title {
background: #f6f6f6;
color: #212a31;
font-size: 16px;
font-weight: bold;
height: 46px;
line-height: 46px;
border-bottom: 1px solid #D5D5D5;
}
body .layer-ext-moon .layui-layer-content .layui-layer-ico {
height: 32px;
width: 32px;
top:18.5px;
}
body .layer-ext-moon .layui-layer-ico0 {
background: url(default.png) no-repeat -96px 0;
;
}
body .layer-ext-moon .layui-layer-ico1 {
background: url(default.png) no-repeat -224px 0;
;
}
body .layer-ext-moon .layui-layer-ico2 {
background: url(default.png) no-repeat -192px 0;
}
body .layer-ext-moon .layui-layer-ico3 {
background: url(default.png) no-repeat -160px 0;
}
body .layer-ext-moon .layui-layer-ico4 {
background: url(default.png) no-repeat -320px 0;
}
body .layer-ext-moon .layui-layer-ico5 {
background: url(default.png) no-repeat -288px 0;
}
body .layer-ext-moon .layui-layer-ico6 {
background: url(default.png) -256px 0;
}
body .layer-ext-moon .layui-layer-ico7 {
background: url(default.png) no-repeat -128px 0;
}
body .layer-ext-moon .layui-layer-setwin {
top: 15px;
right: 15px;
}
body .layer-ext-moon .layui-layer-setwin a {
width: 16px;
height: 16px;
}
body .layer-ext-moon .layui-layer-setwin .layui-layer-min cite:hover {
background-color: #56abe4;
}
body .layer-ext-moon .layui-layer-setwin .layui-layer-max {
background: url(default.png) no-repeat -80px 0;
}
body .layer-ext-moon .layui-layer-setwin .layui-layer-max:hover {
background: url(default.png) no-repeat -64px 0;
}
body .layer-ext-moon .layui-layer-setwin .layui-layer-maxmin {
background: url(default.png) no-repeat -32px 0;
}
body .layer-ext-moon .layui-layer-setwin .layui-layer-maxmin:hover {
background: url(default.png) no-repeat -16px 0;
}
body .layer-ext-moon .layui-layer-setwin .layui-layer-close1,body .layer-ext-moon .layui-layer-setwin .layui-layer-close2 {
background: url(default.png) 0 0;
}
body .layer-ext-moon .layui-layer-setwin .layui-layer-close1:hover,body .layer-ext-moon .layui-layer-setwin .layui-layer-close2:hover {
background: url(default.png) -48px 0;
}
body .layer-ext-moon .layui-layer-padding{padding-top: 24px;}
body .layer-ext-moon .layui-layer-btn {
text-align: center;
padding-top: 15px;
padding-bottom:15px;
background: #f0f4f7;
border-top: 1px #c7c7c7 solid;
}
body .layer-ext-moon .layui-layer-btn a {
font-size: 12px;
font-weight: normal;
margin: 0 3px;
margin-right: 7px;
margin-left: 7px;
padding: 6px 20px;
color: #fff;
border: 1px solid #0064b6;
background: #0071ce;
border-radius: 3px;
display: inline-block;
height: 20px;
line-height: 20px;
text-align: center;
vertical-align: middle;
background-repeat: no-repeat;
text-decoration: none;
outline: none;
}
body .layer-ext-moon .layui-layer-btn .layui-layer-btn0 {
background: #0071ce;
}
body .layer-ext-moon .layui-layer-btn .layui-layer-btn1 {
background: #fff;
color: #404a58;
border: 1px solid #c0c4cd;
border-radius: 3px;
}
body .layer-ext-moon .layui-layer-btn .layui-layer-btn2 {
background: #f60;
color: #fff;
border: 1px solid #f60;
border-radius: 3px;
}
body .layer-ext-moon .layui-layer-btn .layui-layer-btn3 {
background: #f00;
color: #fff;
border: 1px solid #f00;
border-radius: 3px;
}
body .layer-ext-moon .layui-layer-title span.layui-layer-tabnow{
height:47px;
}
@@ -1,76 +0,0 @@

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>layer-更懂你的web弹窗解决方案</title>
<style>
html{background-color:#E3E3E3; font-size:14px; color:#000; font-family:'微软雅黑'}
a,a:hover{ text-decoration:none;}
pre{font-family:'微软雅黑'}
.box{padding:20px; background-color:#fff; margin:50px 100px; border-radius:5px;}
.box a{padding-right:15px;}
#about_hide{display:none}
.layer_text{background-color:#fff; padding:20px;}
.layer_text p{margin-bottom: 10px; text-indent: 2em; line-height: 23px;}
.button{display:inline-block; *display:inline; *zoom:1; line-height:30px; padding:0 20px; background-color:#56B4DC; color:#fff; font-size:14px; border-radius:3px; cursor:pointer; font-weight:normal;}
.photos-demo img{width:200px;}
</style>
<script src="http://cdn.bootcss.com/jquery/1.12.3/jquery.min.js"></script>
<script src="../dist/layer.js"></script>
</head>
<body>
<div class="box">
<pre>
@Namelayer
@Versionv<script>document.write(layer.v)</script>
@Description:通用 Web 弹层组件
<strong>【注意事项】</strong>
一、使用时,请把文件夹 layer 整个放置在您站点的任何一个目录,只需引入 layer.js 即可,除 jQuery 外,其它文件无需再引入。
二、如果您的 js 引入是通过合并处理或者您不想采用layer自动获取的绝对路径,您可以通过 layer.config() 来配置(详见官网 API 页)
三、jQuery 需 1.8+
四、更多使用说明与演示,请参见 layer 官网。
五、使用时请务必保留来源,请勿用于违反我国法律法规的 Web 平台。
六、layer 是一款无偿的公益性项目,遵循 MIT 开源协议。
</pre>
</div>
<div class="box" style="text-align:center">
<a href="http://layer.layui.com/" target="_blank">更多示例</a>
<a href="http://www.layui.com/doc/modules/layer.html" target="_blank">使用文档</a>
<a href="javascript:;" id="about">关于</a>
</div>
<script>
;!function(){
//页面一打开就执行,放入ready是为了layer所需配件(css、扩展模块)加载完毕
layer.ready(function(){
layer.open({
type: 2,
title: '欢迎页',
maxmin: true,
area: ['800px', '500px'],
content: 'http://layer.layui.com/test/welcome.html',
end: function(){
layer.tips('Hi', '#about', {tips: 1})
}
});
});
//关于
$('#about').on('click', function(){
layer.alert('layui 出品');
});
}();
</script>
</body>
</html>
File diff suppressed because it is too large Load Diff
-14
View File
@@ -1,14 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>问卷帮</title>
<script type="module" crossorigin src="http://wjba.oss-accelerate.aliyuncs.com/web/assets/app.js"></script>
<link rel="stylesheet" crossorigin href="http://wjba.oss-accelerate.aliyuncs.com/web/assets/style.css">
</head>
<body>
<div id="app"></div>
</body>
</html>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

@@ -1,7 +0,0 @@
<?php
return array (
'Product does not exist' => 'Product does not exist',
'Gift is incorrect' => 'Gift is incorrect',
'Denomination is incorrect' => 'Denomination is incorrect',
'Insufficient balance' => 'Insufficient balance',
);
@@ -1,8 +0,0 @@
<?php
return array (
'Product does not exist' => 'Product does not exist',
'Questionnaire does not exist' => 'Questionnaire does not exist',
'Incorrect parameter' => 'Incorrect parameter',
'Server is not exist' => 'Server is not exist',
'Server is not exist %sadds_f%' => 'Server is not exist %sadds_f%',
);
@@ -1,9 +0,0 @@
<?php
return array (
'普通用户' => '普通用户',
'VIP' => 'VIP',
'渠道商' => '渠道商',
'Invalid user' => 'Invalid user',
'Access denied' => 'Access denied',
'It cannot be lower than the user\\\'s current level' => 'It cannot be lower than the user\\\'s current level',
);
@@ -1,9 +0,0 @@
<?php
return array (
'The system is under maintenance, please wait...' => 'The system is under maintenance, please wait...',
'Exchange successful' => 'Exchange successful',
'User is incorrect' => 'User is incorrect',
'Insufficient balance' => 'Insufficient balance',
'Transfer successful' => 'Transfer successful',
'卡密不存在' => '卡密不存在',
);

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