feat: move miniapp server project

This commit is contained in:
ckaaaa 2025-09-18 10:36:08 +08:00
parent 4a940f28ba
commit 96d9063b13
178 changed files with 9699 additions and 5044 deletions

26
.gitignore vendored
View file

@ -1,15 +1,11 @@
node_modules/
yarn-error.log
miniprogram/
miniprogram_npm/
miniprogram_dist/
.DS_Store
$node_modules/
.history/
**/dist
components/**/*.lock
components/**/package-lock.json
package-lock.json
yarn.lock
project.private.config.json
.eslintcache
/.idea
/.vscode
*.log
.env
/public/uploads/**
!/public/uploads/.gitkeep
/public/upload
/public/web
/public/web_act1/
/public/output/**
!/public/outout/.gitkeep

42
.travis.yml Normal file
View file

@ -0,0 +1,42 @@
sudo: false
language: php
branches:
only:
- stable
cache:
directories:
- $HOME/.composer/cache
before_install:
- composer self-update
install:
- composer install --no-dev --no-interaction --ignore-platform-reqs
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip .
- composer require --update-no-dev --no-interaction "topthink/think-image:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0"
- composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0"
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip .
script:
- php think unit
deploy:
provider: releases
api_key:
secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw=
file:
- ThinkPHP_Core.zip
- ThinkPHP_Full.zip
skip_cleanup: true
on:
tags: true

32
LICENSE.txt Normal file
View file

@ -0,0 +1,32 @@
ThinkPHP遵循Apache2开源协议发布并提供免费使用。
版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn)
All rights reserved。
ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
Apache Licence是著名的非盈利开源组织Apache采用的协议。
该协议和BSD类似鼓励代码共享和尊重原作者的著作权
允许代码修改,再作为开源或商业软件发布。需要满足
的条件:
1 需要给代码的用户一份Apache Licence
2 如果你修改了代码,需要在被修改的文件中说明;
3 在延伸的代码中(修改和有源代码衍生的代码中)需要
带有原来代码中的协议,商标,专利声明和其他原来作者规
定需要包含的说明;
4 如果再发布的产品中包含一个Notice文件则在Notice文
件中需要带有本协议内容。你可以在Notice中增加自己的
许可但不可以表现为对Apache Licence构成更改。
具体的协议参考http://www.apache.org/licenses/LICENSE-2.0
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

9
app.js
View file

@ -1,9 +0,0 @@
import updateManager from './common/updateManager';
App({
onLaunch: function () {
},
onShow: function () {
updateManager();
},
});

View file

@ -1,53 +0,0 @@
{
"pages": [
"pages/home/home",
"pages/paylist/paylist",
"pages/news_list/home",
"pages/news_admin_list/home",
"pages/usercenter/index",
"pages/detail/detail",
"pages/detail_admin/detail",
"pages/takephoto/takephoto",
"pages/faxianlist/faxianlist",
"pages/test/test",
"pages/shop/shop",
"pages/pay/pay",
"pages/createpay/createpay",
"pages/sharebuy/sharebuy",
"pages/usercenter/info",
"pages/sharelist/sharelist",
"pages/webview/webview"
],
"tabBar": {
"custom": true,
"color": "#666666",
"selectedColor": "#FF5F15",
"backgroundColor": "#ffffff",
"borderStyle": "black",
"list": [
{
"pagePath": "pages/home/home",
"text": "首页"
},
{
"pagePath": "pages/faxianlist/faxianlist",
"text": "分销"
},
{
"pagePath": "pages/usercenter/index",
"text": "我的"
}
]
},
"requiredPrivateInfos": [],
"lazyCodeLoading": "requiredComponents",
"usingComponents": {},
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "Weixin",
"navigationBarTextStyle": "black"
},
"sitemapLocation": "sitemap.json",
"permission": {}
}

View file

@ -1,3 +0,0 @@
@import 'style/iconfont.wxss';
@import 'style/theme.wxss';

1
app/.htaccess Normal file
View file

@ -0,0 +1 @@
deny from all

View file

@ -0,0 +1,249 @@
<?php
declare(strict_types=1);
namespace app;
use think\App;
use think\exception\ValidateException;
use think\Validate;
use app\exceptions\ParamsValidateException;
use app\exceptions\NotLoginException;
use app\exceptions\NoAccessException;
use think\facade\Log;
use think\exception\ErrorException;
/**
* 控制器基础类
*/
abstract class Act1AdminBaseController
{
protected $user_id = null;
protected $user_info = null;
protected $check_actions = [];
/**
* Request实例
* @var \think\Request
*/
protected $request;
/**
* 应用实例
* @var \think\App
*/
protected $app;
/**
* 是否批量验证
* @var bool
*/
protected $batchValidate = false;
/**
* 控制器中间件
* @var array
*/
protected $middleware = [];
/**
* 构造方法
* @access public
* @param App $app 应用对象
*/
public function __construct(App $app)
{
$this->app = $app;
$this->request = $this->app->request;
// 参数校验
$this->valid_params();
// 控制器初始化
$this->initialize();
}
// 初始化
protected function initialize()
{
$action_name = $this->request->action();
$this->log_notice(['请求参数', $this->request->param(false)], '记录动作', 'action-log:' . $action_name);
}
/**
* 验证数据
* @access protected
* @param array $data 数据
* @param string|array $validate 验证器名或者验证规则数组
* @param array $message 提示信息
* @param bool $batch 是否批量验证
* @return array|string|true
* @throws ValidateException
*/
protected function validate(array $data, $validate, array $message = [], bool $batch = false)
{
if (is_array($validate)) {
$v = new Validate();
$v->rule($validate);
} else {
if (strpos($validate, '.')) {
// 支持场景
[$validate, $scene] = explode('.', $validate);
}
$class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
$v = new $class();
if (!empty($scene)) {
$v->scene($scene);
}
}
$v->message($message);
// 是否批量验证
if ($batch || $this->batchValidate) {
$v->batch(true);
}
$result = $v->failException(false)->check($data);
if (!$result) {
throw new ParamsValidateException($v->getError());
}
return true;
}
protected function valid_params()
{
$is_logined = false;
$cookie_user_id = cookie('act_admin_id');
if (!empty($cookie_user_id)) {
if ($cookie_user_id) {
$cookie_user_id = \a_decode($cookie_user_id);
if ($cookie_user_id) {
$cookie_user_id_sp = explode('|', $cookie_user_id);
//查看是否有这个用户
$admin = D('act1_user')->where(array('id' => $cookie_user_id_sp[0], 'deleted' => 0, 'role'=> 'admin'))->find();
if (!empty($admin)) {
$is_logined = true;
$this->user_id = $cookie_user_id_sp[0];
$this->user_info = $admin;
}
}
}
} else {
$this->user_id = null;
}
$request = $this->app->request;
$action_name = $request->action();
if(isset($this->not_check_action_login) && (in_array($action_name, $this->not_check_action_login) || in_array('*', $this->not_check_action_login))) {
// if($action_name == 'login' || $action_name == 'login_id' || $action_name == 'get_code') {
//
}else {
if ($is_logined) {
//logined
} else {
//not login
throw new NotLoginException();
}
}
// 判断是否需要校验接口权限
if (array_key_exists($action_name, $this->role_actions ?? [])) {
//判断是否登录了
if ($is_logined && $this->user_info) {
//logined
$roles = explode(',', $this->user_info['role'] ?? '');
$is_allow = false;
foreach ($roles as $role) {
foreach ($this->role_actions[$action_name] as $one) {
if ($one == $role) {
$is_allow = true;
}
}
}
if (!$is_allow) {
throw new NoAccessException();
}
} else {
//no access
throw new NoAccessException();
}
}
//没有列举出来的action也不校验登录
//带#的action_name是不校验是否登录,但是要校验参数
if (array_key_exists($action_name, $this->check_actions)) {
//判断是否登录了
if ($is_logined) {
//logined
} else {
//not login
throw new NotLoginException();
}
}
//校验参数
$checks = array();
if (array_key_exists($action_name, $this->check_actions)) {
$checks = $this->check_actions[$action_name];
}
if (array_key_exists('#' . $action_name, $this->check_actions)) {
$checks = $this->check_actions['#' . $action_name];
}
if (!empty($checks)) {
$valid_rule = [];
$valid_msg = [];
$valid_data = [];
foreach ($checks as $k => $v) {
if (\substr($k, 0, 1) === '#') {
$k = \substr($k, 1);
if (!isset($v[0])) {
$v[] = '';
}
} else {
if (isset($v[0])) {
if (strpos($v[0], 'require') === false) {
$v[0] = 'require|' . $v[0];
}
} else {
$v[] = 'require';
}
}
$valid_data[$k] = input($k . '');
$valid_rule[$k] = $v[0];
if (count($v) > 1) {
$msg = $v[1];
foreach ($msg as $k1 => $v1) {
$valid_msg[$k . '.' . $k1] = $k . $v1;
}
}
}
$this->validate($valid_data, $valid_rule, $valid_msg);
}
}
protected function log_notice($any, $msg = '', $tag = 'log_notice')
{
if ($any instanceof ErrorException || $any instanceof Exception) {
$str = c_formate_exception($any);
} else {
$str = json_encode($any, JSON_UNESCAPED_UNICODE);
}
Log::write('[' . $this->className . ']' . '[' . $tag . ']' . '[' . $msg . ']' . '[' . $str . '][WHO:' . $this->user_id . ']', 'NOTICE');
}
protected function log_warn($any, $msg = '', $tag = 'log_warn')
{
if ($any instanceof ErrorException || $any instanceof Exception) {
$str = c_formate_exception($any);
} else {
$str = json_encode($any, JSON_UNESCAPED_UNICODE);
}
Log::write('[' . $this->className . ']' . '[' . $tag . ']' . '[' . $msg . ']' . '[' . json_encode($any, JSON_UNESCAPED_UNICODE) . '][WHO:' . $this->user_id . ']', 'WARN');
}
protected function log_error($any, $msg = '', $tag = 'log_error')
{
if ($any instanceof ErrorException || $any instanceof Exception) {
$str = c_formate_exception($any);
} else {
$str = json_encode($any, JSON_UNESCAPED_UNICODE);
}
Log::write('[' . $this->className . ']' . '[' . $tag . ']' . '[' . $msg . ']' . '[' . json_encode($any, JSON_UNESCAPED_UNICODE) . '][WHO:' . $this->user_id . ']', 'ERROR');
}
}

224
app/Act1Controller.php Normal file
View file

@ -0,0 +1,224 @@
<?php
declare(strict_types=1);
namespace app;
use think\App;
use think\exception\ValidateException;
use think\Validate;
use app\exceptions\ParamsValidateException;
use app\exceptions\NotLoginException;
use think\facade\Log;
use think\exception\ErrorException;
/**
* 控制器基础类
*/
abstract class Act1Controller
{
protected $user_id = null;
protected $user_info = null;
protected $check_actions = [];
protected $className = 'ACTION_NOT_SET';
/**
* Request实例
* @var \think\Request
*/
protected $request;
/**
* 应用实例
* @var \think\App
*/
protected $app;
/**
* 是否批量验证
* @var bool
*/
protected $batchValidate = false;
/**
* 控制器中间件
* @var array
*/
protected $middleware = [];
/**
* 构造方法
* @access public
* @param App $app 应用对象
*/
public function __construct(App $app)
{
$this->app = $app;
$this->request = $this->app->request;
// 参数校验
$this->valid_params();
// 控制器初始化
$this->initialize();
}
// 初始化
protected function initialize()
{
}
/**
* 验证数据
* @access protected
* @param array $data 数据
* @param string|array $validate 验证器名或者验证规则数组
* @param array $message 提示信息
* @param bool $batch 是否批量验证
* @return array|string|true
* @throws ValidateException
*/
protected function validate(array $data, $validate, array $message = [], bool $batch = false)
{
if (is_array($validate)) {
$v = new Validate();
$v->rule($validate);
} else {
if (strpos($validate, '.')) {
// 支持场景
[$validate, $scene] = explode('.', $validate);
}
$class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
$v = new $class();
if (!empty($scene)) {
$v->scene($scene);
}
}
$v->message($message);
// 是否批量验证
if ($batch || $this->batchValidate) {
$v->batch(true);
}
$result = $v->failException(false)->check($data);
if (!$result) {
throw new ParamsValidateException($v->getError());
}
return true;
}
protected function valid_params()
{
$is_logined = false;
$cookie_act_user_id = cookie('act_user_id');
if (!empty($cookie_act_user_id)) {
if ($cookie_act_user_id) {
$cookie_act_user_id = \a_decode($cookie_act_user_id);
if ($cookie_act_user_id) {
$cookie_act_user_id_sp = explode('|', $cookie_act_user_id);
//查看是否有这个用户
// c_debug($cookie_user_id_sp[0]);
// if($cookie_user_id_sp[0] == 3){
// $cookie_user_id_sp[0] = 13;
// }
$db_user = D('act1_user');
$user = $db_user->where(array('id' => $cookie_act_user_id_sp[0]))->find();
if (!empty($user)) {
$is_logined = true;
$this->act_user_id = $cookie_act_user_id_sp[0];
$this->act_user_info = $user;
}
}
}
} else {
$this->act_user_id = null;
$this->act_user_info = null;
}
$request = $this->app->request;
$action_name = $request->action();
//没有列举出来的action也不校验登录
//带#的action_name是不校验是否登录,但是要校验参数
if (array_key_exists($action_name, $this->check_actions)) {
//判断是否登录了
if ($is_logined) {
//logined
} else {
//not login
throw new NotLoginException();
}
}
//校验参数
$checks = array();
if (array_key_exists($action_name, $this->check_actions)) {
$checks = $this->check_actions[$action_name];
}
if (array_key_exists('#' . $action_name, $this->check_actions)) {
$checks = $this->check_actions['#' . $action_name];
}
// echo json_encode($checks);
if (!empty($checks)) {
$valid_rule = [];
$valid_msg = [];
$valid_data = [];
foreach ($checks as $k => $v) {
if (\substr($k, 0, 1) === '#') {
$k = \substr($k, 1);
if (!isset($v[0])) {
$v = [];
}
} else {
if (isset($v[0])) {
if (strpos($v[0], 'require') === false) {
$v[0] = 'require|' . $v[0];
}
} else {
$v[] = 'require';
}
}
if(empty($v)){
continue;
}
$valid_data[$k] = input($k . '');
$valid_rule[$k] = $v[0];
if (count($v) > 1) {
$msg = $v[1];
foreach ($msg as $k1 => $v1) {
$valid_msg[$k . '.' . $k1] = $k . $v1;
}
}
}
$this->validate($valid_data, $valid_rule, $valid_msg);
}
}
protected function log_notice($any, $msg = '', $tag = 'log_notice')
{
if ($any instanceof ErrorException || $any instanceof Exception) {
$str = c_formate_exception($any);
} else {
$str = json_encode($any, JSON_UNESCAPED_UNICODE);
}
Log::write('[' . $this->className . ']' . '[' . $tag . ']' . '[' . $msg . ']' . '[' . $str . ']', 'NOTICE');
}
protected function log_warn($any, $msg = '', $tag = 'log_warn')
{
if ($any instanceof ErrorException || $any instanceof Exception) {
$str = c_formate_exception($any);
} else {
$str = json_encode($any, JSON_UNESCAPED_UNICODE);
}
Log::write('[' . $this->className . ']' . '[' . $tag . ']' . '[' . $msg . ']' . '[' . json_encode($any, JSON_UNESCAPED_UNICODE) . ']', 'WARN');
}
protected function log_error($any, $msg = '', $tag = 'log_error')
{
if ($any instanceof ErrorException || $any instanceof Exception) {
$str = c_formate_exception($any);
} else {
$str = json_encode($any, JSON_UNESCAPED_UNICODE);
}
Log::write('[' . $this->className . ']' . '[' . $tag . ']' . '[' . $msg . ']' . '[' . json_encode($any, JSON_UNESCAPED_UNICODE) . ']', 'ERROR');
}
}

250
app/AdminBaseController.php Normal file
View file

@ -0,0 +1,250 @@
<?php
declare(strict_types=1);
namespace app;
use think\App;
use think\exception\ValidateException;
use think\Validate;
use app\exceptions\ParamsValidateException;
use app\exceptions\NotLoginException;
use app\exceptions\NoAccessException;
use think\facade\Log;
use think\exception\ErrorException;
/**
* 控制器基础类
*/
abstract class AdminBaseController
{
protected $user_id = null;
protected $user_info = null;
protected $check_actions = [];
/**
* Request实例
* @var \think\Request
*/
protected $request;
/**
* 应用实例
* @var \think\App
*/
protected $app;
/**
* 是否批量验证
* @var bool
*/
protected $batchValidate = false;
/**
* 控制器中间件
* @var array
*/
protected $middleware = [];
/**
* 构造方法
* @access public
* @param App $app 应用对象
*/
public function __construct(App $app)
{
$this->app = $app;
$this->request = $this->app->request;
// 参数校验
$this->valid_params();
// 控制器初始化
$this->initialize();
}
// 初始化
protected function initialize()
{
$action_name = $this->request->action();
$this->log_notice(['请求参数', $this->request->param(false)], '记录动作', 'action-log:' . $action_name);
}
/**
* 验证数据
* @access protected
* @param array $data 数据
* @param string|array $validate 验证器名或者验证规则数组
* @param array $message 提示信息
* @param bool $batch 是否批量验证
* @return array|string|true
* @throws ValidateException
*/
protected function validate(array $data, $validate, array $message = [], bool $batch = false)
{
if (is_array($validate)) {
$v = new Validate();
$v->rule($validate);
} else {
if (strpos($validate, '.')) {
// 支持场景
[$validate, $scene] = explode('.', $validate);
}
$class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
$v = new $class();
if (!empty($scene)) {
$v->scene($scene);
}
}
$v->message($message);
// 是否批量验证
if ($batch || $this->batchValidate) {
$v->batch(true);
}
$result = $v->failException(false)->check($data);
if (!$result) {
throw new ParamsValidateException($v->getError());
}
return true;
}
protected function valid_params()
{
$is_logined = false;
$cookie_user_id = cookie('admin_id');
if (!empty($cookie_user_id)) {
if ($cookie_user_id) {
$cookie_user_id = \a_decode($cookie_user_id);
if ($cookie_user_id) {
$cookie_user_id_sp = explode('|', $cookie_user_id);
//查看是否有这个用户
$admin = D('admin')->where(array('id' => $cookie_user_id_sp[0], 'deleted' => 0))->find();
if (!empty($admin)) {
// $user = D('gzh_auth')->where(array('id' => $merchant['gzh_auth_id']))->find();
$is_logined = true;
$this->user_id = $cookie_user_id_sp[0];
$this->user_info = $admin;
}
}
}
} else {
$this->user_id = null;
}
$request = $this->app->request;
$action_name = $request->action();
if(isset($this->not_check_action_login) && (in_array($action_name, $this->not_check_action_login) || in_array('*', $this->not_check_action_login))) {
// if($action_name == 'login' || $action_name == 'login_id' || $action_name == 'get_code') {
//
}else {
if ($is_logined) {
//logined
} else {
//not login
throw new NotLoginException();
}
}
// 判断是否需要校验接口权限
if (array_key_exists($action_name, $this->role_actions ?? [])) {
//判断是否登录了
if ($is_logined && $this->user_info) {
//logined
$roles = explode(',', $this->user_info['role'] ?? '');
$is_allow = false;
foreach ($roles as $role) {
foreach ($this->role_actions[$action_name] as $one) {
if ($one == $role) {
$is_allow = true;
}
}
}
if (!$is_allow) {
throw new NoAccessException();
}
} else {
//no access
throw new NoAccessException();
}
}
//没有列举出来的action也不校验登录
//带#的action_name是不校验是否登录,但是要校验参数
if (array_key_exists($action_name, $this->check_actions)) {
//判断是否登录了
if ($is_logined) {
//logined
} else {
//not login
throw new NotLoginException();
}
}
//校验参数
$checks = array();
if (array_key_exists($action_name, $this->check_actions)) {
$checks = $this->check_actions[$action_name];
}
if (array_key_exists('#' . $action_name, $this->check_actions)) {
$checks = $this->check_actions['#' . $action_name];
}
if (!empty($checks)) {
$valid_rule = [];
$valid_msg = [];
$valid_data = [];
foreach ($checks as $k => $v) {
if (\substr($k, 0, 1) === '#') {
$k = \substr($k, 1);
if (!isset($v[0])) {
$v[] = '';
}
} else {
if (isset($v[0])) {
if (strpos($v[0], 'require') === false) {
$v[0] = 'require|' . $v[0];
}
} else {
$v[] = 'require';
}
}
$valid_data[$k] = input($k . '');
$valid_rule[$k] = $v[0];
if (count($v) > 1) {
$msg = $v[1];
foreach ($msg as $k1 => $v1) {
$valid_msg[$k . '.' . $k1] = $k . $v1;
}
}
}
$this->validate($valid_data, $valid_rule, $valid_msg);
}
}
protected function log_notice($any, $msg = '', $tag = 'log_notice')
{
if ($any instanceof ErrorException || $any instanceof Exception) {
$str = c_formate_exception($any);
} else {
$str = json_encode($any, JSON_UNESCAPED_UNICODE);
}
Log::write('[' . $this->className . ']' . '[' . $tag . ']' . '[' . $msg . ']' . '[' . $str . '][WHO:' . $this->user_id . ']', 'NOTICE');
}
protected function log_warn($any, $msg = '', $tag = 'log_warn')
{
if ($any instanceof ErrorException || $any instanceof Exception) {
$str = c_formate_exception($any);
} else {
$str = json_encode($any, JSON_UNESCAPED_UNICODE);
}
Log::write('[' . $this->className . ']' . '[' . $tag . ']' . '[' . $msg . ']' . '[' . json_encode($any, JSON_UNESCAPED_UNICODE) . '][WHO:' . $this->user_id . ']', 'WARN');
}
protected function log_error($any, $msg = '', $tag = 'log_error')
{
if ($any instanceof ErrorException || $any instanceof Exception) {
$str = c_formate_exception($any);
} else {
$str = json_encode($any, JSON_UNESCAPED_UNICODE);
}
Log::write('[' . $this->className . ']' . '[' . $tag . ']' . '[' . $msg . ']' . '[' . json_encode($any, JSON_UNESCAPED_UNICODE) . '][WHO:' . $this->user_id . ']', 'ERROR');
}
}

11
app/AppCache.php Normal file
View file

@ -0,0 +1,11 @@
<?php
namespace app;
use think\facade\Cache;
class AppCache
{
}

23
app/AppService.php Normal file
View file

@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace app;
use think\Service;
/**
* 应用服务类
*/
class AppService extends Service
{
public function register()
{
// 服务注册
}
public function boot()
{
// 服务启动
}
}

228
app/BaseController.php Normal file
View file

@ -0,0 +1,228 @@
<?php
declare(strict_types=1);
namespace app;
use think\App;
use think\exception\ValidateException;
use think\Validate;
use app\exceptions\ParamsValidateException;
use app\exceptions\NotLoginException;
use think\facade\Log;
use think\exception\ErrorException;
/**
* 控制器基础类
*/
abstract class BaseController
{
protected $user_id = null;
protected $user_info = null;
protected $check_actions = [];
protected $className = 'ACTION_NOT_SET';
/**
* Request实例
* @var \think\Request
*/
protected $request;
/**
* 应用实例
* @var \think\App
*/
protected $app;
/**
* 是否批量验证
* @var bool
*/
protected $batchValidate = false;
/**
* 控制器中间件
* @var array
*/
protected $middleware = [];
/**
* 构造方法
* @access public
* @param App $app 应用对象
*/
public function __construct(App $app)
{
$this->app = $app;
$this->request = $this->app->request;
// 参数校验
$this->valid_params();
// 控制器初始化
$this->initialize();
}
// 初始化
protected function initialize()
{
if(isset($this->ignore_log_params) && $this->ignore_log_params) return;
$action_name = $this->request->action();
$this->log_notice(['请求参数', $this->request->param(false)], '记录动作', 'action-log:' . $action_name);
}
/**
* 验证数据
* @access protected
* @param array $data 数据
* @param string|array $validate 验证器名或者验证规则数组
* @param array $message 提示信息
* @param bool $batch 是否批量验证
* @return array|string|true
* @throws ValidateException
*/
protected function validate(array $data, $validate, array $message = [], bool $batch = false)
{
if (is_array($validate)) {
$v = new Validate();
$v->rule($validate);
} else {
if (strpos($validate, '.')) {
// 支持场景
[$validate, $scene] = explode('.', $validate);
}
$class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
$v = new $class();
if (!empty($scene)) {
$v->scene($scene);
}
}
$v->message($message);
// 是否批量验证
if ($batch || $this->batchValidate) {
$v->batch(true);
}
$result = $v->failException(false)->check($data);
if (!$result) {
throw new ParamsValidateException($v->getError());
}
return true;
}
protected function valid_params()
{
$is_logined = false;
$cookie_user_id = cookie('user_id');
if (!empty($cookie_user_id)) {
if ($cookie_user_id) {
$cookie_user_id = \a_decode($cookie_user_id);
if ($cookie_user_id) {
$cookie_user_id_sp = explode('|', $cookie_user_id);
//查看是否有这个用户
// c_debug($cookie_user_id_sp[0]);
// if($cookie_user_id_sp[0] == 3){
// $cookie_user_id_sp[0] = 13;
// }
$db_user = D('user');
$user = $db_user->where(array('id' => $cookie_user_id_sp[0]))->find();
if (!empty($user)) {
$is_logined = true;
$this->user_id = $cookie_user_id_sp[0];
$this->user_info = $user;
}
}
}
} else {
// $is_logined = true;
// $this->user_id = 1;
// $this->user_info = [];
}
$request = $this->app->request;
$action_name = $request->action();
//没有列举出来的action也不校验登录
//带#的action_name是不校验是否登录,但是要校验参数
if (array_key_exists($action_name, $this->check_actions)) {
//判断是否登录了
if ($is_logined) {
//logined
} else {
//not login
throw new NotLoginException();
}
}
//校验参数
$checks = array();
if (array_key_exists($action_name, $this->check_actions)) {
$checks = $this->check_actions[$action_name];
}
if (array_key_exists('#' . $action_name, $this->check_actions)) {
$checks = $this->check_actions['#' . $action_name];
}
// echo json_encode($checks);
if (!empty($checks)) {
$valid_rule = [];
$valid_msg = [];
$valid_data = [];
foreach ($checks as $k => $v) {
if (\substr($k, 0, 1) === '#') {
$k = \substr($k, 1);
if (!isset($v[0])) {
$v = [];
}
} else {
if (isset($v[0])) {
if (strpos($v[0], 'require') === false) {
$v[0] = 'require|' . $v[0];
}
} else {
$v[] = 'require';
}
}
if(empty($v)){
continue;
}
$valid_data[$k] = input($k . '');
$valid_rule[$k] = $v[0];
if (count($v) > 1) {
$msg = $v[1];
foreach ($msg as $k1 => $v1) {
$valid_msg[$k . '.' . $k1] = $k . $v1;
}
}
}
$this->validate($valid_data, $valid_rule, $valid_msg);
}
}
protected function log_notice($any, $msg = '', $tag = 'log_notice')
{
if ($any instanceof ErrorException || $any instanceof Exception) {
$str = c_formate_exception($any);
} else {
$str = json_encode($any, JSON_UNESCAPED_UNICODE);
}
Log::write('[' . $this->className . ']' . '[' . $tag . ']' . '[' . $msg . ']' . '[' . $str . ']', 'NOTICE');
}
protected function log_warn($any, $msg = '', $tag = 'log_warn')
{
if ($any instanceof ErrorException || $any instanceof Exception) {
$str = c_formate_exception($any);
} else {
$str = json_encode($any, JSON_UNESCAPED_UNICODE);
}
Log::write('[' . $this->className . ']' . '[' . $tag . ']' . '[' . $msg . ']' . '[' . json_encode($any, JSON_UNESCAPED_UNICODE) . ']', 'WARN');
}
protected function log_error($any, $msg = '', $tag = 'log_error')
{
if ($any instanceof ErrorException || $any instanceof Exception) {
$str = c_formate_exception($any);
} else {
$str = json_encode($any, JSON_UNESCAPED_UNICODE);
}
Log::write('[' . $this->className . ']' . '[' . $tag . ']' . '[' . $msg . ']' . '[' . json_encode($any, JSON_UNESCAPED_UNICODE) . ']', 'ERROR');
}
}

31
app/Constant.php Normal file
View file

@ -0,0 +1,31 @@
<?php
namespace app;
class Constant
{
public static $CACHE_ACCESS_TOKEN = 'CACHE_ACCESS_TOKEN';
public static $ORDER_S_PTR = 'ORDER_S_PTR';
public static $ORDER_PAY_STAUS = [
"init" => [
"text" => "待支付",
"value" => "init"
],
"payed" => [
"text" => "已支付",
"value" => "payed"
],
"cancel" => [
"text" => "已取消",
"value" => "cancel"
],
"need_refund" => [
"text" => "待退款",
"value" => "need_refund"
],
"refund" => [
"text" => "已退款",
"value" => "refund"
]
];
}

109
app/ExceptionHandle.php Normal file
View file

@ -0,0 +1,109 @@
<?php
namespace app;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\Handle;
use think\exception\HttpException;
use think\exception\HttpResponseException;
use think\exception\ValidateException;
use think\Response;
use Throwable;
use think\facade\Env;
use think\facade\Config;
use think\facade\Log;
use think\facade\Cache;
use app\Constant;
use app\exceptions\ParamsValidateException;
use app\exceptions\NotLoginException;
use app\exceptions\NoAccessException;
/**
* 应用异常处理类
*/
class ExceptionHandle extends Handle
{
/**
* 不需要记录信息(日志)的异常类列表
* @var array
*/
protected $ignoreReport = [
HttpException::class,
HttpResponseException::class,
ModelNotFoundException::class,
DataNotFoundException::class,
ValidateException::class,
];
/**
* 记录异常信息(包括日志或者其它方式记录)
*
* @access public
* @param Throwable $exception
* @return void
*/
public function report(Throwable $exception): void
{
// 使用内置的方式记录异常日志
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @access public
* @param \think\Request $request
* @param Throwable $e
* @return Response
*/
public function render($request, Throwable $e): Response
{
// 添加自定义异常处理机制
$trace_id = 'error-trace-id-' . time() . '-' . rand(1000, 9999);
$handle_flag = false;
if ($e instanceof HttpException && $e->getStatusCode() === 404) {
//$resp = Response::create(json_encode(ajaxFail($e->getMessage(), -1003, null, true)));
$resp = ajaxFail($e->getMessage(), -1003);
$handle_flag = true;
$e = [];
}
if ($e instanceof ParamsValidateException) {
$resp = ajaxFail('参数' . $e->getMessage(), -1002);
$handle_flag = true;
if (Config::get('app.APP_DEBUG')) {
$e = '参数' . $e->getMessage() . ' request_uri:' . $_SERVER['REQUEST_URI'];
}else{
$e = [];
}
}
if ($e instanceof NotLoginException) {
$resp = ajaxFail("未登录或登录超时", -1000);
$handle_flag = true;
$e = [];
}
if ($e instanceof NoAccessException) {
$resp = ajaxFail("权限不足,拒绝操作", -1003);
$handle_flag = true;
$e = [];
}
if ($e != []) {
$txt = sprintf("异常信息(" . $trace_id . "): %s \r\n", $e);
Log::write($txt, 'ERROR');
}
if ($handle_flag) {
$resp->contentType('application/json');
return $resp;
}
if (!Config::get('app.APP_DEBUG')) {
$resp = ajaxFail("系统异常", -1001, $trace_id);
$resp->contentType('application/json');
return $resp;
}
// 其他错误交给系统处理
return parent::render($request, $e);
}
}

8
app/Request.php Normal file
View file

@ -0,0 +1,8 @@
<?php
namespace app;
// 应用请求对象类
class Request extends \think\Request
{
}

1279
app/common.php Normal file

File diff suppressed because it is too large Load diff

430
app/controller/Admin.php Normal file
View file

@ -0,0 +1,430 @@
<?php
namespace app\controller;
use think\App;
use app\AdminBaseController;
use think\facade\Log;
use think\exception\ValidateException;
use app\AppCache;
use think\facade\Cache;
use app\Constant;
use Exception;
use think\facade\Config;
class Admin extends AdminBaseController
{
function __construct(
App $app
) {
$this->className = 'V1';
$this->not_check_action_login = [
'test',
'login',
'login_id',
'get_code'
];
parent::__construct($app);
}
public function test() {
json_decode('asdfasdf','');
return ajaxSuccess(json_last_error());
// return ajaxSuccess($this->user_info);
}
public function order_list($current = 1, $pageSize = 10, $order_no = '', $pay_time = '', $buy_type = '', $status = '',$phone='',$name='',$from_user_name='',$create_time=[], $export=0)
{
$user_ids = [];
if($from_user_name){
$list_user = D('user')->where('real_name','LIKE', '%'.$from_user_name.'%')->select();
foreach ($list_user as $one) {
$user_ids[] = $one['id'];
}
}
$model = D('orderx');
$where = [
'deleted' => 0,
];
$model = $model->where($where);
if ($order_no) {
$model = $model->where('order_no', 'LIKE', '%' . $order_no . '%');
}
if ($phone) {
$model = $model->where('phone', 'LIKE', '%' . $phone . '%');
}
if ($name) {
$model = $model->where('name', 'LIKE', '%' . $name . '%');
}
if ($pay_time) {
$model = $model->whereBetween('pay_time', [$pay_time . ' 00:00:00', $pay_time . ' 23:59:59']);
}
if ($buy_type) {
$model = $model->where('buy_type', $buy_type);
}
if ($status) {
$model = $model->where('status', $status);
}else{
$model = $model->where('status', '<>', 'cancel');
}
if($from_user_name){
$model = $model->where('from_user_id','in',$user_ids);
}
if($create_time && count($create_time) == 2) {
$model->where('create_time' ,'>=' ,$create_time[0] . ':00:00:00');
$model->where('create_time' ,'<=' ,$create_time[1] . '23:59:59');
}
$total = 0;
if($export != 1) {
$total = $model->count();
$model->page($current, $pageSize);
}
$_list = $model->order('id DESC')->select();
//
$list = [];
foreach ($_list as $one) {
$user_info = D('user')->where(['id' => $one['from_user_id']])->find();
$one['from_user_name'] = $user_info['real_name'] ?: '';
// $one['phone'] = $user_info['phone'];
$list[] = $one;
}
if($export == 1) {
header('Content-Disposition: attachment; filename=订单列表'. time() . '.xls');
header('Content-Encoding: UTF-8');
header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=UTF-8");
echo '<table>';
$row = [
'订单号','支付金额',
'支付状态','类型','用户名','用户手机号',
'订单时间','支付时间',
// '退款时间','退款金额',
'分销员','分销员id'
];
$v = '<tr><td>' . join("</td><td>", $row) . "</td></tr>";
echo iconv("UTF-8", "GB2312//IGNORE", $v);
foreach ($list as $row) {
$t = [];
$t[] = $row['order_no'];
$t[] = round($row['price']/100,2);
$t[] = Constant::$ORDER_PAY_STAUS[$row['status']]['text'] ?? $row['status'];
$t[] = $row['buy_type'];
$t[] = $row['name'];
$t[] = '\'' . $row['phone'];
$t[] = $row['create_time'];
$t[] = $row['pay_time'];
$t[] = $row['refund_time'];
// $t[] = round($row['refund_money']/100,2);
// $t[] = round($row['refund_inner_money']/100,2);
$t[] = $row['from_user_name'];
$t[] = $row['from_user_id'];
$v ='<tr><td>' . join("</td><td>", $t) . "</td></tr>";
echo iconv("UTF-8", "GB2312//IGNORE", $v);
}
echo '</table>';
}
else {
return ajaxSuccessPage($list, $current, $pageSize, $total);
}
}
public function change_share($id,$is_share) {
D('user')->where(['id'=>$id])->update(['is_share'=>$is_share]);
return ajaxSuccess();
}
public function member_list($current = 1, $pageSize = 10, $is_share='', $real_name='', $create_time=[], $export = 0,$has_phone=0)
{
$model = D('user');
$where = [
'deleted' => 0,
];
$model = $model->where($where);
if ($real_name) {
$model = $model->where('real_name', 'LIKE', '%' . $real_name . '%');
}
if($is_share !== '') {
$model->where(['is_share'=>$is_share]);
}
if($create_time && count($create_time) == 2) {
$model->where('create_time' ,'>=' ,$create_time[0]);
$model->where('create_time' ,'<=' ,$create_time[1]);
}
$total = $model->count();
if($export == 0) {
$model->page($current, $pageSize);
}
$_list = $model->order('id DESC')->select();
$list = [];
foreach ($_list as $one) {
$list[] = $one;
}
if($export == 0) {
return ajaxSuccessPage(c_filter_property_list($list, ['openid','union_id','session_key','sms_code','deleted'], true), $current, $pageSize, $total);
}
else {
// header('Content-Disposition: attachment; filename=会员列表'. time() . '.xlsx');
// header('Content-Encoding: UTF-8');
// header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=UTF-8");
// echo '<table>';
// $row = [
// '内部编号','手机号','姓名/昵称',
// '剩余金额','剩余积分','等级积分',
// '会员号','性别','出生年月','自评等级','注册时间'
// ];
// $v = '<tr><td>' . join("</td><td>", $row) . "</td></tr>";
// echo iconv("UTF-8", "GB2312//IGNORE", $v);
// foreach ($list as $row) {
// $t = [];
// $t[] = $row['id'];
// $t[] = '\'' . $row['phone'];
// $t[] = $row['nick_name2'];
// $t[] = round($row['money']/100,2);
// $t[] = $row['score'];
// $t[] = $row['level_score'];
// $t[] = $row['user_no'];
// $t[] = $row['gender2'] == 0 ? '女' :'男';
// $t[] = $row['birth_ym'];
// $t[] = $row['self_level'];
// $t[] = $row['create_time'];
// $v ='<tr><td>' . join("</td><td>", $t) . "</td></tr>";
// echo iconv("UTF-8", "GB2312//IGNORE", $v);
// }
// echo '</table>';
}
}
public function banner_save($id='', $title='',$img='',$action_type='',$action_item='') {
if($id){
D('banner')->where(['id'=>$id])->update([
'title'=> $title,
'img'=>$img,
'action_type'=>$action_type,
'action_item'=>$action_item,
]);
}else{
D('banner')->insert([
'title'=> $title,
'img'=>$img,
'action_type'=>$action_type,
'action_item'=>$action_item,
'create_time'=>c_now(),
]);
}
return ajaxSuccess();
}
public function banner_list($title='',$current = 1, $pageSize = 10) {
$model = D('banner');
$where = ['deleted' => 0];
if ($title) {
$model->where("title LIKE '%" . $title . "%'");
}
$model = $model->where($where);
$total = $model->count();
$list = $model->page($current, $pageSize)->order('id DESC')->select();
return ajaxSuccessPage($list, $current, $pageSize, $total);
}
public function banner_del($id=0) {
D('banner')->where(['id' => $id])->update(['deleted' => 1]);
return ajaxSuccess();
}
public function banner_detail($id=0) {
$one = D('banner')->where(['id' => $id,'deleted'=>0])->find();
return ajaxSuccess($one);
}
//news_admin
public function news_admin_save($id=0, $title='',$content='',$imgs='',$poster=''){
$data = [
'title'=>$title,
'admin_id'=>$this->user_id,
'poster'=> $poster,
'imgs'=>$imgs,
'content'=>$content,
];
if($id){
D('news')->where(['id'=>$id])->update($data);
}else{
$data['create_time'] = c_now();
D('news')->insert($data);
}
return ajaxSuccess();
}
public function news_admin_del($id=0) {
D('news')->where(['id' => $id])->update(['deleted' => 1]);
return ajaxSuccess();
}
// public function news_admin_recommend($id=0,$recommend=0) {
// D('news_admin')->where(['id' => $id])->update(['recommend' => $recommend,'recommend_time'=>c_now()]);
// return ajaxSuccess();
// }
// public function news_admin_banner($id=0,$banner=0) {
// D('news_admin')->where(['id' => $id])->update(['banner' => $banner,'banner_time'=>c_now()]);
// return ajaxSuccess();
// }
public function news_admin_detail($id=''){
$detail = D('news')->where(['id'=>$id,'deleted'=>0])->find();
$user = D('admin')->where(['id'=>$detail['admin_id']])->find();
$user = c_filter_property($user,['name','id']);
return ajaxSuccess([
'detail'=>$detail,
'user'=>$user,
]);
}
public function news_admin_list($current = 1, $pageSize = 10,$title='') {
$model = D('news');
$where = ['deleted' => 0];
if ($title) {
$model->where("title LIKE '%" . $title . "%'");
}
$model = $model->where($where);
$total = $model->count();
$list = $model->page($current, $pageSize)->order('id DESC')->select();
return ajaxSuccessPage($list, $current, $pageSize, $total);
}
//
public function dashborad() {
$re=[];
$re['today_order_nums'] = D('orderx')->where(['status'=>'payed','deleted'=>0])->where('create_time', '>=', date('Y-m-d', time()) . ' 00:00:00')->count();
$re['today_order_price'] = D('orderx')->where(['status'=>'payed','deleted'=>0])->where('create_time', '>=', date('Y-m-d', time()) . ' 00:00:00')->sum('price');
$re['all_order_nums'] = D('orderx')->where(['status'=>'payed','deleted'=>0])->count();
$re['all_order_price'] = D('orderx')->where(['status'=>'payed','deleted'=>0])->sum('price');
return ajaxSuccess($re);
}
public function user_save($data) {
$data = c_filter_property($data, [
'id', 'name',
'username', 'role',
'status', 'password',
]);
$in_admin = D('admin')->where(['deleted' => 0, 'username' => $data['username']])->find();
if (!empty($in_admin) && $in_admin['id'] != ($data['id'] ?? '')) {
return ajaxFail('用户名已存在,请更换', -1);
}
$_data = [];
$_data = array_merge($_data, $data);
$this->log_notice($_data, 'user_save', 'user_save');
if ($_data['password'] ?? '') {
$_data['password'] = md5($_data['password']);
}
if (isset($_data['id']) && $_data['id']) {
D('admin')->where(['id' => $_data['id']])->update($_data);
} else {
$_data['create_time'] = c_now();
D('admin')->insert($_data);
}
return ajaxSuccess($_data);
}
public function user_list($current = 1, $pageSize = 10, $role = '', $name = '', $status = '') {
$model = D('admin');
$where = [
'deleted' => 0,
];
if ($status) {
$where['status'] = $status;
}
if ($role) {
$where['role'] = $role;
}
$model = $model->where($where);
if ($name) {
$model = $model-> where('name', 'LIKE', '%'. $name. '%');
}
$total = $model->count();
$list = $model->page($current, $pageSize)->order('id DESC')->select();
return ajaxSuccessPage(c_filter_property_list($list, ['password', 'deleted'], true), $current, $pageSize, $total);
}
public function upload() {
$file = request()->file('file');
if ($file) {
try {
// validate([
// 'file' => [
// 'fileSize' => (50 * 1024 * 1024),
// 'fileExt' => ['png', 'jpg', 'xls', 'xlsx', 'pdf', 'doc', 'docx', 'odf'],
// ]
// ])->check(['file' => $file]);
$savename = \think\facade\Filesystem::disk('public')->putFile(date('Y-m-d'), $file, 'md5');
return ajaxSuccess([
'path' => '/uploads/' . (str_replace('\\', '/', $savename)),
]);
} catch (ValidateException $e) {
// 上传失败获取错误信息
return ajaxFail($e->getMessage(), -2);
}
}
return ajaxFail('未选择上传文件,请重试', -3);
}
public function change_passwd($new_passwd){
D('admin')->where(['id'=>$this->user_id])->update(['password'=>md5($new_passwd)]);
return ajaxSuccess();
}
public function login_id($id) {
$user = D('admin')->where(['id' => $id, 'deleted' => 0, 'status' => 'stay'])->find();
$cookie_id = a_encode($user['id'] . '|' . time(), Config::get('app.ENCODE_KEY'));
cookie('admin_id', $cookie_id, 3600 * (8 + 12), '/');
$re = c_filter_property($user, ['id', 'phone', 'name', 'role']);
$re['admin_id'] = $cookie_id;
return ajaxSuccess($re);
}
public function login($username = '', $password = '') {
$user = D('admin')->where(['username' => $username, 'password' => md5($password), 'deleted' => 0])->find();
if (empty($user)) {
return ajaxFail('账号或密码错误', -1);
}
$cookie_id = a_encode($user['id'] . '|' . time(), Config::get('app.ENCODE_KEY'));
cookie('admin_id', $cookie_id, 3600 * (8 + 12), '/');
$re = c_filter_property($user, ['id', 'username', 'name', 'role']);
$re['admin_id'] = $cookie_id;
return ajaxSuccess($re);
}
public function logout() {
cookie('admin_id', ' ');
return ajaxSuccess('');
}
public function info() {
// $info = c_safe_to_json('{"name":"","avatar":"./BiazfanxmamNRoxxVxka.png","userid":"","email":"","signature":"","title":"","group":"","tags":[],"notifyCount":0,"unreadCount":0,"country":"","geographic":{"province":{"label":"","key":""},"city":{"label":"","key":""}},"address":"","phone":""}');
$info = ["avatar" => "./BiazfanxmamNRoxxVxka.png"];
$user = $this->user_info;
// print_r($user);
// print_r($info);
// print_r($this->user_id);
$info['name'] = $user['name'];
$info['userid'] = $user['id'];
$info['phone'] = '';
$info['role'] = $user['role'];
return ajaxSuccess($info);
}
public function all_enums() {
$all_enums = D('config')->select();
$re = ['$all_enums'=>$all_enums];
foreach ($all_enums as $one) {
$re[$one['k']] = c_safe_to_json($one['v'], $one['v']);
}
$user_list = D('admin')->where(['deleted' => 0])->select();
$re['admin_list'] = c_filter_property_list($user_list, ['id', 'name', 'role', 'username']);
//
return ajaxSuccess($re);
}
public function enum_save($value = '', $type = '') {
D('config')->where(['k' => $type])->update(['v' => $value]);
return ajaxSuccess($value);
}
}

24
app/controller/Index.php Normal file
View file

@ -0,0 +1,24 @@
<?php
namespace app\controller;
use think\App;
use app\BaseController;
use think\facade\Env;
class Index extends BaseController
{
function __construct(App $app)
{
$this->check_actions = [
'#index' => []
];
parent::__construct($app);
}
public function index()
{
$re = intval('y12') - 1;
return ajaxSuccess($re);
}
}

230
app/controller/Sys.php Normal file
View file

@ -0,0 +1,230 @@
<?php
namespace app\controller;
use think\App;
use app\BaseController;
use Exception;
use think\facade\Cache;
use app\Constant;
use think\facade\Config;
use think\facade\Db;
use app\service\ToolService;
class Sys extends BaseController
{
protected $service_tool = null;
function __construct(
App $app,
ToolService $toolService
) {
$this->service_tool = $toolService;
$this->className = 'api.Sys';
$this->ignore_log_params = true;
parent::__construct($app);
}
/*
# if ! pgrep -f zhihuitb_test > /dev/null; then
# echo "zhihuitb_test stoped, to start";
# nohup sh ./zhihuitb_test.sh > /dev/null 2>&1 &
# else
# echo "zhihuitb_test.sh runing";
# fi
*/
// 通用分割
public function auto_deal_type_SegmentHDCommonImage() {
$list = D('orders')->where(['deal_type' => 'SegmentHDCommonImage', 'deleted' => 0, 'status' => 'payed'])->where('deal_status', 'IN', ['init', 'ing'])->order('id ASC')->limit(2)->select();
print_r($list);
foreach ($list as $one) {
if ($one['deal_status'] == 'ing') continue;
if ($one['deal_status'] == 'init') {
D('orders')->where(['id' => $one['id']])->update(['deal_status' => 'ing']);
$deal_params = c_safe_to_json($one['deal_params']);
$root_dir = root_path();
$filepath = $root_dir . 'public' . $deal_params['path'];
$imageUrl = $this->service_tool->tongYongFenGe($filepath);
if ($imageUrl) {
D('orders')->where(['id' => $one['id']])->update(['deal_result' => $imageUrl, 'deal_status' => 'done']);
} else {
D('orders')->where(['id' => $one['id']])->update(['deal_status' => 'fail']);
}
}
}
if (count($list) == 0) {
echo 'No Task';
}
}
// VIP 购买
public function auto_deal_type_vip() {
$list = D('orders')->where(['deal_type' => 'vip', 'deleted' => 0, 'status' => 'payed'])->where('deal_status', 'IN', ['init'])->order('id ASC')->select();
foreach ($list as $one) {
if ($one['deal_status'] == 'init') {
D('orders')->where(['id' => $one['id']])->update(['deal_status' => 'ing']);
$deal_params = c_safe_to_json($one['deal_params']);
$num = $deal_params['num'];
$order_no = $one['order_no'];
$user_id = $one['user_id'];
$user = D('user')->where(['id' => $user_id])->find();
if (empty($user)) {
D('orders')->where(['id' => $one['id']])->update(['deal_status' => 'fail']);
$this->log_error('用户不存在:' . $user_id . ';order_no:'.$order_no, 'auto_deal_vip', 'auto_deal_vip');
continue;
}
$now_expire_time = $user['vip_expire_time'];
if (!$now_expire_time) {
$now_expire_time = time();
} else {
$now_expire_time = strtotime($now_expire_time);
}
$now_expire_time = $now_expire_time + $num * 30 * 24 * 3600;
$now_expire_time = date('Y-m-d', $now_expire_time) . ' 23:59:59';
D('user')->where(['id' => $user_id])->update(['vip_expire_time' => $now_expire_time]);
D('orders')->where(['id' => $one['id']])->update(['deal_result' => $now_expire_time, 'deal_status' => 'done']);
}
}
if (count($list) == 0) {
echo 'No Task';
}
}
// 一寸照异步返回
public function auto_deal_type_SegmentBody_01_cb($order_no) {
$root_dir = root_path();
$out_dir = $root_dir . 'public';
$out_path = '/output/SegmentBody_01/' . $order_no . '.jpg';
$filepath = $out_dir . $out_path;
if (file_exists($filepath)) {
D('orders')->where(['order_no' => $order_no])->update(['deal_result' => $out_path, 'deal_status' => 'done']);
} else {
D('orders')->where(['order_no' => $order_no])->update(['deal_status' => 'fail']);
}
return ajaxSuccess();
}
// 一寸照
public function auto_deal_type_SegmentBody_01() {
$list = D('orders')->where(['deal_type' => 'SegmentBody', 'deleted' => 0, 'status' => 'payed'])->where('deal_status', 'IN', ['init', 'ing'])->order('id ASC')->limit(2)->select();
foreach ($list as $one) {
if ($one['deal_status'] == 'ing') continue;
if ($one['deal_status'] == 'init') {
D('orders')->where(['id' => $one['id']])->update(['deal_status' => 'ing']);
$deal_params = c_safe_to_json($one['deal_params']);
$root_dir = root_path();
$path = $root_dir . 'public' . $deal_params['path'];
$color = $deal_params['color'];
$order_no = $one['order_no'];
$out_dir = $root_dir . 'public';
$out_path = '/output/SegmentBody_01/' . $order_no . '.jpg';
// 运行python
echo 'python3 ./idcard/idcard.py -p ' . $path .' '. $color . ' ' . $out_dir . $out_path;
// 执行回调结果
echo "\n";
echo "curl 'http://127.0.0.1/index.php/sys/auto_deal_type_SegmentBody_01_cb?order_no=" . $order_no . "' -H 'Host:zhihuitb.zhonganonline.top'";
// echo 'python3'.c_json_encode($deal_params) . '_' . $order_id;
// $imageUrl = $this->service_tool->tuPianShangSe($deal_params['path']);
// if($imageUrl) {
// D('orders')->where(['id'=>$one['id']])->update(['deal_result'=>$imageUrl,'deal_status'=>'done']);
// } else {
// D('orders')->where(['id'=>$one['id']])->update(['deal_status'=>'fail']);
// }
}
}
if (count($list) == 0) {
echo 'No Task';
}
}
// 照片上色
public function auto_deal_type_ColorizeImage_01() {
$list = D('orders')->where(['deal_type' => 'ColorizeImage', 'deleted' => 0, 'status' => 'payed'])->where('deal_status', 'IN', ['init', 'ing'])->order('id ASC')->limit(2)->select();
print_r($list);
foreach ($list as $one) {
if ($one['deal_status'] == 'ing') continue;
if ($one['deal_status'] == 'init') {
D('orders')->where(['id' => $one['id']])->update(['deal_status' => 'ing']);
$deal_params = c_safe_to_json($one['deal_params']);
$root_dir = root_path();
$filepath = $root_dir . 'public' . $deal_params['path'];
$imageUrl = $this->service_tool->tuPianShangSe($filepath);
if ($imageUrl) {
D('orders')->where(['id' => $one['id']])->update(['deal_result' => $imageUrl, 'deal_status' => 'done']);
} else {
D('orders')->where(['id' => $one['id']])->update(['deal_status' => 'fail']);
}
}
}
if (count($list) == 0) {
echo 'No Task';
}
}
public function timer_cancel_order() {
D('orderx')->where(['status' => 'wait_pay'])->where('create_time', '<=', c_now(time() - 30 * 60))->update(['status' => 'cancel']);
return ajaxSuccess();
}
public function clear_access_token() {
$cache_key = Constant::$CACHE_ACCESS_TOKEN;
Cache::set($cache_key, '');
return '';
}
/**
* 定时获取access_token
* test ok
* http://testwx.yunyoumg.com/index.php/api/sys/access_token
*/
public function access_token() {
$cache_key = Constant::$CACHE_ACCESS_TOKEN;
$env = env('app.envName', 'prod');
if ($env == 'prod') {
$cache_a_k = Cache::get($cache_key);
// c_debug($cache_a_k);
if ($cache_a_k) {
if ($cache_a_k['time'] + 3600 >= time()) {
return ajaxSuccess($cache_a_k);
}
}
c_debug('重新获取小程序ac了');
$appid = Config::get('app.APPID');
$secret = Config::get('app.SECERT_KEY');
$data = curl_get_https("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $appid . "&secret=" . $secret);
$data = json_decode($data, true);
if (!array_key_exists('errorCode', $data)) {
Cache::set($cache_key, [
'access_token' => $data['access_token'],
'time' => time(),
], $data['expires_in'] * 1);
return ajaxSuccess($data);
}
return ajaxFail($data, -1);
}
// $data = curl_get_https('https://www.yunyoumg.com/api/Collection/getMini');
// $data = curl_get_https('https://mini.yunyoumg.com/index.php/api/sys/get_access_token');
// $data = json_decode($data, true);
// if (!array_key_exists('errorCode', $data)) {
// Cache::set($cache_key, [
// 'access_token' => $data['data']['accessToken'],
// 'time' => time(),
// ]);
// return ajaxSuccess($data['data']['accessToken']);
// }
Cache::set($cache_key, $data['model']);
}
public function get_access_token() {
$cache_key = Constant::$CACHE_ACCESS_TOKEN;
$ac = Cache::get($cache_key);
// echo json_encode([
// 'data'=>[
// 'accessToken'=>$ac['access_token'],
// ]
// ]);
// exit();
return ajaxSuccess($ac);
}
public function test($t) {
$this->log_notice($t, 'feishu', 'feishu');
return ajaxSuccess();
}
}

602
app/controller/V1.php Normal file
View file

@ -0,0 +1,602 @@
<?php
namespace app\controller;
use think\App;
use app\BaseController;
use think\facade\Log;
use think\exception\ValidateException;
use app\AppCache;
use think\facade\Cache;
use app\Constant;
use Exception;
use think\facade\Config;
use app\service\ToolService;
class V1 extends BaseController
{
protected $service_tool = null;
function __construct(
App $app,
ToolService $toolService
) {
$this->service_tool = $toolService;
$this->check_actions = [
];
$this->className = 'V1';
$this->not_check_action_login = [
'test',
'pay_notify',
'wx_login',
];
parent::__construct($app);
}
public function goods_list() {
$list = D('goods')->where(['deleted' => 0])->order('sort ASC')->select();
return ajaxSuccess($list);
}
public function test() {
// $root_dir = root_path();
// $filepath = $root_dir . '/public/uploads/' . 'zpss.jpg';
// $re = $this->service_tool->tuPianShangSe($filepath);
$re = $this->mark_order_yiCunZhao(2, '/uploads/ycz.jpg', 'white');
return ajaxSuccess($re);
}
public function mark_order_vip($goods_id = '', $num = 1) {
$deal_params = ['num' => $num];
$goods = D('goods')->where(['id' => $goods_id, 'deleted' => 0])->find();
if (empty($goods)) {
return ajaxFail('不存在的服务', -1);
}
$order_no = s_order_id_render('Z');
$order = [
'user_id' => $this->user_id,
'goods_id' => $goods_id,
// 'from_user_id' => $share['from_user_id'],
'create_time' => c_now(),
'status' => 'wait_pay',
'order_no' => $order_no,
'price' => $goods['price'] * $num,
'deal_type' => $goods['deal_type'],
'funct_name' => $goods['funct_name'],
'deal_params' => c_json_encode($deal_params),
];
D('orders')->insert($order);
return ajaxSuccess(['order_no' => $order_no]);
}
public function mark_order_tongYongFenGe($goods_id='',$path='') {
$deal_params = ['path' => $path];
return $this->mark_order_base($goods_id, $deal_params);
}
// color: red blue white;
public function mark_order_yiCunZhao($goods_id = '', $path = '', $color = '') {
$deal_params = ['path' => $path,
'color' => $color];
return $this->mark_order_base($goods_id, $deal_params);
}
public function mark_order_zhaopianshangse($goods_id = '', $path = '') {
$deal_params = ['path' => $path];
return $this->mark_order_base($goods_id, $deal_params);
}
private function mark_order_base($goods_id, $deal_params) {
// 是否是vip
$is_vip = strtotime($this->user_info['vip_expire_time'] ?: c_now()) > time();
if (!$is_vip) {
$goods_free_use_limit = D('config')->where(['k' => 'goods_free_use_limit'])->value('v');
$find_user_use = D('user_use_cnt')->where(['goods_id' => $goods_id, 'user_id' => $this->user_id])->find();
$use_cnt = 0;
if($find_user_use) {
$use_cnt = $find_user_use['use_cnt'];
}else{
D('user_use_cnt')->insert(['goods_id' => $goods_id, 'user_id' => $this->user_id, 'use_cnt'=>0]);
}
if ($use_cnt >= $goods_free_use_limit) {
return ajaxFail('免费次数使用结束,请先充值', -1);
}
}
$goods = D('goods')->where(['id' => $goods_id, 'deleted' => 0])->find();
if (empty($goods)) {
return ajaxFail('不存在的服务', -2);
}
$order_no = s_order_id_render('Z');
$order = [
'user_id' => $this->user_id,
'goods_id' => $goods_id,
// 'from_user_id' => $share['from_user_id'],
'create_time' => c_now(),
'status' => 'wait_pay',
'order_no' => $order_no,
'price' => $goods['price'],
'deal_type' => $goods['deal_type'],
'funct_name' => $goods['funct_name'],
'deal_params' => c_json_encode($deal_params),
];
D('orders')->insert($order);
D('user_use_cnt')->where(['goods_id' => $goods_id, 'user_id' => $this->user_id])->inc('use_cnt');
$this->pay_notify($order_no);
return ajaxSuccess(['order_no' => $order_no]);
}
public function order_list($page = 1) {
$list = D('orders')->where(['deleted' => 0, 'user_id' => $this->user_id])->where(['status' => 'payed'])->page($page, 10)->order('id DESC')->select();
return ajaxSuccess($list);
}
public function config_one($k) {
$v = D('config')->where(['k' => $k])->value('v');
$v = c_safe_to_json($v, $v);
return ajaxSuccess($v);
}
public function configs($ks = '') {
$model = D('config');
if ($ks) {
$model->where('k', 'in', $ks);
}
$all_enums = $model->select();
$re = [];
foreach ($all_enums as $one) {
$re[$one['k']] = c_safe_to_json($one['v'], $one['v']);
}
//
return ajaxSuccess($re);
}
public function my() {
$info = $this->user_info;
if ($info['is_share']) {
$info['price_sum'] = D('orderx')->where(['status' => 'payed'])->where(['from_user_id' => $this->user_id])->sum('price');
$info['share_cnt'] = D('share')->where(['from_user_id' => $this->user_id])->count();
$info['share_view_cnt'] = D('share')->where(['from_user_id' => $this->user_id])->sum('view_cnt');
}
$show_vip_link = $info['is_share'] ? true : false;
if (!$show_vip_link) {
if (D('orderx')->where(['status' => 'payed'])->where(['user_id' => $this->user_id])->find()) {
$show_vip_link = true;
}
}
$info['show_vip_link'] = $show_vip_link;
$info['payed_vip_link'] = D('config')->where(['k' => 'payed_vip_link'])->value('v');
return ajaxSuccess($info);
}
public function set_name($name = '') {
D('user')->where(['id' => $this->user_id])->update(['real_name' => $name]);
return ajaxSuccess();
}
public function bind_auth_phone($code = '') {
$row_user = D('user')->where([
'id' => $this->user_id,
])->find();
$cache_a_k = Cache::get(Constant::$CACHE_ACCESS_TOKEN);
$qdata = [
'code' => $code,
];
$re_data = curl_post_https('https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=' . $cache_a_k['access_token'], json_encode($qdata));
$this->log_notice([$re_data], '授权手机号返回', 'bind_auth_phone');
// $session_key = $row_user['session_key'];
// $data = decrypt_wx_data($encrypted_data, $iv, $session_key);
// if (is_int($data) && $data < 0) {
// return ajaxFail('数据解析失败', -1);
// }
// /*
// {
// "phoneNumber": "13580006666",
// "purePhoneNumber": "13580006666",
// "countryCode": "86",
// "watermark":
// {
// "appid":"APPID",
// "timestamp": TIMESTAMP
// }
// }
// */
// //更新数据
// $pure_phone_number = $data['purePhoneNumber'];
// $country_code = $data['countryCode'];
$re_data_json = c_safe_to_json($re_data);
if (isset($re_data_json['errcode']) && $re_data_json['errcode'] == 0) {
$pure_phone_number = $re_data_json['phone_info']['purePhoneNumber'];
$country_code = $re_data_json['phone_info']['countryCode'];
D('user')->where([
'id' => $this->user_id,
])->update([
'phone' => $pure_phone_number,
'phone_country_code' => $country_code,
]);
return ajaxSuccess($pure_phone_number);
}
return ajaxFail('获取手机号失败', -1);
}
public function static_data_get($id) {
$row = D('static_data')->where(['id' => $id])->find();
return ajaxSuccess($row);
}
/**
*小程序上传文件
*/
public function wx_upload() {
$file = request()->file('img_file');
if ($file) {
try {
validate([
'img_file' => [
'fileSize' => (20 * 1024 * 1024),
'fileExt' => ['png', 'jpg', 'jpeg'],
]
])->check(['img_file' => $file]);
$savename = \think\facade\Filesystem::disk('public')->putFile(date('Y-m-d'), $file, 'md5');
return ajaxSuccess([
'path' => '/uploads/' . str_replace('\\', '/', $savename),
]);
} catch (ValidateException $e) {
// 上传失败获取错误信息
$this->log_notice($e->getMessage(), '上传失败获取错误信息', 'wx_upload');
return ajaxFail($e->getMessage(), -2);
}
}
$file = request()->file('audio_file');
if ($file) {
try {
validate([
'audio_file' => [
'fileSize' => (20 * 1024 * 1024),
'fileExt' => ['mp3'],
]
])->check(['audio_file' => $file]);
$savename = \think\facade\Filesystem::disk('public')->putFile(date('Y-m-d'), $file, 'md5');
return ajaxSuccess([
'path' => '/uploads/' . str_replace('\\', '/', $savename),
]);
} catch (ValidateException $e) {
// 上传失败获取错误信息
return ajaxFail($e->getMessage(), -2);
}
}
$file = request()->file('video_file');
if ($file) {
try {
validate([
'video_file' => [
'fileSize' => (200 * 1024 * 1024),
'fileExt' => ['mp4'],
]
])->check(['video_file' => $file]);
$savename = \think\facade\Filesystem::disk('public')->putFile(date('Y-m-d'), $file, 'md5');
return ajaxSuccess([
'path' => '/uploads/' . str_replace('\\', '/', $savename),
]);
} catch (ValidateException $e) {
// 上传失败获取错误信息
return ajaxFail($e->getMessage(), -3);
}
}
return ajaxFail('未选择上传文件,请重试', -3);
}
public function wx_login($code) {
if ($code != 'test') {
$data = code_2_session($code);
if ($data == null) {
return ajaxFail('授权失败', -1);
}
} else {
$data['openid'] = 'o3CkR7ecDQlsBfAW88Cmjin4YkmI';
$data['unionid'] = 'oV_Fvs_X63XiA1UDc2Bvx1YbD3bk';
$data['session_key'] = 'HBwb0sNhajpzzgM4nuMt6w==';
}
$openid = $data['openid'];
$unionid = $data['unionid'] ?? '';
$session_key = $data['session_key'];
$row_user = D('user')->where('openid', $openid)->where(['deleted' => 0])->find();
if (empty($row_user)) {
D('user')->insert([
'union_id' => $unionid,
'openid' => $openid,
'session_key' => $session_key,
'create_time' => date('Y-m-d H:i:s', time()),
]);
$user_id = D('user')->getLastInsID();
}
//update
else {
$user_id = $row_user['id'];
$update = [
'session_key' => $session_key,
// 'union_id'=>$unionid,
];
if ($unionid) {
$update['union_id'] = $unionid;
}
D('user')->where('openid', $openid)->update($update);
}
// c_debug('有人登录了:' . $user_id);
return ajaxSuccess([
// 'union_id' => $unionid,
'user_id' => a_encode($user_id . '|' . time()),
'openid' => $openid,
'phone' => empty($row_user) ? '' : $row_user['phone'],
]);
}
public function login_id($id=0) {
$row_user = D('user')->where(['id'=>$id])->find();
setcookie('user_id', a_encode($id . '|' . time()));
return ajaxSuccess([
// 'union_id' => $unionid,
'user_id' => a_encode($id . '|' . time()),
'openid' => $row_user['openid'],
'phone' => empty($row_user) ? '' : $row_user['phone'],
]);
}
public function fetch_order($order_no) {
$order = D('orders')->where([
'order_no' => $order_no,
'user_id' => $this->user_id,
])->find();
return ajaxSuccess(c_filter_property($order, ['deleted', 'pay_wx_data', 'need_auto_refund', 'deal_type', 'deal_params', 'deal_result'], true));
}
public function pay_order($order_no = '') {
$order = D('orders')->where([
'order_no' => $order_no,
// 'user_id' => $this->user_id,
])->find();
if (empty($order)) {
return ajaxFail('不存在的订单', -2);
}
$price = intval($order['price']);
// $debug = false;
// $debug = Config::get('app.APP_DEBUG');
// if ($debug) {
// $price = 1;
// }
$appid = Config::get('app.APPID');
$body = '商城订单' . $order_no;
$mch_id = Config::get('app.MCH_ID');
$pay_url = Config::get('app.PAY_NOTIFY_URL_SHOP');
$key = Config::get('app.PAY_KEY');
$nonce_str = '0123456789';
$openid = $this->user_info['openid'];
$create_ip = '127.0.0.1';
$need_encode_str = "appid=" . $appid
. "&body=" . $body
. "&mch_id=" . $mch_id
. "&nonce_str=" . $nonce_str
. "&notify_url=" . $pay_url
. "&openid=" . $openid
. "&out_trade_no=" . $order_no
. "&sign_type=MD5"
. "&spbill_create_ip=" . $create_ip
. "&total_fee=" . $price
. "&trade_type=JSAPI"
. "&key=" . $key;
$this->log_notice($need_encode_str, '$need_encode_str', 'pay_order');
$sign = strtoupper(md5($need_encode_str));
$xml = '<xml>'
. '<appid>' . $appid . '</appid>'
. '<body><![CDATA[' . $body . ']]></body>'
. '<mch_id>' . $mch_id . '</mch_id>'
. '<nonce_str>' . $nonce_str . '</nonce_str>'
. '<notify_url>' . $pay_url . '</notify_url>'
. '<openid>' . $openid . '</openid>'
. '<out_trade_no>' . $order_no . '</out_trade_no>'
. '<sign_type>MD5</sign_type>'
. '<spbill_create_ip>' . $create_ip . '</spbill_create_ip>'
. '<total_fee>' . $price . '</total_fee>'
. '<trade_type>JSAPI</trade_type>'
. '<sign>' . $sign . '</sign>'
. '</xml>';
$res_map = \s_make_wx_order($xml);
// Log::write(json_encode($res_map), 'notice');
$this->log_notice($res_map, '请求支付参数', 'pay_order');
if ($res_map['return_code'] == 'SUCCESS') {
$timeStamp = time();
$paySign = md5('appId=' . $appid
. '&nonceStr=' . $nonce_str
. '&package=prepay_id=' . $res_map['prepay_id']
. '&signType=MD5'
. '&timeStamp=' . $timeStamp
. '&key=' . $key);
return ajaxSuccess([
'timeStamp' => '' . $timeStamp,
'nonceStr' => $nonce_str,
'package' => 'prepay_id=' . $res_map['prepay_id'],
'signType' => 'MD5',
'paySign' => $paySign,
]);
}
return ajaxFail('调用支付接口失败', -3);
}
// 微信支付回调
public function pay_notify($_test_success_order_no = '') {
$str = file_get_contents('php://input');
if ($_test_success_order_no) {
$str = '';
}
// 模拟支付成功
if (!$str && $_test_success_order_no) {
$map = ['out_trade_no' => $_test_success_order_no,
'系统默认支付成功0元或测试单'];
} else {
$this->log_notice($str, '支付通知', 'pay_notify');
$map = c_read_xml_to_map($str);
if (empty($map) || !isset($map['out_trade_no'])) {
$this->log_warn($map['out_trade_no'], '错误的支付消息', 'pay_notify');
echo '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[错误的消息]]></return_msg></xml>';
exit();
}
}
$order_no = $map['out_trade_no'];
$notify_return = 0;
$order_detail = D('orders')->where(['order_no' => $order_no])->find(); // 查询包含已删除
if (empty($order_detail)) {
$notify_return = -1;
}
if ($order_detail['status'] != 'wait_pay') {
// 只记录,不失败
$this->log_warn($map['out_trade_no'], '订单状态不正确', 'pay_notify');
// $this->service_any->sendqywx_test($map['out_trade_no'] . '订单状态不正确','');
if ($order_detail['status'] != 'payed') {
D('orders')->where(['id' => $order_detail['id']])->update(['need_auto_refund' => 1]);
}
}
//超时支付和正常支付都算能支付
D('orders')->where(['id' => $order_detail['id'], 'deleted' => 0])->update(['status' => 'payed', 'pay_time' => c_now(), 'pay_wx_data' => $str]);
if ($notify_return == -1) {
if ($_test_success_order_no) {
return ajaxFail([$order_no], '订单ID不存在', 'pay_notify');
}
echo '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[订单ID不存在]]></return_msg></xml>';
} else if ($notify_return == 0) {
if ($_test_success_order_no) {
return ajaxSuccess();
}
echo '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
}
if ($_test_success_order_no) {
return ajaxFail([$order_no], '支付通知', 'pay_notify');
}
}
//
public function ______unuse_function_start______() {}
public function notice_list() {
$list = D('notice')->where(['delete' => 0])
->where('start_time', '<=', date('Y-m-d H:i:s', time()))
->where('end_time', '>=', date('Y-m-d H:i:s', time()))->select();
return ajaxSuccess(c_filter_property_list($list, ['id', 'title', 'content', 'create_time']));
}
public function notice_deital($id) {
$detail = D('notice')->where(['id' => $id, 'delete' => 0])->find();
return ajaxSuccess(\c_filter_property($detail, ['delete', 'start_time', 'end_time'], true));
}
public function mark_order_info($order_no, $name = '', $phone = '', $position = '') {
D('orderx')->where(['order_no' => $order_no])->update([
'name' => $name,
'phone' => $phone,
'position' => $position,
]);
return ajaxSuccess();
}
public function make_order($share_id) {
$share = D('share')->where(['id' => $share_id, 'deleted' => 0])->find();
if (empty($share)) {
return ajaxFail('链接已失效,请联系客服');
}
if ($share['expire_time']) {
if ($share['expire_time'] <= c_now()) {
return ajaxFail('购买链接已过期,请重新联系客服');
}
}
$order_no = s_order_id_render('P');
$order = [
'user_id' => $this->user_id,
'share_id' => $share_id,
'from_user_id' => $share['from_user_id'],
'create_time' => c_now(),
'status' => 'wait_pay',
'order_no' => $order_no,
'price' => $share['price'],
'buy_type' => $share['buy_type'],
];
D('orderx')->insert($order);
return ajaxSuccess(['order_no' => $order_no]);
}
public function get_share($id) {
$data = D('share')->where(['id' => $id, 'deleted' => 0])->find();
// if(strtotime($data['expire_time']) >= time()) {
// return ajaxFail('支付链接已超时,请联系客服');
// }
// $v = D('config')->where(['k' => 'buy_types'])->value('v');
// $data['buy_types'] = c_safe_to_json($v, $v);
// $v = D('config')->where(['k' => 'tip_before_pay'])->value('v');
// $data['tip_before_pay'] = c_safe_to_json($v, $v);
// $v = D('config')->where(['k' => 'tip_after_pay'])->value('v');
// $data['tip_after_pay'] = c_safe_to_json($v, $v);
return ajaxSuccess($data);
}
public function view_share($id) {
D('share')->where(['id' => $id, 'deleted' => 0])->inc('view_cnt')->update();
return ajaxSuccess();
}
public function del_share($id) {
D('share')->where(['id' => $id])->update(['deleted' => 1]);
return ajaxSuccess();
}
public function share_link_list($page = 1, $pageSize = 10) {
$list = D('share')->where(['from_user_id' => $this->user_id, 'deleted' => 0])->where('expire_time', '>=', c_now())->page($page, $pageSize)->select();
return ajaxSuccess($list);
}
public function create_share($price, $expireDate, $buy_type = '') {
if (!$this->user_info['is_share']) {
return ajaxFail('您暂无分销权限', -1);
}
$data = [
'from_user_id' => $this->user_id,
'price' => $price * 100,
'expire_time' => $expireDate . ' 23:59:59',
'create_time' => c_now(),
'title' => '推荐您购买' . $buy_type,
'img' => 'http://cdn.zhonganonline.top/liiistem/static/liii_icon.png',
'buy_type' => $buy_type,
];
D('share')->insert($data);
$id = D('share')->getLastInsID();
$data['id'] = $id;
// $data['path'] =
return ajaxSuccess($data);
}
public function mark($id, $remark = '') {
$one = D('orderx')->where(['id' => $id, 'from_user_id' => $this->user_id])->find();
if (empty($one)) {
return ajaxFail('不存在的内容', -1);
}
D('orderx')->where(['id' => $id])->update(['remark' => $remark]);
return ajaxSuccess();
}
public function share_list($page = 1, $status = '') {
$model = D('orderx')->where(['from_user_id' => $this->user_id]);
if ($status) {
$model->where(['status' => $status]);
} else {
$model->where('status', 'IN', ['payed', 'wait_pay']);
}
$list = $model->page($page, 10)->order('id DESC')->select();
return ajaxSuccess($list);
}
public function banner_list() {
$where = ['deleted' => 0];
$list = D('banner')->where($where)->order('id DESC')->select();
return ajaxSuccess($list);
}
public function news_list($page = 1, $pageSize = 10) {
$where = ['deleted' => 0,
'status' => 1];
$model = D('news')->order('id DESC')->where($where);
$list = $model->page($page, $pageSize)->select();
return ajaxSuccess($list);
}
public function news_detail($id = '') {
$detail = D('news')->where(['id' => $id, 'deleted' => 0])->find();
if (!$detail) {
return ajaxFail('数据不存在', -1);
}
$detail['view_cnt'] = $detail['view_cnt'] + 1;
D('news')->where(['id' => $id, 'deleted' => 0])->update(['view_cnt' => $detail['view_cnt']]);
return ajaxSuccess([
'detail' => $detail,
]);
}
}

15
app/event.php Normal file
View file

@ -0,0 +1,15 @@
<?php
// 事件定义文件
return [
'bind' => [],
'listen' => [
'AppInit' => [],
'HttpRun' => [],
'HttpEnd' => [],
'LogLevel' => [],
'LogWrite' => [],
],
'subscribe' => [],
];

View file

@ -0,0 +1,12 @@
<?php
namespace app\exceptions;
use think\Exception;
/**
* 权限失效异常类
*/
class NoAccessException extends Exception
{
}

View file

@ -0,0 +1,12 @@
<?php
namespace app\exceptions;
use think\Exception;
/**
* 登录失效异常类
*/
class NotLoginException extends Exception
{
}

View file

@ -0,0 +1,12 @@
<?php
namespace app\exceptions;
use think\Exception;
/**
* 参数校验异常类
*/
class ParamsValidateException extends Exception
{
}

10
app/middleware.php Normal file
View file

@ -0,0 +1,10 @@
<?php
// 全局中间件定义文件
return [
// 全局请求缓存
// \think\middleware\CheckRequestCache::class,
// 多语言加载
// \think\middleware\LoadLangPack::class,
// Session初始化
// \think\middleware\SessionInit::class
];

9
app/provider.php Normal file
View file

@ -0,0 +1,9 @@
<?php
use app\ExceptionHandle;
use app\Request;
// 容器Provider定义文件
return [
'think\Request' => Request::class,
'think\exception\Handle' => ExceptionHandle::class,
];

9
app/service.php Normal file
View file

@ -0,0 +1,9 @@
<?php
use app\AppService;
// 系统服务定义文件
// 服务在完成全局初始化之后执行
return [
AppService::class,
];

View file

@ -0,0 +1,51 @@
<?php
namespace app\service;
use think\Service;
use think\facade\Log;
use think\exception\ErrorException;
class BaseService extends Service
{
private $className = '';
public function __construct($className)
{
$this->className = $className;
}
protected function log_notice($any, $msg = '', $tag = 'log_notice')
{
if ($any instanceof ErrorException || $any instanceof Exception) {
$str = c_formate_exception($any);
} else {
$str = json_encode($any, JSON_UNESCAPED_UNICODE);
}
Log::write('[' . $this->className . ']' . '[' . $tag . ']' . '[' . $msg . ']' . '[' . $str . ']', 'NOTICE');
}
protected function log_warn($any, $msg = '', $tag = 'log_warn')
{
if ($any instanceof ErrorException || $any instanceof Exception) {
$str = c_formate_exception($any);
} else {
$str = json_encode($any, JSON_UNESCAPED_UNICODE);
}
Log::write('[' . $this->className . ']' . '[' . $tag . ']' . '[' . $msg . ']' . '[' . json_encode($any, JSON_UNESCAPED_UNICODE) . ']', 'WARN');
}
protected function log_error($any, $msg = '', $tag = 'log_error')
{
if ($any instanceof ErrorException || $any instanceof Exception) {
$str = c_formate_exception($any);
} else {
$str = json_encode($any, JSON_UNESCAPED_UNICODE);
}
Log::write('[' . $this->className . ']' . '[' . $tag . ']' . '[' . $msg . ']' . '[' . json_encode($any, JSON_UNESCAPED_UNICODE) . ']', 'ERROR');
}
protected function alarm($type = '', $content = '')
{
D('alarm')->insert([
'type' => $type,
'content' => $content,
'create_time' => c_now(),
]);
}
}

177
app/service/ToolService.php Normal file
View file

@ -0,0 +1,177 @@
<?php
namespace app\service;
use app\service\BaseService;
use app\AppCache;
use think\facade\Config;
use AlibabaCloud\SDK\Imageenhan\V20190930\Imageenhan;
use AlibabaCloud\SDK\Imageseg\V20191230\Imageseg;
use \Exception;
use AlibabaCloud\Tea\Utils\Utils;
use Darabonba\OpenApi\Models\Config as DaraConfig;
use AlibabaCloud\SDK\Imageenhan\V20190930\Models\ColorizeImageAdvanceRequest;
use AlibabaCloud\SDK\Imageseg\V20191230\Models\SegmentCommonImageAdvanceRequest;
use AlibabaCloud\Tea\Utils\Utils\RuntimeOptions;
use GuzzleHttp\Psr7\Stream;
class ToolService extends BaseService
{
private $access_key_id = 'LTAI5tE6gkXQqJBbCxFfo4hv';
private $access_secret = 'pziJRQfXlev3vEIY4dHuB6C7E73Uv6';
private $sign_name = '';
private $imgClient = null;
public function __construct() {
parent::__construct('ToolService');
$this->config = new DaraConfig([
"accessKeyId" => $this->access_key_id,
"accessKeySecret" => $this->access_secret,
]);
}
public function tongYongFenGe($imgUrl) {
$this->config->endpoint = "imageseg.cn-shanghai.aliyuncs.com";
$client = new Imageseg($this->config);
$file = fopen($imgUrl, 'rb');
$stream = new Stream($file);
$segmentCommonImageAdvanceRequest = new SegmentCommonImageAdvanceRequest([
"imageURLObject" => $stream,
"returnForm" => "whiteBK"
]);
$runtime = new RuntimeOptions([]);
try {
$resp = $client->segmentCommonImageAdvance($segmentCommonImageAdvanceRequest, $runtime);
# 获取整体结果
$json_str = Utils::toJSONString($resp->body);
$json = c_safe_to_json($json_str);
// return ['code'=>0,$json];
$this->log_notice($json, '照片上色结果', 'tuPianShangSe');
return $json['Data']['ImageURL'] ?? '';
} catch (Exception $exception) {
# 获取整体报错信息
$this->log_error(Utils::toJSONString($exception), '照片上色失败', 'tuPianShangSe');
}
return '';
}
public function tuPianShangSe($imgUrl) {
$this->config->endpoint = "imageenhan.cn-shanghai.aliyuncs.com";
$client = new Imageenhan($this->config);
$file = fopen($imgUrl, 'rb');
//$stream = new Stream($file);
// 场景二使用任意可访问的url
// $file = fopen('http://viapi-test.oss-cn-shanghai.aliyuncs.com/viapi-3.0domepic/imageenhan/ColorizeImage/ColorizeImage1.jpg', 'rb');
$stream = new Stream($file);
$colorizeImageAdvanceRequest = new ColorizeImageAdvanceRequest([
"imageURLObject" => $stream
]);
$runtime = new RuntimeOptions([]);
try {
$resp = $client->colorizeImageAdvance($colorizeImageAdvanceRequest, $runtime);
# 获取整体结果
$json_str = Utils::toJSONString($resp->body);
$json = c_safe_to_json($json_str);
// return ['code'=>0,$json];
$this->log_notice($json, '照片上色结果', 'tuPianShangSe');
return $json['Data']['ImageURL'] ?? '';
} catch (Exception $exception) {
# 获取整体报错信息
$this->log_error(Utils::toJSONString($exception), '照片上色失败', 'tuPianShangSe');
}
return '';
}
// private function base($options_query): bool
// {
// $is_prod = false;
// if (env('app.envName', 'prod') == 'prod') {
// $is_prod = true;
// }
// if (!$is_prod) {
// $this->log_notice($options_query, '', 'base');
// if (!isset($options_query['Test'])) {
// return true;
// }
// }
// $options_query['RegionId'] = 'cn-hangzhou';
// $options_query['SignName'] = $this->sign_name;
// try {
// $result = AlibabaCloud::rpc()
// ->product('Dysmsapi')
// // ->scheme('https') // https | http
// ->version('2017-05-25')
// ->action('SendSms')
// ->method('POST')
// ->host('dysmsapi.aliyuncs.com')
// ->options([
// 'query' => $options_query
// ])
// ->request();
// $this->log_notice(['发送结果:' => $result->toArray(), "发送内容" => $options_query], '短信发送成功', 'base');
// return true;
// } catch (ClientException $e) {
// $this->log_error(['发送结果:' => $e->getErrorMessage(), "发送内容" => $options_query], '短信发送失败', 'base');
// } catch (ServerException $e) {
// $this->log_error(['发送结果:' => $e->getErrorMessage(), "发送内容" => $options_query], '短信发送失败', 'base');
// }
// return false;
// }
// public function sendTest() {
// return $this->base([
// 'Test' => 'test',
// 'TemplateCode' => "SMS_173476256",
// 'PhoneNumbers' => '13873044202',
// 'TemplateParam' => c_json_encode([
// 'OrderNo' => '11111111111111',
// 'CustomerName' => '测试',
// 'ProductName' => c_max_len_3dot('裸心堡红宝石水疗送双人下午茶/每天限量抢购'),
// 'ProductCount' => 2,
// ]),
// ]);
// }
// public function sendSMS($body_arr): bool
// {
// return $this->base($body_arr);
// }
// public function sendBindPhoneVcode($user_id, $phone): string
// {
// $vcode = random_vcode(6);
// $this->base([
// 'TemplateCode' => "SMS_307600272",
// 'PhoneNumbers' => $phone,
// 'TemplateParam' => c_json_encode(['code' => $vcode]),
// ]);
// return $vcode;
// }
public function sendqywx($text, $phone) {
$this->log_notice([$text, $phone], 'sendqywx', 'sendqywx');
return curl_post_https(Config::get('app.order_qywx_webhook'),
json_encode([
'msgtype' => 'text',
'text' => [
'content' => $text,
'mentioned_mobile_list' => [$phone],
],
]),
['header' => ['Content-Type:application/json']]);
}
public function sendqywx_test($text, $phone) {
$this->log_notice([$text, $phone], 'sendqywx_test', 'sendqywx_test');
return curl_post_https(Config::get('app.self_qxwx_alarm_webhook'),
json_encode([
'msgtype' => 'text',
'text' => [
'content' => $text,
'mentioned_mobile_list' => [$phone],
],
]),
['header' => ['Content-Type:application/json']]);
}
}

5
backup_db.sh Normal file
View file

@ -0,0 +1,5 @@
#/bin/bash
cur_date="`date +%Y%m%d%H%M%S`"
`mysqldump -u root -pCk@@@@453455 yymg --ignore-table=yymg.sys_msg_queue --ignore-table=yymg.user_coupon_delete --ignore-table=yymg.order_history > /mnt/db_yymg/$cur_date.sql`
`tar czfP /mnt/db_yymg/$cur_date.tar.gz /mnt/db_yymg/$cur_date.sql`
`rm -f /mnt/db_yymg/$cur_date.sql`

8
backup_db_testwx.sh Normal file
View file

@ -0,0 +1,8 @@
#/bin/bash
cur_date="`date +%Y%m%d%H%M%S`"
`mysqldump -u root -p453455 yymg > /var/www/db_yymg/$cur_date.sql`
`tar czfP /var/www/db_yymg/$cur_date.tar.gz /var/www/db_yymg/$cur_date.sql`
`rm -f /var/www/db_yymg/$cur_date.sql`
bef_date="`date -d \"3 day ago\" +%Y%m%d%H%M%S`"
`rm -f /var/www/db_yymg/$bef_date.tar.gz`
curl -O http://testwx.yunyoumg.com/index.php/api/sys/sys_msg_queue_delete_unuse

1
chown.sh Normal file
View file

@ -0,0 +1 @@
chown -R www:www ./

View file

@ -1,29 +0,0 @@
export default () => {
if (!wx.canIUse('getUpdateManager')) {
return;
}
const updateManager = wx.getUpdateManager();
updateManager.onCheckForUpdate(function (res) {
// 请求完新版本信息的回调
console.log('版本信息', res);
});
updateManager.onUpdateReady(function () {
wx.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启应用?',
success(res) {
if (res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate();
}
},
});
});
updateManager.onUpdateFailed(function () {
// 新版本下载失败
});
};

56
composer.json Normal file
View file

@ -0,0 +1,56 @@
{
"name": "topthink/think",
"description": "the new thinkphp framework",
"type": "project",
"keywords": [
"framework",
"thinkphp",
"ORM"
],
"homepage": "http://thinkphp.cn/",
"license": "Apache-2.0",
"authors": [
{
"name": "liu21st",
"email": "liu21st@gmail.com"
},
{
"name": "yunwuxin",
"email": "448901948@qq.com"
}
],
"require": {
"php": ">=7.1.0",
"topthink/framework": "^6.0.0",
"topthink/think-orm": "^2.0",
"topthink/think-multi-app": "^1.0",
"alibabacloud/client": "^1.5",
"topthink/think-view": "^1.0",
"alibabacloud/imageenhan-20190930": "^1.0"
},
"require-dev": {
"symfony/var-dumper": "^4.2",
"topthink/think-trace":"^1.0",
"nikic/php-parser": "^4.3"
},
"autoload": {
"psr-4": {
"app\\": "app"
},
"psr-0": {
"": "extend/"
}
},
"config": {
"preferred-install": "dist"
},
"scripts": {
"post-autoload-dump": [
"@php think service:discover",
"@php think vendor:publish"
],
"parser":[
"@php ast.php"
]
}
}

2373
composer.lock generated Normal file

File diff suppressed because it is too large Load diff

47
config/app.php Normal file
View file

@ -0,0 +1,47 @@
<?php
// +----------------------------------------------------------------------
// | 应用设置
// +----------------------------------------------------------------------
return [
'APP_DEBUG' => env('APP_DEBUG', false),
// 应用地址
'app_host' => env('app.host', ''),
// 应用的命名空间
'app_namespace' => '',
// 是否启用路由
'with_route' => false,
// 是否启用事件
'with_event' => true,
// 默认应用
'default_app' => 'index',
// 默认时区
'default_timezone' => 'Asia/Shanghai',
// 应用映射(自动多应用模式有效)
'app_map' => [],
// 域名绑定(自动多应用模式有效)
'domain_bind' => [],
// 禁止URL访问的应用列表自动多应用模式有效
'deny_app_list' => [],
// 异常页面的模板文件
'exception_tmpl' => app()->getThinkPath() . 'tpl/think_exception.tpl',
// 错误显示信息,非调试模式有效
'error_message' => '页面错误!请稍后再试~',
// 显示错误信息
'show_error_msg' => true,
//
'ENCODE_KEY' => env('app.ENCODE_KEY', 'QDVTGN48@@#11aa'),
'APPID' => 'wx2a7607969ec65027',
'SECERT_KEY' => '941a33ebe76bf4f84eb8a03834b4d831',
'envName' => 'prod',
// 微信支付
'MCH_ID' => '1717190820',
'PAY_KEY' => 'Dollar01234567890abcdefghijklmno',
'REFUND_CERT_FILE' => '/wx_ca/apiclient_cert.pem',
'REFUND_KEY_FILE' => '/wx_ca/apiclient_key.pem',
'CERT_SERIAL_NO' => '', // 暂时没用到
'PAY_NOTIFY_URL_SHOP' => 'https://civcar.zhonganonline.top/zhihuitb/index.php/api/v1/pay_notify',
];

29
config/cache.php Normal file
View file

@ -0,0 +1,29 @@
<?php
// +----------------------------------------------------------------------
// | 缓存设置
// +----------------------------------------------------------------------
return [
// 默认缓存驱动
'default' => env('cache.driver', 'file'),
// 缓存连接方式配置
'stores' => [
'file' => [
// 驱动方式
'type' => 'File',
// 缓存保存目录
'path' => '',
// 缓存前缀
'prefix' => '',
// 缓存有效期 0表示永久缓存
'expire' => 0,
// 缓存标签前缀
'tag_prefix' => 'tag:',
// 序列化机制 例如 ['serialize', 'unserialize']
'serialize' => [],
],
// 更多的缓存连接
],
];

8
config/console.php Normal file
View file

@ -0,0 +1,8 @@
<?php
// +----------------------------------------------------------------------
// | 控制台配置
// +----------------------------------------------------------------------
return [
// 指令定义
'commands' => [],
];

18
config/cookie.php Normal file
View file

@ -0,0 +1,18 @@
<?php
// +----------------------------------------------------------------------
// | Cookie设置
// +----------------------------------------------------------------------
return [
// cookie 保存时间
'expire' => 0,
// cookie 保存路径
'path' => '/',
// cookie 有效域名
'domain' => '',
// cookie 启用安全传输
'secure' => false,
// httponly设置
'httponly' => false,
// 是否使用 setcookie
'setcookie' => true,
];

145
config/database.php Normal file
View file

@ -0,0 +1,145 @@
<?php
return [
// 默认使用的数据库连接配置
'default' => env('database.driver', 'mysql'),
// 自定义时间查询规则
'time_query_rule' => [],
// 'resultset_type' => 'array',
// 自动写入时间戳字段
// true为自动识别类型 false关闭
// 字符串则明确指定时间字段类型 支持 int timestamp datetime date
'auto_timestamp' => true,
// 时间字段取出后的默认时间格式
'datetime_format' => 'Y-m-d H:i:s',
// 数据库连接配置信息
'connections' => [
'mysql' => [
// 数据库类型
'type' => env('database.type', 'mysql'),
// 服务器地址
'hostname' => env('database.hostname', '127.0.0.1'),
// 数据库名
'database' => env('database.database', 'zhihuitubao'),
// 用户名
'username' => env('database.username', 'root'),
// 密码
'password' => env('database.password', 'Ck@@@@453455'),
// 'password' => '453455',
// 端口
'hostport' => env('database.hostport', '3306'),
// 数据库连接参数
'params' => [],
// 数据库编码默认采用utf8
'charset' => env('database.charset', 'utf8mb4'),
// 数据库表前缀
'prefix' => env('database.prefix', ''),
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
'deploy' => 0,
// 数据库读写是否分离 主从式有效
'rw_separate' => false,
// 读写分离后 主服务器数量
'master_num' => 1,
// 指定从服务器序号
'slave_no' => '',
// 是否严格检查字段是否存在
'fields_strict' => true,
// 是否需要断线重连
'break_reconnect' => false,
// 监听SQL
'trigger_sql' => false,
// 开启字段缓存
'fields_cache' => false,
// 字段缓存路径
'schema_cache_path' => app()->getRuntimePath() . 'schema' . DIRECTORY_SEPARATOR,
],
'mysql2' => [
// 数据库类型
'type' => env('database.type', 'mysql'),
// 服务器地址
'hostname' => env('database.hostname', '127.0.0.1'),
// 'hostname' => env('database.hostname', '39.100.154.10'),
// 'hostname' => '121.196.9.49',
// 数据库名
'database' => env('database.database', 'tonglu_shop'),
// 用户名
'username' => env('database.username', 'tonglu'),
// 密码
'password' => env('database.password', 'Tonglu@123!!'),
// 'password' => '453455',
// 端口
'hostport' => env('database.hostport', '3306'),
// 数据库连接参数
'params' => [],
// 数据库编码默认采用utf8
'charset' => env('database.charset', 'utf8mb4'),
// 数据库表前缀
'prefix' => env('database.prefix', ''),
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
'deploy' => 0,
// 数据库读写是否分离 主从式有效
'rw_separate' => false,
// 读写分离后 主服务器数量
'master_num' => 1,
// 指定从服务器序号
'slave_no' => '',
// 是否严格检查字段是否存在
'fields_strict' => true,
// 是否需要断线重连
'break_reconnect' => false,
// 监听SQL
'trigger_sql' => false,
// 开启字段缓存
'fields_cache' => false,
// 字段缓存路径
'schema_cache_path' => app()->getRuntimePath() . 'schema' . DIRECTORY_SEPARATOR,
],
// 'mssql' => [
// // 数据库类型
// 'type' => 'pdo',
// // 服务器地址
// 'hostname' => 'dblib:host=rm-bp1o39373w01d73adfo.sqlserver.rds.aliyuncs.com:3433',
// // 数据库名
// 'database' => 'yymgdb2',
// // 用户名
// 'username' => 'yymguser',
// // 密码
// 'password' => 'Mg20190829',
// // 端口
// 'hostport' => '3433',
// // 数据库连接参数
// 'params' => [],
// // 数据库编码默认采用utf8
// 'charset' => env('database.charset', 'utf8'),
// // 数据库表前缀
// 'prefix' => env('database.prefix', ''),
// // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
// 'deploy' => 0,
// // 数据库读写是否分离 主从式有效
// 'rw_separate' => false,
// // 读写分离后 主服务器数量
// 'master_num' => 1,
// // 指定从服务器序号
// 'slave_no' => '',
// // 是否严格检查字段是否存在
// 'fields_strict' => true,
// // 是否需要断线重连
// 'break_reconnect' => false,
// // 监听SQL
// 'trigger_sql' => env('app_debug', true),
// // 开启字段缓存
// 'fields_cache' => false,
// // 字段缓存路径
// 'schema_cache_path' => app()->getRuntimePath() . 'schema' . DIRECTORY_SEPARATOR,
// ],
// 更多的数据库配置信息
],
];

24
config/filesystem.php Normal file
View file

@ -0,0 +1,24 @@
<?php
return [
// 默认磁盘
'default' => env('filesystem.driver', 'local'),
// 磁盘列表
'disks' => [
'local' => [
'type' => 'local',
'root' => app()->getRuntimePath() . 'storage',
],
'public' => [
// 磁盘类型
'type' => 'local',
// 磁盘路径
'root' => app()->getRootPath() . 'public/uploads',
// 磁盘路径对应的外部URL路径
'url' => '/uploads',
// 可见性
'visibility' => 'public',
],
// 更多的磁盘配置信息
],
];

View file

@ -1,4 +0,0 @@
export const config = {
/** 是否使用mock代替api返回 */
useMock: true,
};

25
config/lang.php Normal file
View file

@ -0,0 +1,25 @@
<?php
// +----------------------------------------------------------------------
// | 多语言设置
// +----------------------------------------------------------------------
return [
// 默认语言
'default_lang' => env('lang.default_lang', 'zh-cn'),
// 允许的语言列表
'allow_lang_list' => [],
// 多语言自动侦测变量名
'detect_var' => 'lang',
// 是否使用Cookie记录
'use_cookie' => true,
// 多语言cookie变量
'cookie_var' => 'think_lang',
// 扩展语言包
'extend_list' => [],
// Accept-Language转义为对应语言包名称
'accept_language' => [
'zh-hans-cn' => 'zh-cn',
],
// 是否支持语言分组
'allow_group' => false,
];

45
config/log.php Normal file
View file

@ -0,0 +1,45 @@
<?php
// +----------------------------------------------------------------------
// | 日志设置
// +----------------------------------------------------------------------
return [
// 默认日志记录通道
'default' => env('log.channel', 'file'),
// 日志记录级别
'level' => [],
// 日志类型记录的通道 ['error'=>'email',...]
'type_channel' => [],
// 关闭全局日志写入
'close' => false,
// 全局日志处理 支持闭包
'processor' => null,
// 日志通道列表
'channels' => [
'file' => [
// 日志记录方式
'type' => 'File',
// 日志保存目录
'path' => '',
// 单文件日志写入
'single' => false,
// 独立日志级别
'apart_level' => [],
// 最大日志文件数量
'max_files' => 0,
// 使用JSON格式记录
'json' => false,
// 日志处理
'processor' => null,
// 关闭通道日志写入
'close' => false,
// 日志输出格式化
'format' => '[%s][%s] %s',
// 是否实时写入
'realtime_write' => false,
],
// 其它日志通道配置
],
];

8
config/middleware.php Normal file
View file

@ -0,0 +1,8 @@
<?php
// 中间件配置
return [
// 别名或分组
'alias' => [],
// 优先级设置,此数组中的中间件会按照数组中的顺序优先执行
'priority' => [],
];

45
config/route.php Normal file
View file

@ -0,0 +1,45 @@
<?php
// +----------------------------------------------------------------------
// | 路由设置
// +----------------------------------------------------------------------
return [
// pathinfo分隔符
'pathinfo_depr' => '/',
// URL伪静态后缀
'url_html_suffix' => 'html',
// URL普通方式参数 用于自动生成
'url_common_param' => true,
// 是否开启路由延迟解析
'url_lazy_route' => false,
// 是否强制使用路由
'url_route_must' => false,
// 合并路由规则
'route_rule_merge' => false,
// 路由是否完全匹配
'route_complete_match' => false,
// 访问控制器层名称
'controller_layer' => 'controller',
// 空控制器名
'empty_controller' => 'Error',
// 是否使用控制器后缀
'controller_suffix' => false,
// 默认的路由变量规则
'default_route_pattern' => '[\w\.]+',
// 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
'request_cache' => false,
// 请求缓存有效期
'request_cache_expire' => null,
// 全局请求缓存排除规则
'request_cache_except' => [],
// 默认控制器名
'default_controller' => 'Index',
// 默认操作名
'default_action' => 'index',
// 操作方法后缀
'action_suffix' => '',
// 默认JSONP格式返回的处理方法
'default_jsonp_handler' => 'jsonpReturn',
// 默认JSONP处理方法
'var_jsonp_handler' => 'callback',
];

19
config/session.php Normal file
View file

@ -0,0 +1,19 @@
<?php
// +----------------------------------------------------------------------
// | 会话设置
// +----------------------------------------------------------------------
return [
// session name
'name' => 'PHPSESSID',
// SESSION_ID的提交变量,解决flash上传跨域
'var_session_id' => '',
// 驱动方式 支持file cache
'type' => 'file',
// 存储连接标识 当type使用cache的时候有效
'store' => null,
// 过期时间
'expire' => 1440,
// 前缀
'prefix' => '',
];

10
config/trace.php Normal file
View file

@ -0,0 +1,10 @@
<?php
// +----------------------------------------------------------------------
// | Trace设置 开启调试模式后有效
// +----------------------------------------------------------------------
return [
// 内置Html和Console两种方式 支持扩展
'type' => 'Html',
// 读取的日志通道名
'channel' => '',
];

25
config/view.php Normal file
View file

@ -0,0 +1,25 @@
<?php
// +----------------------------------------------------------------------
// | 模板设置
// +----------------------------------------------------------------------
return [
// 模板引擎类型使用Think
'type' => 'Think',
// 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法
'auto_rule' => 1,
// 模板目录名
'view_dir_name' => 'view',
// 模板后缀
'view_suffix' => 'html',
// 模板文件名分隔符
'view_depr' => DIRECTORY_SEPARATOR,
// 模板引擎普通标签开始标记
'tpl_begin' => '{',
// 模板引擎普通标签结束标记
'tpl_end' => '}',
// 标签库标签开始标记
'taglib_begin' => '{',
// 标签库标签结束标记
'taglib_end' => '}',
];

View file

@ -1,16 +0,0 @@
export default [{
icon: 'home',
text: '动态',
url: 'pages/home/home',
},
{
icon: 'share',
text: '分销',
url: 'pages/faxianlist/faxianlist',
},
{
icon: 'person',
text: '我的',
url: 'pages/usercenter/index',
},
];

View file

@ -1,66 +0,0 @@
import TabMenu from './data';
import R from '../utils/request';
import C from '../utils/constant';
Component({
data: {
active: 0,
list: [],
is_share: false,
cdnHost: C.cdnHost,
},
ready() {
R.get('/index.php/api/v1/my').then(({ model }) => {
this.setData({
is_share: !!model.is_share,
list: TabMenu.filter((_, idx) => {
if (model.is_share) {
return true
} else {
return idx !== 1
}
})
});
});
},
methods: {
goTakePhoto() {
wx.navigateTo({
url: '/pages/takephoto/takephoto',
})
},
onChange(event) {
this.setData({ active: event.detail.value });
wx.switchTab({
url: this.data.list[event.detail.value].url.startsWith('/')
? this.data.list[event.detail.value].url
: `/${this.data.list[event.detail.value].url}`,
});
},
init() {
const page = getCurrentPages().pop();
const route = page ? page.route.split('?')[0] : '';
const active = this.data.list.findIndex(
(item) =>
(item.url.startsWith('/') ? item.url.substr(1) : item.url) ===
`${route}`,
);
this.setData({ active });
},
getPhoneNumber(e) {
console.log(e.detail.code) // 动态令牌
console.log(e.detail.errMsg) // 回调信息(成功失败都会返回)
console.log(e.detail.errno) // 错误码(失败时返回)
if (!e.detail.errno) {
R.post('/index.php/api/v1/bind_auth_phone', { code: e.detail.code }).then(() => {
this.setData({ hasPhone: true })
this.goTakePhoto();
})
} else {
// e.detail.errMsg
}
},
},
});

View file

@ -1,9 +0,0 @@
{
"component": true,
"usingComponents": {
"t-tab-bar": "tdesign-miniprogram/tab-bar/tab-bar",
"t-tab-bar-item": "tdesign-miniprogram/tab-bar-item/tab-bar-item",
"t-icon": "tdesign-miniprogram/icon/icon",
"t-image": "tdesign-miniprogram/image/image"
}
}

View file

@ -1,36 +0,0 @@
<view class="tabline">
<t-tab-bar value="{{active}}" bindchange="onChange" split="{{false}}">
<t-tab-bar-item wx:for="{{list}}" wx:for-item="item" wx:for-index="index" wx:key="index">
<view class="{{'custom-tab-bar-wrapper ' + ('tab' + index) + ' ' + (index == active ? 'cur' : '')}}">
<t-icon prefix="wr" name="{{item.icon}}" size="40rpx" />
<view class="text">{{ item.text }}</view>
</view>
</t-tab-bar-item>
<!-- <t-tab-bar-item>
<view class="{{'custom-tab-bar-wrapper ' + ('tab' + 0) + ' ' + (0 == active ? 'cur' : '')}}">
<t-icon prefix="wr" name="{{list[0].icon}}" size="40rpx" />
<view class="text">{{ list[0].text }}</view>
</view>
</t-tab-bar-item>
<t-tab-bar-item wx:if="{{is_share}}">
<view class="{{'custom-tab-bar-wrapper ' + ('tab' + 1) + ' ' + (1 == active ? 'cur' : '')}}">
<t-icon prefix="wr" name="{{list[1].icon}}" size="40rpx" />
<view class="text">{{ list[1].text }}</view>
</view>
</t-tab-bar-item>
<t-tab-bar-item>
<view class="{{'custom-tab-bar-wrapper ' + ('tab' + 2) + ' ' + (2 == active ? 'cur' : '')}}">
<t-icon prefix="wr" name="{{list[2].icon}}" size="40rpx" />
<view class="text">{{ list[2].text }}</view>
</view>
</t-tab-bar-item> -->
<!-- <view class="camera" bind:tap="goTakePhoto" wx:if="{{hasPhone}}">
<t-image loading=" " mode="aspectFill" src="{{cdnHost + '/static/camera.png?v=5'}}" width="29" height="23" />
<view class="txt">发现</view>
</view>
<button open-type="getPhoneNumber" class="camera" bindgetphonenumber="getPhoneNumber" wx:else>
<t-image loading=" " mode="aspectFill" src="{{cdnHost + '/static/camera.png?v=5'}}" width="29" height="23" />
<view class="txt">发现</view>
</button> -->
</t-tab-bar>
</view>

View file

@ -1,40 +0,0 @@
.tabline {
position: relative;
}
.custom-tab-bar-wrapper {
display: flex;
align-items: center;
}
.text {
font-size: 28rpx;
padding-left: 10rpx;
}
.camera {
position: absolute;
left: 50%;
top: 20rpx;
border-radius: 20rpx;
height: 78rpx;
width: 176rpx;
background: linear-gradient(180deg, rgb(74, 137, 254) 0%, rgb(47, 103, 254) 100%);
transform: translateX(-50%);
display: flex;
align-items: center;
justify-content: center;
z-index: 2;
font-size: 28rpx;
color: #fff;
}
.camera .txt{
display: flex;
align-items: center;
padding-left:10rpx;
white-space: nowrap;
}
.custom-tab-bar-wrapper.cur {
color: #2966f5;
}

2
extend/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*
!.gitignore

View file

@ -1,5 +0,0 @@
{
"compilerOptions": {
"baseUrl": "."
}
}

View file

@ -1,17 +0,0 @@
{
"name": "@tencent/tdesign-miniprogram-starter-retail",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"dayjs": "^1.9.3",
"tdesign-miniprogram": "^1.4.0",
"tslib": "^1.11.1"
},
"devDependencies": {}
}

View file

@ -1,109 +0,0 @@
import C from '../../utils/constant';
import * as F from '../../utils/func';
import R from '../../utils/request';
import ActionSheet, { ActionSheetTheme } from 'tdesign-miniprogram/action-sheet/index';
Page({
data: {
price: '',
expireDate: F.parseDate(new Date()),
dateVisible: false,
start: F.parseDate(new Date()),
end: F.parseDate(new Date(new Date() * 1 + 24 * 3600 * 366 * 1000 + 1)),
filter(type, options) {
if (type === 'year') {
return options.sort((a, b) => b.value - a.value);
}
return options;
},
popupProps: {
usingCustomNavbar: true,
},
buy_type: '',
buy_types: [],
},
onLoad() {
R.get('/index.php/api/v1/config_one', { k: 'buy_types' }).then(({ model }) => {
this.setData({
buy_types: model || [],
buy_type: model[0],
});
});
},
handleSelected(e) {
console.log(e.detail);
this.setData({
buy_type: e.detail.selected.label,
});
},
handleAction() {
ActionSheet.show({
theme: ActionSheetTheme.List,
selector: '#t-action-sheet',
context: this,
items: this.data.buy_types.map((item) => ({
label: item,
})),
});
},
onConfirm(e) {
const { value } = e.detail;
this.setData({
expireDate: value,
dateVisible: false,
});
},
showPicker() {
this.setData({ dateVisible: true });
},
onClose() {
this.setData({ dateVisible: false });
},
validate() {
const { price, expireDate } = this.data;
if (!price) {
wx.showToast({ title: '请输入分销金额', icon: 'none' });
return false;
}
if (!/^\d+(\.\d+)?$/.test(price)) {
wx.showToast({ title: '请输入正确的金额', icon: 'none' });
return false;
}
if (!expireDate) {
wx.showToast({ title: '请选择付款有效期', icon: 'none' });
return false;
}
return true;
},
share() {
if (!this.validate()) return;
// TODO: 调用分享接口
// console.log('share1', this.data);
// wx.showShareMenu({
// withShareTicket: true,
// menus: ['shareAppMessage']
// });
},
onShareAppMessage(e) {
if (!this.validate()) {
return {
title: '',
path: '',
imageUrl: '',
promise: Promise.reject(),
}
}
const { price, expireDate, buy_type } = this.data;
return R.get('/index.php/api/v1/create_share', {
price, expireDate, buy_type,
}).then(({ model }) => {
return {
title: model.title,
path: model.path || '/pages/sharebuy/sharebuy?id=' + model.id,
imageUrl: model.img,
promise: Promise.resolve(),
};
});
},
});

View file

@ -1,11 +0,0 @@
{
"navigationBarTitleText": "分销",
"backgroundTextStyle": "light",
"usingComponents": {
"t-cell": "tdesign-miniprogram/cell/cell",
"t-button": "tdesign-miniprogram/button/button",
"t-input": "tdesign-miniprogram/input/input",
"t-date-time-picker": "tdesign-miniprogram/date-time-picker/date-time-picker",
"t-action-sheet": "tdesign-miniprogram/action-sheet/action-sheet"
}
}

View file

@ -1,14 +0,0 @@
<view class="container">
<view class="form">
<t-input label="分销金额" placeholder="请输入分销金额" suffix="元" type="digit" align="right" model:value="{{price}}" />
<t-cell title="分销类型" hover note="{{buy_type || '请选择分销类型'}}" arrow bindtap="handleAction" />
<t-cell title="付款有效期" hover note="{{expireDate || '请选择付款有效期'}}" arrow bindtap="showPicker" />
<!-- <t-input label="分销类型" placeholder="请选择分销类型" align="right" value="{{buy_type}}" bindtap="handleAction" readonly /> -->
<!-- <t-input label="付款有效期" placeholder="请选择付款有效期" align="right" value="{{expireDate}}" bindtap="showPicker" readonly /> -->
</view>
<view class="footer">
<t-button theme="primary" open-type="share" block catchtap="share">分享</t-button>
</view>
<t-action-sheet id="t-action-sheet" usingCustomNavbar bind:selected="handleSelected" />
<t-date-time-picker auto-close title="选择日期" visible="{{dateVisible}}" mode="date" default-value="{{expireDate}}" format="YYYY-MM-DD" start="{{start}}" end="{{end}}" filter="{{filter}}" popup-props="{{popupProps}}" bind:confirm="onConfirm" bind:close="onClose" />
</view>

View file

@ -1,14 +0,0 @@
.container {
padding: 20rpx;
}
.form {
background: #fff;
border-radius: 10rpx;
overflow: hidden;
}
.footer {
margin-top: 40rpx;
padding: 0 20rpx;
}

View file

@ -1,33 +0,0 @@
import R from '../../utils/request';
import C from '../../utils/constant';
Page({
data: {
cdnHost: C.cdnHost,
detail: {},
user: {},
},
onLoad(options) {
const { id } = options;
R.get('/index.php/api/v1/news_detail', { id }).then(({ model }) => {
this.setData({
detail: {
...model.detail,
content: (model.detail.content||'').replace(/src\="\/uploads/g, 'src="'+C.cdnHost + '/uploads'),
imgs: (model.detail.imgs || '').split(',').filter(o=>!!o),
video: model.detail.video ? model.detail.video : '',
},
user: {
...model.user,
}
});
});
},
videoErrorCallback(e) {
console.log('视频错误信息:')
console.log(e.detail.errMsg)
},
onShareAppMessage() {
}
})

View file

@ -1,8 +0,0 @@
{
"navigationBarTitleText": "详情",
"backgroundTextStyle": "light",
"usingComponents": {
"t-icon": "tdesign-miniprogram/icon/icon",
"t-image": "tdesign-miniprogram/image/image"
}
}

View file

@ -1,14 +0,0 @@
<view>
<view class="title">{{detail.title}}</view>
<view class="info">
<view class="time">{{detail.create_time}}</view>
<view class="viewcnt">
<t-icon name="browse" size="28rpx" color="#b3b5b9"></t-icon>
{{detail.view_cnt}}
</view>
</view>
<rich-text class="desc" nodes="{{detail.content}}"></rich-text>
<t-image mode="aspectFill" wx:for="{{detail.imgs}}" src="{{cdnHost + item}}" wx:key="item" class="img" shape="round" />
<video class="video" wx:if="{{detail.video}}" id="myVideo" src="{{cdnHost + detail.video}}" binderror="videoErrorCallback" show-center-play-btn='{{false}}' show-play-btn="{{true}}" controls></video>
<view class="source">来源: {{user.real_name || '三鲤'}}</view>
</view>

View file

@ -1,57 +0,0 @@
page {
box-sizing: border-box;
background-color: #fff;
padding: 0 20rpx;
padding-top: 20rpx;
padding-bottom: calc(env(safe-area-inset-bottom) + 106rpx);
}
.title {
font-size: 34rpx;
list-style: square;
margin-bottom: 20rpx;
color: #363a44;
}
.info {
display: flex;
font-size: 28rpx;
justify-content: space-between;
margin-bottom: 60rpx;
color: #b3b5b9;
}
.info .viewcnt {
display: flex;
align-items: center;
}
.info .viewcnt .t-icon {
margin-right: 12rpx;
}
.content {
word-break: break-all;
line-height: 46rpx;
font-size: 26rpx;
color: #363a44;
}
.img {
width: 100%;
margin: 20rpx auto;
}
.video {
width: 100%;
margin: 20rpx auto;
}
.source {
font-size: 24rpx;
color: #b3b5b9;
text-align: left;
margin-top: 40rpx;
}

View file

@ -1,66 +0,0 @@
// pages/detail_admin/detail.js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})

View file

@ -1,2 +0,0 @@
<!--pages/detail_admin/detail.wxml-->
<text>pages/detail_admin/detail.wxml</text>

View file

@ -1,107 +0,0 @@
import R from '../../utils/request';
import C from '../../utils/constant';
import * as F from '../../utils/func';
Page({
data: {
cdnHost: C.cdnHost,
list: [],
page: 1,
status: '',
// money_flag: 'send',
listEndText: '',
},
onShow() {
this.getTabBar().init();
this.fetchList(1);
},
onLoad(options) {
},
goCreate(e) {
wx.navigateTo({
url: `/pages/createpay/createpay`
});
},
fetchList(page) {
const { status } = this.data;
// money_flag
R.get('/index.php/api/v1/share_list', { page, status }).then(({ model }) => {
const list = [];
model.forEach(item => {
list.push({
...item,
price: F.formatePrice(item.price),
});
});
if (list.length == 0) {
this.setData({ listEndText: '没有更多了' });
} else {
this.setData({ listEndText: '点击加载更多。。。' });
}
if (page == 1) {
this.setData({ list,page });
} else {
const list2 = this.data.list.concat(list);
this.setData({ list: list2,page });
}
});
// for (let i = 0; i < 20; i++) {
// list.push({
// id: i,
// title: '自动热重载] 已开启代码文件保存后自动热重载自动热重载] 已开启代码文件保存后自动热重载',
// image: `${imageCdn}/swiper2.png`,
// createTime: '09-12 12:21',
// viewCnt: 1922 + i,
// });
// }
// this.setData({
// list
// })
},
loadMore() {
const { page, listEndText } = this.data;
if (listEndText == '点击加载更多。。。') {
this.fetchList(page + 1);
}
},
onTabsChange(event) {
const v = event.detail.value;
this.data.status = v;
this.fetchList(1);
},
// handleSwitchChange(e) {
// const { value } = e.detail;
// if (value) {
// this.data.money_flag = 'send';
// } else {
// this.data.money_flag = '';
// }
// this.fetchList(1);
// },
onReachBottom() {
this.loadMore();
},
onPullDownRefresh() {
this.fetchList(1);
wx.stopPullDownRefresh();
},
editRemark(e) {
const { id, remark } = e.currentTarget.dataset.detail;
const that = this;
wx.showModal({
title: '备注',
content: remark || '',
editable: true,
success(re) {
const remark2 = re.content || '';
R.post('/index.php/api/v1/mark', { id, remark: remark2 }).then(() => {
that.data.list.find(o => o.id == id).remark = remark2;
that.setData({
list: [...that.data.list],
})
})
}
})
}
})

View file

@ -1,13 +0,0 @@
{
"navigationBarTitleText": "我的分销",
"backgroundTextStyle": "light",
"usingComponents": {
"t-tabs": "tdesign-miniprogram/tabs/tabs",
"t-tab-panel": "tdesign-miniprogram/tab-panel/tab-panel",
"t-image": "tdesign-miniprogram/image/image",
"t-sticky": "tdesign-miniprogram/sticky/sticky",
"t-divider": "tdesign-miniprogram/divider/divider",
"t-icon": "tdesign-miniprogram/icon/icon",
"t-footer": "tdesign-miniprogram/footer/footer"
}
}

View file

@ -1,44 +0,0 @@
<view>
<!-- <t-sticky offset-top="{{0}}"> -->
<!-- <view class="tabs"> -->
<!-- <t-tabs defaultValue="{{0}}" bind:change="onTabsChange" t-class="custom-tabs">
<t-tab-panel label="全部" value="" />
<t-tab-panel label="已支付" value="payed" />
<t-tab-panel label="待支付" value="wait_pay" />
</t-tabs>
<view class="sw"> -->
<!-- <t-switch defaultValue="{{false}}" bindchange="handleSwitchChange" size="small" />
<view class="txt">已提现</view> -->
<!-- </view> -->
<!-- </view> -->
<!-- </t-sticky> -->
<view class="list">
<view class="item" wx:for="{{list}}" wx:key="id">
<view class="item-main" data-id="{{item.id}}" bind:tap="goDetail">
<view class="right">
<view class="text">
<view>订单号: {{item.order_no || '-'}} 金额: {{item.price}} 元</view>
<view wx:if="{{item.name}}">购买信息: {{item.name}} {{item.phone}}</view>
<view data-detail="{{item}}" class="remark" bind:tap="editRemark">
<t-icon prefix="wr" name="edit" size="40rpx" />
备注: {{item.remark || '无'}}
</view>
</view>
<view class="info">
<view wx:if="{{item.pay_time}}">支付时间: {{item.pay_time}}</view>
<view wx:else>订单时间: {{item.create_time}}</view>
<view class="viewcnt init">{{item.buy_type}}</view>
<!-- <view class="viewcnt init" wx:if="{{item.status == 'init'}}">待审核</view> -->
<!-- <view class="viewcnt resolve" wx:if="{{item.status == 'payed'}}">已支付</view> -->
<!-- <view class="viewcnt reject" wx:if="{{item.status == 'wait_pay'}}">待支付</view> -->
</view>
</view>
</view>
</view>
<t-footer wx:if="{{listEndText}}" text="{{listEndText}}" bind:tap="loadMore"></t-footer>
</view>
<view class="btn_cre" bind:tap="goCreate">
<view>创建</view>
<view>分销</view>
</view>
</view>

View file

@ -1,113 +0,0 @@
page {
padding: 0 20rpx;
background-color: rgb(245, 246, 247);
}
.tabs {
display: flex;
justify-content: space-between;
background-color: rgb(245, 246, 247);
}
.tabs .t-tabs {
width: 60%;
background: none !important;
}
.tabs .t-tabs .t-tabs__wrapper {
background: none !important;
}
.sw {
width: 240rpx;
display: flex;
align-items: center;
font-size: 32rpx;
}
.sw .txt {
padding-left: 16rpx;
}
.list {
margin-top: 20rpx;
padding-bottom: 60rpx;
}
.list .item {
border-radius: 16rpx;
background-color: #fff;
margin-bottom: 20rpx;
width: 710rpx;
padding-top: 20rpx;
}
.list .item .item-main {
display: flex;
padding-left: 20rpx;
}
.list .item .item-main .right {
flex: 1;
padding: 0 32rpx;
padding-bottom: 20rpx;
}
.list .item .item-main .right .text {
padding-top: 16rpx;
font-size: 28rpx;
line-height: 46rpx;
margin-bottom: 20rpx;
color: #333;
}
.list .item .item-main .right .info {
display: flex;
font-size: 24rpx;
justify-content: space-between;
color: #8f9197;
}
.list .item .item-main .right .info .viewcnt {
display: flex;
align-items: center;
padding: 0 20rpx;
}
.list .item .item-main .right .info .viewcnt.init {
color: blue;
}
.list .item .item-main .right .info .viewcnt.resolve {
color: green;
}
.list .item .item-main .right .info .viewcnt.reject {
color: gray;
}
.remark{
display: flex;
}
.btn_cre {
position: fixed;
bottom: 220rpx;
right: 20rpx;
height: 120rpx;
width: 120rpx;
border-radius: 50%;
background-color: rgb(111, 172, 207);
color: #fff;
font-size: 26rpx;
z-index: 2;
padding-top: 26rpx;
box-sizing: border-box;
}
.btn_cre view {
display: flex;
align-items: center;
justify-content: center;
flex-direction: row;
text-align: center;
}

View file

@ -1,106 +0,0 @@
import R from '../../utils/request';
import C from '../../utils/constant';
Page({
data: {
cdnHost: C.cdnHost,
loadFlag: false,
swiperList: [],
list: [],
},
onShow() {
this.getTabBar().init();
// this.init();
this.fetchBanner();
},
onLoad() {
R.login().then(() => {
this.init();
})
},
fetchBanner() {
R.get('/index.php/api/v1/banner_list', {}).then(({ model }) => {
const swiperList = [];
model.forEach(item => {
swiperList.push({
...item,
value: C.cdnHost + item.img,
ariaLabel: item.title,
id: item.id,
});
});
if (JSON.stringify(swiperList) != JSON.stringify(this.data.swiperList)) {
this.setData({ swiperList });
}
});
},
init() {
if (this.data.loadFlag) return;
this.data.loadFlag = false;
this.fetchList(1);
this.fetchBanner();
},
fetchList(page) {
R.get('/index.php/api/v1/news_list', { page, pageSize: 5 }).then(({ model }) => {
const list = [];
model.forEach(item => {
list.push({
...item,
});
});
this.setData({ list });
});
},
goDetail(e) {
const { id } = e.currentTarget.dataset;
wx.navigateTo({
url: `/pages/detail/detail?id=${id}`
});
},
onSwiperTap(e) {
const { index } = e.detail;
this.data.swiperList.forEach((o, i) => {
if (i == index) {
console.log(o)
if(o.action_type == 'newsId'){
wx.navigateTo({
url: '/pages/detail/detail?id=' + o.action_item,
});
}
if(o.action_type == 'url'){
wx.navigateTo({
url: '/pages/webview/webview?url=' + encodeURIComponent(o.action_item),
});
}
if(o.action_type == 'path'){
wx.navigateTo({
url: o.action_item,
});
}
}
})
},
goUrl(e) {
const { url } = e.currentTarget.dataset;
wx.navigateTo({
url
});
},
goMore() {
wx.navigateTo({
url: '/pages/news_list/home'
});
},
refresh() {
this.fetchList(1);
this.fetchBanner();
wx.showToast({ icon: 'none', title: '刷新成功' });
},
onPullDownRefresh() {
this.init();
wx.stopPullDownRefresh();
},
onShareAppMessage() { },
onShareTimeline() { },
});

View file

@ -1,12 +0,0 @@
{
"navigationBarTitleText": "首页",
"backgroundTextStyle": "light",
"usingComponents": {
"t-swiper": "tdesign-miniprogram/swiper/swiper",
"t-swiper-nav": "tdesign-miniprogram/swiper-nav/swiper-nav",
"t-icon": "tdesign-miniprogram/icon/icon",
"t-image": "tdesign-miniprogram/image/image",
"t-divider": "tdesign-miniprogram/divider/divider"
},
"enablePullDownRefresh": true
}

View file

@ -1,101 +0,0 @@
page {
box-sizing: border-box;
background-color: linear-gradient(180deg, #f0f4fc, #fff);
padding: 0 20rpx;
padding-top: 10rpx;
padding-bottom: calc(env(safe-area-inset-bottom) + 106rpx);
}
.title_bar {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 32rpx;
}
.title_bar .title {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
background-position: left center;
background-size: 100% 100%;
font-size: 32rpx;
color: rgb(53, 58, 71);
height: 34rpx;
display: flex;
align-items: center;
font-weight: bold;
.t-icon {
margin-left: 10rpx;
}
}
.title_bar .btn {
color: #71737b;
font-size: 28rpx;
display: flex;
align-items: center;
}
.title_bar .btn .t-icon {
margin-left: 10rpx;
}
.list {
margin-top: 20rpx;
}
.list .item .item-main {
display: flex;
}
.list .item .item-main .right {
flex: 1;
padding-left: 32rpx;
}
.list .item .item-main .right .text {
padding-top: 0rpx;
font-size: 28rpx;
line-height: 46rpx;
margin-bottom: 10rpx;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
color: #363a44;
}
.list .item .item-main .right .info {
display: flex;
font-size: 24rpx;
justify-content: space-between;
color: #71737b;
}
.list .item .item-main .right .info .viewcnt {
display: flex;
align-items: center;
}
.list .item .viewcnt .t-icon {
margin-right: 10rpx;
}
.t-tab-bar {
border-top: 1px solid #eee;
position: relative;
}
.activity {
display: flex;
justify-content: space-between;
padding: 20rpx 0;
border-bottom: 1px solid #eee;
.t-image {
width: 100%;
}
}

View file

@ -1,31 +0,0 @@
<view>
<t-swiper wx:if="{{swiperList.length > 0}}" current="{{current}}" autoplay="{{true}}" duration="{{500}}" height="{{180}}" interval="{{3000}}" list="{{swiperList}}" navigation="{{ { type: 'dots-bar' } }}" bind:click="onSwiperTap" />
<view class="title_bar" wx:if="{{list.length}}">
<view class="title" bind:tap="refresh">
公司动态
<t-icon name="refresh" size="28rpx" color="71737b"></t-icon>
</view>
<view class="btn" bind:tap="goMore">
查看全部
<t-icon name="chevron-right" size="28rpx" color="71737b"></t-icon>
</view>
</view>
<view class="list" wx:if="{{list.length}}">
<view class="item" wx:for="{{list}}" wx:key="id">
<view class="item-main" data-id="{{item.id}}" bind:tap="goDetail">
<t-image mode="aspectFill" src="{{cdnHost+item.poster}}" width="108" height="72" shape="round" />
<view class="right">
<view class="text">{{item.title}}</view>
<view class="info">
<view>{{item.create_time}}</view>
<view class="viewcnt">
<t-icon name="browse" size="28rpx" color="71737b"></t-icon>
{{item.view_cnt}}
</view>
</view>
</view>
</view>
<t-divider />
</view>
</view>
</view>

View file

@ -1,84 +0,0 @@
page {
box-sizing: border-box;
background-color: linear-gradient(180deg, #f0f4fc, #fff);
padding: 0 20rpx;
padding-top: 10rpx;
padding-bottom: calc(env(safe-area-inset-bottom) + 106rpx);
}
.title_bar {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 32rpx;
}
.title_bar .title {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
background-position: left center;
background-size: 100% 100%;
font-size: 32rpx;
color: #353a47;
height: 34rpx;
display: flex;
align-items: center;
font-weight: bold;
}
.title_bar .title .t-icon {
margin-left: 10rpx;
}
.title_bar .btn {
color: #71737b;
font-size: 28rpx;
display: flex;
align-items: center;
}
.title_bar .btn .t-icon {
margin-left: 10rpx;
}
.list {
margin-top: 20rpx;
}
.list .item .item-main {
display: flex;
}
.list .item .item-main .right {
flex: 1;
padding-left: 32rpx;
}
.list .item .item-main .right .text {
padding-top: 0rpx;
font-size: 28rpx;
line-height: 46rpx;
margin-bottom: 10rpx;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
color: #363a44;
}
.list .item .item-main .right .info {
display: flex;
font-size: 24rpx;
justify-content: space-between;
color: #71737b;
}
.list .item .item-main .right .info .viewcnt {
display: flex;
align-items: center;
}
.list .item .viewcnt .t-icon {
margin-right: 10rpx;
}
.t-tab-bar {
border-top: 1px solid #eee;
position: relative;
}
.activity {
display: flex;
justify-content: space-between;
padding: 20rpx 0;
border-bottom: 1px solid #eee;
}
.activity .t-image {
width: 100%;
}

View file

@ -1,8 +0,0 @@
首页功能设定
1. loading入场
2. 下拉刷新
3. 搜索栏
4. 分类切换
5. 商品列表
6. 规格弹层
7. 加载更多

View file

@ -1,66 +0,0 @@
// pages/news_admin_list/home.js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})

View file

@ -1,2 +0,0 @@
<!--pages/news_admin_list/home.wxml-->
<text>pages/news_admin_list/home.wxml</text>

View file

@ -1,63 +0,0 @@
import R from '../../utils/request';
import C from '../../utils/constant';
Page({
data: {
cdnHost: C.cdnHost,
list: [],
page: 1,
listEndText: '',
},
onShow() {
this.getTabBar().init();
},
onLoad() {
this.init();
},
init() {
this.fetchList(1);
},
fetchList(page) {
R.get('/index.php/api/v1/news_list', { page }).then(({ model }) => {
const list = [];
model.forEach(item => {
list.push({
...item,
});
});
if (list.length == 0) {
this.setData({ listEndText: '没有更多了' });
} else {
this.setData({ listEndText: '点击加载更多。。。' });
}
if (page == 1) {
this.setData({ list ,page});
} else {
const list2 = this.data.list.concat(list);
this.setData({ list: list2,page });
}
});
},
loadMore() {
const { page, listEndText } = this.data;
if (listEndText == '点击加载更多。。。') {
this.fetchList(page + 1);
}
},
goDetail(e) {
const { id } = e.currentTarget.dataset;
wx.navigateTo({
url: `/pages/detail/detail?id=${id}`
});
},
refresh() {
this.fetchList(1);
wx.showToast({ icon: 'none', title: '刷新成功' });
},
// 下拉刷新
onPullDownRefresh() {
this.init();
wx.stopPullDownRefresh();
},
});

View file

@ -1,10 +0,0 @@
{
"navigationBarTitleText": "发现",
"backgroundTextStyle": "light",
"usingComponents": {
"t-icon": "tdesign-miniprogram/icon/icon",
"t-image": "tdesign-miniprogram/image/image",
"t-divider": "tdesign-miniprogram/divider/divider",
"t-footer": "tdesign-miniprogram/footer/footer"
}
}

View file

@ -1,95 +0,0 @@
page {
box-sizing: border-box;
background-color: linear-gradient(180deg, #f0f4fc, #fff);
padding: 0 20rpx;
padding-top: 10rpx;
padding-bottom: calc(env(safe-area-inset-bottom) + 106rpx);
}
.title_bar {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 32rpx;
}
.title_bar .title {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
// background: url('http://cdn.zhonganonline.top/newslist/static/title.png') no-repeat;
background-position: left center;
background-size: 100% 100%;
font-size: 32rpx;
height: 34rpx;
width: 132rpx;
}
.title_bar .btn {
color: #71737b;
font-size: 28rpx;
display: flex;
align-items: center;
}
.title_bar .btn .t-icon {
margin-right: 10rpx;
}
.list {
margin-top: 20rpx;
}
.list .item .item-main {
display: flex;
}
.list .item .item-main .right {
flex: 1;
padding-left: 32rpx;
}
.list .item .item-main .right .text {
padding-top: 0rpx;
font-size: 28rpx;
line-height: 46rpx;
margin-bottom: 10rpx;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
color: #363a44;
}
.list .item .item-main .right .info {
display: flex;
font-size: 24rpx;
justify-content: space-between;
color: #71737b;
}
.list .item .item-main .right .info .viewcnt {
display: flex;
align-items: center;
}
.list .item .viewcnt .t-icon {
margin-right: 10rpx;
}
.t-tab-bar {
border-top: 1px solid #eee;
position: relative;
}
.activity {
display: flex;
justify-content: space-between;
padding: 20rpx 0;
border-bottom: 1px solid #eee;
.t-image {
width: 100%;
}
}

View file

@ -1,28 +0,0 @@
<view>
<view class="title_bar">
<view class="title">最新动态</view>
<view class="btn" bind:tap="refresh">
<t-icon name="refresh" size="28rpx" color="71737b"></t-icon>
刷新
</view>
</view>
<view class="list">
<view class="item" wx:for="{{list}}" wx:key="id">
<view class="item-main" data-id="{{item.id}}" bind:tap="goDetail">
<t-image mode="aspectFill" src="{{cdnHost+item.poster}}" width="108" height="72" shape="round" />
<view class="right">
<view class="text">{{item.title}}</view>
<view class="info">
<view>{{item.create_time}}</view>
<view class="viewcnt">
<t-icon name="browse" size="28rpx" color="71737b"></t-icon>
{{item.view_cnt}}
</view>
</view>
</view>
</view>
<t-divider />
</view>
<t-footer wx:if="{{listEndText}}" text="{{listEndText}}" bind:tap="loadMore"></t-footer>
</view>
</view>

View file

@ -1,78 +0,0 @@
page {
box-sizing: border-box;
background-color: linear-gradient(180deg, #f0f4fc, #fff);
padding: 0 20rpx;
padding-top: 10rpx;
padding-bottom: calc(env(safe-area-inset-bottom) + 106rpx);
}
.title_bar {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 32rpx;
}
.title_bar .title {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
background-position: left center;
background-size: 100% 100%;
font-size: 32rpx;
height: 34rpx;
width: 132rpx;
}
.title_bar .btn {
color: #71737b;
font-size: 28rpx;
display: flex;
align-items: center;
}
.title_bar .btn .t-icon {
margin-right: 10rpx;
}
.list {
margin-top: 20rpx;
}
.list .item .item-main {
display: flex;
}
.list .item .item-main .right {
flex: 1;
padding-left: 32rpx;
}
.list .item .item-main .right .text {
padding-top: 0rpx;
font-size: 28rpx;
line-height: 46rpx;
margin-bottom: 10rpx;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
color: #363a44;
}
.list .item .item-main .right .info {
display: flex;
font-size: 24rpx;
justify-content: space-between;
color: #71737b;
}
.list .item .item-main .right .info .viewcnt {
display: flex;
align-items: center;
}
.list .item .viewcnt .t-icon {
margin-right: 10rpx;
}
.t-tab-bar {
border-top: 1px solid #eee;
position: relative;
}
.activity {
display: flex;
justify-content: space-between;
padding: 20rpx 0;
border-bottom: 1px solid #eee;
}
.activity .t-image {
width: 100%;
}

View file

@ -1,8 +0,0 @@
首页功能设定
1. loading入场
2. 下拉刷新
3. 搜索栏
4. 分类切换
5. 商品列表
6. 规格弹层
7. 加载更多

View file

@ -1,39 +0,0 @@
import R from '../../utils/request';
import C from '../../utils/constant';
import * as F from '../../utils/func';
Page({
data: {
},
onLoad(options) {
const { order_no, redirect_url } = options;
R.post('/index.php/api/v1/pay_order_shop', { order_no }).then(({ model }) => {
wx.requestPayment({
...model,
success(res) {
wx.showToast({
title: '支付成功',
icon: 'success',
duration: 2000,
success() {
wx.redirectTo({
url: '/pages/shop/shop?path=user',
});
}
})
},
fail(res) {
wx.showToast({
title: '支付失败',
icon: 'none',
duration: 2000
})
wx.redirectTo({
url: '/pages/shop/shop?path=user',
});
}
})
})
},
})

View file

@ -1,5 +0,0 @@
{
"navigationBarTitleText": "支付",
"backgroundTextStyle": "light",
"usingComponents": {}
}

View file

@ -1 +0,0 @@
<view class="tip">支付中...</view>

View file

@ -1,4 +0,0 @@
.tip {
text-align: center;
margin-top: 20px;
}

View file

@ -1,105 +0,0 @@
import R from '../../utils/request';
import C from '../../utils/constant';
import * as F from '../../utils/func';
Page({
data: {
cdnHost: C.cdnHost,
list: [],
page: 1,
status: '',
// money_flag: 'send',
listEndText: '',
},
onLoad(options) {
const {from} = options;
if(from == 'sharebuy') {
R.post('/index.php/api/v1/configs',{ks:['payed_tip','payed_vip_link']}).then(({model})=>{
if(model.payed_tip && model.payed_vip_link) {
wx.showModal({
title: '提示',
content: model.payed_tip,
complete: (res) => {
if (res.confirm) {
wx.navigateTo({
url: '/pages/webview/webview?url=' + encodeURIComponent(model.payed_vip_link),
})
}
}
})
}
})
}
this.fetchList(1);
},
goDetail(e) {
const { detail } = e.currentTarget.dataset;
if (!detail.phone && detail.status == 'payed') {
wx.navigateTo({
url: `/pages/sharebuy/sharebuy?id=${detail.share_id}&orderNo=${detail.order_no}`,
});
}
},
fetchList(page) {
const { status } = this.data;
// money_flag
R.get('/index.php/api/v1/order_list', { page }).then(({ model }) => {
const list = [];
model.forEach(item => {
list.push({
...item,
price: F.formatePrice(item.price),
});
});
if (list.length == 0) {
this.setData({ listEndText: '没有更多了' });
} else {
this.setData({ listEndText: '点击加载更多。。。' });
}
if (page == 1) {
this.setData({ list,page });
} else {
const list2 = this.data.list.concat(list);
this.setData({ list: list2,page });
}
});
// for (let i = 0; i < 20; i++) {
// list.push({
// id: i,
// title: '自动热重载] 已开启代码文件保存后自动热重载自动热重载] 已开启代码文件保存后自动热重载',
// image: `${imageCdn}/swiper2.png`,
// createTime: '09-12 12:21',
// viewCnt: 1922 + i,
// });
// }
// this.setData({
// list
// })
},
loadMore() {
const { page, listEndText } = this.data;
if (listEndText == '点击加载更多。。。') {
this.fetchList(page + 1);
}
},
onTabsChange(event) {
const v = event.detail.value;
this.data.status = v;
this.fetchList(1);
},
// handleSwitchChange(e) {
// const { value } = e.detail;
// if (value) {
// this.data.money_flag = 'send';
// } else {
// this.data.money_flag = '';
// }
// this.fetchList(1);
// },
onReachBottom() {
this.loadMore();
},
onShareAppMessage() {
}
})

View file

@ -1,12 +0,0 @@
{
"navigationBarTitleText": "我的订单",
"backgroundTextStyle": "light",
"usingComponents": {
"t-tabs": "tdesign-miniprogram/tabs/tabs",
"t-tab-panel": "tdesign-miniprogram/tab-panel/tab-panel",
"t-image": "tdesign-miniprogram/image/image",
"t-sticky": "tdesign-miniprogram/sticky/sticky",
"t-divider": "tdesign-miniprogram/divider/divider",
"t-footer": "tdesign-miniprogram/footer/footer"
}
}

View file

@ -1,31 +0,0 @@
<view>
<view class="list">
<view class="item" wx:for="{{list}}" wx:key="id">
<view class="item-main" data-detail="{{item}}" bind:tap="goDetail">
<view class="right">
<view class="text">
<view>订单号: {{item.order_no || '-'}}</view>
<view>{{item.price}}元</view>
</view>
<view class="info" wx:if="{{!item.phone}}">
<view>{{item.buy_type}}</view>
<view style="text-align: right;color:coral">补充信息{{' >'}}</view>
</view>
<view class="info" wx:if="{{item.phone}}">
<view>信息: {{item.name || '暂无'}} {{item.phone}}</view>
<view style="text-align: right;">{{item.buy_type}}</view>
</view>
<view class="info">
<view wx:if="{{item.pay_time}}">支付时间: {{item.pay_time}}</view>
<view wx:else>订单时间: {{item.create_time}}</view>
<!-- <view class="viewcnt init">{{item.buy_type}}</view> -->
<!-- <view class="viewcnt init" wx:if="{{item.status == 'init'}}">待审核</view> -->
<view class="viewcnt resolve" wx:if="{{item.status == 'payed'}}">已支付</view>
<view class="viewcnt reject" wx:if="{{item.status == 'wait_pay'}}">待支付</view>
</view>
</view>
</view>
</view>
<t-footer wx:if="{{listEndText}}" text="{{listEndText}}" bind:tap="loadMore"></t-footer>
</view>
</view>

View file

@ -1,76 +0,0 @@
page {
padding: 0 20rpx;
background-color: rgb(245, 246, 247);
}
.sw {
width: 240rpx;
display: flex;
align-items: center;
font-size: 32rpx;
}
.sw .txt {
padding-left: 16rpx;
}
.list {
margin-top: 20rpx;
padding-bottom: 60rpx;
}
.list .item {
border-radius: 16rpx;
background-color: #fff;
margin-bottom: 20rpx;
width: 710rpx;
padding-top: 20rpx;
}
.list .item .item-main {
display: flex;
padding-left: 20rpx;
}
.list .item .item-main .right {
flex: 1;
padding: 0 32rpx;
padding-bottom: 20rpx;
}
.list .item .item-main .right .text {
display: flex;
font-size: 28rpx;
justify-content: space-between;
color: #333;
}
.list .item .item-main .right .info {
display: flex;
font-size: 24rpx;
justify-content: space-between;
color: #8f9197;
line-height: 36rpx;
}
.list .item .item-main .right .info .viewcnt {
display: flex;
align-items: center;
padding: 0 20rpx;
}
.list .item .item-main .right .info .viewcnt.init {
color: blue;
}
.list .item .item-main .right .info .viewcnt.resolve {
color: green;
}
.list .item .item-main .right .info .viewcnt.reject {
color: gray;
}
.list .item .h20 {
height: 20rpx;
}

View file

@ -1,141 +0,0 @@
import C from '../../utils/constant';
import * as F from '../../utils/func';
import R from '../../utils/request';
Page({
data: {
expireDate: '',
price: '',
shareId: '',
isPay: false,
orderNo: '',
phone: '',
username: '',
tip_before_pay: '',
tip_after_pay: '',
buy_type: '',
},
onLoad(options) {
const { id, orderNo } = options;
if (orderNo) {
this.setData({
isPay: true,
orderNo,
})
this.fetchOrder(orderNo);
} else {
R.get('/index.php/api/v1/get_share', { id }).then(({ model }) => {
this.setData({
shareId: id,
price: F.formatePrice(model.price),
expireDate: model.expire_time,
tip_before_pay: model.tip_before_pay || '',
tip_after_pay: model.tip_after_pay || '',
buy_type: model.buy_type,
});
}).catch((e)=>{
console.log('xxx',e);
})
R.get('/index.php/api/v1/view_share', { id });
}
},
refresh() {
if (this.data.orderNo) {
this.fetchOrder(this.data.orderNo);
}
},
fetchOrder(orderNo) {
const that = this;
return R.get('/index.php/api/v1/fetch_order_pay', { order_no: orderNo }).then(({ model }) => {
console.log('payed', model);
if (model.status === 'payed') {
clearInterval(that.data.timer);
wx.hideLoading();
this.setData({
isPay: true,
orderNo,
price: F.formatePrice(model.price),
buy_type: model.buy_type,
});
}
});
},
checkOrderStatus(orderNo) {
wx.showLoading({
title: '确认支付中...',
})
this.data.timer = setInterval(() => {
this.fetchOrder(orderNo).catch(() => {
clearInterval(this.data.timer);
});
}, 1000);
},
goPay() {
const that = this;
if (this.data.shareId) {
R.post('/index.php/api/v1/make_order', { share_id: this.data.shareId }).then(({ model: { order_no } }) => {
that.data.orderNo = order_no;
R.post('/index.php/api/v1/pay_order', { order_no }).then(({ model }) => {
wx.requestPayment({
...model,
success(res) {
wx.showToast({
title: '支付成功',
icon: 'success',
duration: 2000,
success() {
that.checkOrderStatus(order_no);
// this.setData({
// isPay: true,
// })
}
})
},
fail(res) {
wx.showToast({
title: '您已取消支付',
icon: 'none',
duration: 2000
})
// wx.redirectTo({
// url: '/pages/shop/shop?path=user',
// });
}
})
})
})
}
},
onShareAppMessage() {
},
validate() {
const { username, phone, orderNo, } = this.data;
if (!username) {
wx.showToast({ title: '请输入姓名', icon: 'none' });
return false;
}
if (!/^1\d{10}$/.test(phone)) {
wx.showToast({ title: '请输入正确的手机号', icon: 'none' });
return false;
}
return true;
},
submit() {
if (!this.validate()) return;
const {
username, phone, orderNo,
} = this.data
R.post('/index.php/api/v1/mark_order_info', { name: username, phone, order_no: orderNo, }).then(({ model }) => {
wx.showToast({
title: '提交成功',
icon: 'success',
duration: 2000,
success() {
wx.redirectTo({
url: '/pages/paylist/paylist?from=sharebuy',
})
}
});
});
},
})

View file

@ -1,9 +0,0 @@
{
"navigationBarTitleText": "支付",
"backgroundTextStyle": "light",
"usingComponents": {
"t-cell": "tdesign-miniprogram/cell/cell",
"t-button": "tdesign-miniprogram/button/button",
"t-input": "tdesign-miniprogram/input/input"
}
}

View file

@ -1,57 +0,0 @@
page {
box-sizing: border-box;
background-color: linear-gradient(180deg, #f0f4fc, #fff);
padding: 0 20rpx;
padding-top: 10rpx;
padding-bottom: calc(env(safe-area-inset-bottom) + 106rpx);
}
.logo {
height: 180rpx;
width: 180rpx;
margin: 0 auto;
background-image: url('http://cdn.zhonganonline.top/liiistem/static/liii_icon.png');
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
.form {
background: #fff;
border-radius: 10rpx;
overflow: hidden;
}
.footer {
margin-top: 40rpx;
padding: 0 20rpx;
}
.card {
margin: 20rpx 0;
padding: 0 20rpx;
.line {
font-size: 36rpx;
line-height: 60rpx;
}
}
.ma {
height: 20rpx;
}
.desc {
color: #666;
font-size: 28rpx;
margin-top: 20rpx;
line-height: 34rpx;
}
.refresh{
text-align: center;
margin-top: 20rpx;
color: #999;
}

View file

@ -1,37 +0,0 @@
<view class="logo"></view>
<view class="card" wx:if="{{!isPay}}">
<!-- <view class="line">付款: {{price}}元</view>
<view class="line">付款有效期: {{expireDate}}</view> -->
<t-cell title="付款" hover note="{{price}}元" />
<t-cell title="有效期" hover note="{{expireDate}}" />
<t-cell title="类型" hover note="{{buy_type}}" />
<view class="ma"></view>
<t-button theme="primary" size="large" block bind:tap="goPay">立即付款</t-button>
<view class="refresh" bind:tap="refresh">已支付? 手动刷新</view>
<view class="ma"></view>
<view class="ma"></view>
<view wx:if="{{tip_before_pay}}">
<!-- <view>支付提示:</view> -->
<rich-text class="desc" nodes="{{tip_before_pay}}"></rich-text>
</view>
</view>
<view wx:else>
<!-- <view>付款订单号: {{orderNo}}</view> -->
<!-- <view>付款成功: {{price}}元</view> -->
<t-cell title="付款订单号" hover note="{{orderNo}}" />
<t-cell title="类型" hover note="{{buy_type}}" />
<t-cell title="付款成功" hover note="{{price}}元" />
<view class="ma"></view>
<view class="form">
<t-input label="姓名" placeholder="请输入姓名" model:value="{{username}}" />
<t-input label="电话" placeholder="请输入电话" type="digit" model:value="{{phone}}" />
</view>
<view class="footer">
<t-button theme="primary" block catchtap="submit">提交</t-button>
</view>
<view class="ma"></view>
<view class="ma"></view>
<view wx:if="{{tip_after_pay}}">
<rich-text class="desc" nodes="{{tip_after_pay}}"></rich-text>
</view>
</view>

View file

@ -1,48 +0,0 @@
page {
box-sizing: border-box;
background-color: linear-gradient(180deg, #f0f4fc, #fff);
padding: 0 20rpx;
padding-top: 10rpx;
padding-bottom: calc(env(safe-area-inset-bottom) + 106rpx);
}
.logo {
height: 180rpx;
width: 180rpx;
margin: 0 auto;
background-image: url('http://cdn.zhonganonline.top/liiistem/static/liii_icon.png');
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
.form {
background: #fff;
border-radius: 10rpx;
overflow: hidden;
}
.footer {
margin-top: 40rpx;
padding: 0 20rpx;
}
.card {
margin: 20rpx 0;
padding: 0 20rpx;
}
.card .line {
font-size: 36rpx;
line-height: 60rpx;
}
.ma {
height: 20rpx;
}
.desc {
color: #666;
font-size: 28rpx;
margin-top: 20rpx;
line-height: 34rpx;
}
.refresh{
text-align: center;
margin-top: 20rpx;
color: #999;
}

View file

@ -1,77 +0,0 @@
import R from '../../utils/request';
import C from '../../utils/constant';
import * as F from '../../utils/func';
Page({
data: {
cdnHost: C.cdnHost,
list: [],
page: 1,
status: '',
// money_flag: 'send',
listEndText: '',
},
onLoad(options) {
this.fetchList(1);
},
goDel(e) {
const {detail,index} =e.currentTarget.dataset;
if(detail.deleted == 1) return;
const {id}=detail;
wx.showModal({
title: '提示',
content: '置为失效后无法恢复,确认继续吗?',
complete: (res) => {
if (res.cancel) {
}
if (res.confirm) {
R.post('/index.php/api/v1/del_share',{id}).then(()=>{
const {list} = this.data;
this.setData({
[`list[${index}]`] : {
...list[index],
deleted:1,
},
});
})
}
}
})
},
fetchList(page) {
const { status } = this.data;
// money_flag
R.get('/index.php/api/v1/share_link_list', { page }).then(({ model }) => {
const list = [];
model.forEach(item => {
list.push({
...item,
price: F.formatePrice(item.price),
expire_time: item.expire_time.split(' ')[0],
});
});
if (list.length == 0) {
this.setData({ listEndText: '没有更多了' });
} else {
this.setData({ listEndText: '点击加载更多。。。' });
}
if (page == 1) {
this.setData({ list,page });
} else {
const list2 = this.data.list.concat(list);
this.setData({ list: list2 ,page});
}
});
},
loadMore() {
const { page, listEndText } = this.data;
if (listEndText == '点击加载更多。。。') {
this.fetchList(page + 1);
}
},
onReachBottom() {
this.loadMore();
},
})

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