master
wangxinglong 2021-12-15 15:04:20 +08:00
parent 6a99ae542b
commit 872946ba8c
11 changed files with 372 additions and 8 deletions

View File

@ -883,3 +883,23 @@ if (!function_exists('is_mobile')) {
return preg_match("/^1(3|4|5|6|7|8|9)\d{9}$/", $num);
}
}
/**
* 求两个日期之间相差的天数
* (针对1970年1月1日之后求之前可以采用泰勒公式)
* @param string $day1
* @param string $day2
* @return number
*/
function diffBetweenTwoDays ($day1, $day2)
{
$second1 = strtotime($day1);
$second2 = strtotime($day2);
if ($second1 < $second2) {
$tmp = $second2;
$second2 = $second1;
$second1 = $tmp;
}
return ($second1 - $second2) / 86400;
}

View File

@ -22,6 +22,7 @@ class Area extends Base
public function index()
{
$pcode = input("areaId/d",86);
return json(AreaModel::getByPCode($pcode,false));
$filter = input("filter",false);
return json(AreaModel::getByPCode($pcode,$filter));
}
}

View File

@ -299,6 +299,18 @@ class Coupon extends Base
if(strtotime(date("Y-m-d ".$usingRule->day_end_time)) < $time){
return $this->json(4001, "请在当天{$usingRule->day_start_time}-{$usingRule->day_start_time}使用");
}
//签到距离
Config::load('extra/wechat', 'wechat');
$signDistance = config('wechat.signDistance')??0;
if($signDistance > 0 ){
$Distance = get_distance($coupon->lat,$coupon->lng,$lat,$lng);
if($Distance > $signDistance){
return $this->json(4001, "请在规定区域内使用优惠券");
}
}
$business = BusinessRepository::getInstance()->getModel()->with(["agency"])->where(["code"=>$coupon->couponMain->business_code])->lock(true)->find();
if(empty($business)){
return $this->json(4001, "商家不存在");
@ -487,6 +499,7 @@ class Coupon extends Base
if (!$usingRuleValidate->check($usingRule)) {
return $this->json(4001, $usingRuleValidate->getError());
}
//验证通过
$couponMain['business_type'] = $account->business['type'];
$couponMain['business_name'] = $account->business['business_name'];

View File

@ -41,9 +41,11 @@ class User extends Base
'code' => $this->request->param('code', ''),
'nick_name' => $this->request->param('nickName', ''),
'avatar_url' => $this->request->param('avatarUrl', ''),
'gender' => $this->request->param('gender', 0),
'gender' => $this->request->param('gender/d', 0),
'real_name' => $this->request->param('real_name/s', '',"trim"),
'mobile' => $this->request->param('mobile/s', ''),
'lat' => $this->request->param('lat/f', 0),
'lng' => $this->request->param('lng/f', 0),
];
$validate = new UserValidate();
@ -91,6 +93,8 @@ class User extends Base
'gender' => $params['gender'],
'real_name' => $params['real_name'],
'mobile' => $params['mobile'],
'lat' => $params['lat'],
'lng' => $params['lng'],
]);
} else {

View File

@ -0,0 +1,78 @@
<?php
namespace app\controller\manager;
use app\repository\AccountRepository;
use app\repository\CouponRepository;
/**
* 统计图
*/
class Statistical extends Base
{
/**
* 性别比例
* */
public function sign()
{
$startTime = input("startTime/s", date("Y-m-d", strtotime("-1 year")));
$endTime = input("endTime/s", date("Y-m-d"));
$agencyCode = input("agencyCode/s");
$this->data["startTime"] = $startTime;
$this->data["endTime"] = $endTime;
$xDay = diffBetweenTwoDays($startTime, $endTime);
if ($xDay > 366) {
return $this->error("日期不要超过");
}
//生成折现点
$x = ["product"];
$releaseDataArray = ["zero"=>"发布数量"];
$signDataArray = ["zero"=>"签到数量"];
$receiveDataArray = ["zero"=>"领取数量"];
for ($aa = 0; $aa <= $xDay; $aa++) {
$key = date("Y-m-d", strtotime($startTime . " +" . $aa . " day"));
$x[] = $key;
$releaseDataArray[$key] = 0;
$signDataArray[$key] = 0;
$receiveDataArray[$key] = 0;
}
$this->data["x"] = json_encode($x);
//拿数据
//发布
$release = CouponRepository::getInstance()->getReleaseStatistics($startTime,$endTime,$agencyCode);
foreach ($release as $item){
if(isset($releaseDataArray[$item["create_time"]])){
$releaseDataArray[$item["create_time"]]++;
}
}
$releaseDataArray= array_values($releaseDataArray);
$this->data["releaseDataArray"]=json_encode($releaseDataArray);
//签到数量
$sign = CouponRepository::getInstance()->getSignStatistics($startTime,$endTime,$agencyCode);
foreach ($sign as $item){
if(isset($signDataArray[$item["verificate_time"]])){
$signDataArray[$item["verificate_time"]]++;
}
}
$signDataArray= array_values($signDataArray);
$this->data["signDataArray"]=json_encode($signDataArray);
//领取数量
$receive = CouponRepository::getInstance()->getReceiveStatistics($startTime,$endTime,$agencyCode);
foreach ($receive as $item){
if(isset($receiveDataArray[$item["received_time"]])){
$receiveDataArray[$item["received_time"]]++;
}
}
$receiveDataArray= array_values($receiveDataArray);
$this->data["receiveDataArray"]=json_encode($receiveDataArray);
return $this->view();
}
}

View File

@ -4,6 +4,7 @@ namespace app\repository;
use app\exception\RepositoryException;
use app\model\Account;
use app\service\Repository;
use app\traits\account\ApplyStaffTrait;
use app\traits\account\BusinessFlowTrait;
@ -24,7 +25,6 @@ use think\Model;
*/
class AccountRepository extends Repository
{
use CommentTrait;
use CommentTrait;
use BusinessFlowTrait;
use CouponTrait;
@ -103,6 +103,4 @@ class AccountRepository extends Repository
return $user->save();
}
}

View File

@ -71,6 +71,77 @@ trait CouponMainTrait
$totalDeductionMoney += $item["total_deduction_money"];
}
return $totalDeductionMoney;
}
/**
* 获取 发布优惠券的统计
* 每条数据都走一遍
*
* */
public function getReleaseStatistics($startTime,$endTime,$agencyCode)
{
return CouponMain::alias("a")
->join("business b","a.business_code =b.code")
->whereTime("a.start_time", ">=", $startTime)
->whereTime("a.end_time", "<=", $endTime)
->when(!empty($agencyCode), function ($q) use ($agencyCode) {
$q->where("b.agency_code", $agencyCode);
})
->field("a.id,a.create_time")
->withAttr("create_time",function ($value){
return date("Y-m-d",strtotime($value));
})
->order(["a.id" => "desc"])
->select()
->toArray()
;
}
/**
* 获取 验证优惠券的统计
* 每条数据都走一遍
*
* */
public function getSignStatistics($startTime,$endTime,$agencyCode)
{
return Coupon::alias("a")
->join("business b","a.business_code =b.code")
->whereTime("a.verificate_time", ">=", $startTime)
->whereTime("a.verificate_time", "<=", $endTime)
->where("a.is_verificated", "=", Coupon::is_verificated_on)
->when(!empty($agencyCode), function ($q) use ($agencyCode) {
$q->where("b.agency_code", $agencyCode);
})
->field("a.id,a.verificate_time")
->withAttr("verificate_time",function ($value){
return date("Y-m-d",strtotime($value));
})
->order(["a.id" => "desc"])
->select()
->toArray()
;
}
/**
* 获取 验证优惠券的统计
* 每条数据都走一遍
*
* */
public function getReceiveStatistics($startTime,$endTime,$agencyCode)
{
return Coupon::alias("a")
->join("business b","a.business_code =b.code")
->whereTime("a.received_time", ">=", $startTime)
->whereTime("a.received_time", "<=", $endTime)
->when(!empty($agencyCode), function ($q) use ($agencyCode) {
$q->where("b.agency_code", $agencyCode);
})
->field("a.id,a.received_time")
->withAttr("received_time",function ($value){
return date("Y-m-d",strtotime($value));
})
->order(["a.id" => "desc"])
->select()
->toArray()
;
}
}

View File

@ -2,6 +2,7 @@
namespace app\validate;
use think\facade\Config;
use think\Validate;
class CouponRelease extends Validate
@ -16,7 +17,7 @@ class CouponRelease extends Validate
'end_time|结束时间' => 'require|date|checkEndTime',
'name|优惠券名称' => 'require|length:3,32',
'money|金额' => 'require|>:0|<:5000',
'deduction_money|扣除金额' => 'require|>=:0.1|<:5000',
'deduction_money|扣除金额' => 'require|checkDeductionMoney|>=:0.1|<:5000',
//'image_url|预览图' => '',
//'using_rule|使用规则' => '',
//'punishing_rule|处罚规则' => '',
@ -29,7 +30,6 @@ class CouponRelease extends Validate
//'white_list|白名单' => '',
];
protected $scene = [
'edit' => ['start_time', 'end_time', 'name',"status","on_shelf"],
'api_edit' => ['name', 'type', 'start_time',"end_time","image_url"],
@ -44,4 +44,15 @@ class CouponRelease extends Validate
}
protected function checkDeductionMoney($value, $rule, $data = [])
{
//最小充值
Config::load('extra/wechat', 'wechat');
$minCouponDeductionMoney = config('wechat.minCouponDeductionMoney') ?? 0;
if($minCouponDeductionMoney > 0 &&$minCouponDeductionMoney>$value){
return "最小扣除佣金{$minCouponDeductionMoney}";
}
return true;
}
}

View File

@ -12,11 +12,13 @@ class User extends Validate
'nick_name|昵称' => 'max:100',
'avatar_url|头像' => 'max:250',
'gender|性别' => 'number',
'lat|位置' => 'require|>:0',
'lng|位置' => 'require|>:0',
];
protected $scene = [
// 微信小程序登录
'wx_applets' => ['code', 'nick_name', 'gender'],
'wx_applets' => ['code', 'nick_name', 'gender',"lat","lng"],
];
}

View File

@ -139,6 +139,22 @@
<input class="layui-input" type="text" name="commentNum" value="{$item.commentNum ?? 10}"/>
</div>
</div>
<div class="layui-form-item layui-form-item-lg">
<label class="layui-form-label">签到距离0表示不限</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="signDistance" value="{$item.signDistance ?? 0}"/>
</div>
</div>
<div class="layui-form-item layui-form-item-lg">
<label class="layui-form-label">优惠券最小佣金0表示不限</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="minCouponDeductionMoney" value="{$item.minCouponDeductionMoney ?? 0}"/>
</div>
</div>
<div class="layui-form-item layui-form-item-lg layui-hide">
<label class="layui-form-label">评论人工审核可见</label>
<div class="layui-input-block">

View File

@ -0,0 +1,150 @@
{layout name="manager/layout" /}
<div class="layui-row layui-col-space12">
<div class="layui-col-xs12 layui-col-md12">
<div style="background-color:#ffffff;min-height:600px;">
<div class="layuimini-container location-index-page">
<div class="layuimini-main">
<fieldset class="table-search-fieldset">
<legend>搜索信息</legend>
<div style="margin: 10px 10px 10px 10px">
<form class="layui-form layui-form-pane" action="">
<div class="layui-form-item">
<div class="layui-inline">
时间段:
<div class="layui-inline">
<input type="text" class="layui-input" value="{$startTime}" id="start_time">
</div>
-
<div class="layui-inline">
<input class="layui-input" type="text" value="{$endTime}" id="end_time">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">平台商</label>
<div class="layui-input-block">
<select name="agency">
<option value=""></option>
</select>
</div>
</div>
<div class="layui-inline layui-hide" >
<label class="layui-form-label">类型</label>
<div class="layui-input-block">
<select name="agency">
<option value="release" selected>发布数量</option>
<option value="sign">签到数量</option>
<option value="receive">领取数量</option>
</select>
</div>
</div>
<div class="layui-inline">
<button type="submit" class="layui-btn layui-btn-primary" lay-submit lay-filter="data-search-btn"><i class="layui-icon"></i> 搜 索</button>
</div>
</div>
</form>
</div>
</fieldset>
<div class="layui-row layui-col-space15">
<div class="layui-col-xs12 layui-col-md12">
<div id="echarts-dataset" style="background-color:#ffffff;min-height:300px;padding: 10px"></div>
</div>
<div class="layui-col-xs12 layui-col-md12">
<div id="echarts-map" style="background-color:#ffffff;min-height:300px;padding: 10px"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
layui.use(['echarts', 'jquery', 'form', 'laydate'], function () {
var laydate = layui.laydate,
$ = layui.jquery,
echarts = layui.echarts
;
//日期时间选择器
laydate.render({
elem: '#start_time'
,type: 'date'
});
laydate.render({
elem: '#end_time'
,type: 'date'
});
/**
* 中国地图
*/
var echartsMap = echarts.init(document.getElementById('echarts-map'), 'walden');
//console.log( JSON.parse('{$x|raw}'));
var x = JSON.parse('{$x|raw}');//X轴
var release = JSON.parse('{$releaseDataArray|raw}');//发布
var signDataArray = JSON.parse('{$signDataArray|raw}');//发布
var receiveDataArray = JSON.parse('{$receiveDataArray|raw}');//发布
// console.log( JSON.parse('{$releaseDataArray|raw}'));
// console.log( JSON.parse('{$signDataArray|raw}'));
var optionMap = {
legend: {},
tooltip: {
trigger: 'axis',
showContent: false
},
dataset: {
source: [
x,//X轴
// ['product', '2012', '2013', '2014', '2015', '2016', '2017'],
release,//发布数量
signDataArray,//签到数量
receiveDataArray,//领取数量
//折线图
// ['Matcha Latte', 41.1, 30.4, 65.1, 53.3, 83.8, 98.7],
// ['Milk Tea', 86.5, 92.1, 85.7, 83.1, 73.4, 55.1],
// ['Cheese Cocoa', 24.1, 67.2, 79.5, 86.4, 65.2, 82.5],
// ['Walnut Brownie', 55.2, 67.1, 69.2, 72.4, 53.9, 39.1]
]
},
xAxis: {type: 'category'},
yAxis: {gridIndex: 0},
grid: {top: '55%'},
series: [
{type: 'line', smooth: true, seriesLayoutBy: 'row'},
{type: 'line', smooth: true, seriesLayoutBy: 'row'},
{type: 'line', smooth: true, seriesLayoutBy: 'row'},
{
type: 'pie',
id: 'pie',
radius: '30%',
center: ['50%', '25%'],
label: {
formatter: '{b}: {@2012} ({d}%)'
},
encode: {
itemName: 'x',
value: '2012',
tooltip: '2012'
}
}
]
};
echartsMap.setOption(optionMap);
// echarts 窗口缩放自适应
window.onresize = function () {
echartsMap.resize();
}
})
</script>