zxhxx 3 년 전
커밋
75d6c43762

+ 23 - 0
app/admin/controller/order/Level.php

@@ -0,0 +1,23 @@
+<?php
+namespace app\admin\controller\order;
+use app\admin\controller\AuthController;
+use app\models\order\Level as LevelModel;
+use think\facade\Route as Url;
+use crmeb\services\{
+    UtilService as Util
+};
+class Level extends AuthController
+{
+    public function index()
+    {
+        $where = Util::getMore([
+            ['data', ''],
+            ['key', ''],
+            ['paid',-1],
+        ], $this->request);
+        $where['data'] = trim($where['data']);
+        $this->assign('where', $where);
+        $this->assign(LevelModel::orderlist($where));
+        return $this->fetch();
+    }
+}

+ 140 - 0
app/admin/controller/ump/StoreWholesale.php

@@ -0,0 +1,140 @@
+<?php
+namespace app\admin\controller\ump;
+use app\admin\controller\AuthController;
+use app\admin\model\system\SystemGroupData;
+use app\models\store\StoreWholesale as Wholesale;
+use crmeb\services\{UtilService,JsonService as Json,UtilService as Util};
+
+
+class StoreWholesale extends  AuthController
+{
+    public function index()
+    {
+        $this->assign('countSeckill', Wholesale::getWholeCount());
+        $this->assign('seckillId', Wholesale::getWholeIdAll());
+        return $this->fetch();
+    }
+    public function save_excel()
+    {
+        $where = Util::getMore([
+            ['status', ''],
+            ['store_name', '']
+        ]);
+        Wholesale::SaveExcel($where);
+    }
+
+    /**
+     * 异步获取砍价数据
+     */
+    public function getlist()
+    {
+        $where = UtilService::getMore([
+            ['page', 1],
+            ['limit', 20],
+            ['status', ''],
+            ['store_name', '']
+        ]);
+        $seckillList = Wholesale::systemPage($where);
+        if (is_object($seckillList['list'])) $seckillList['list'] = $seckillList['list']->toArray();
+        $data = $seckillList['list']['data'];
+
+        foreach ($data as $k => $v) {
+            $end_time = $v['stop_time'];
+            if ($end_time) {
+                $config = SystemGroupData::get($v['time_id']);
+                if ($config) {
+                    $arr = json_decode($config->value, true);
+                    $start_hour = intval($arr['time']['value']);
+                    $continued = intval($arr['continued']['value']);
+                    $end_hour = $start_hour + $continued;
+                    $end_time = $end_time . ' ' . $end_hour . ':00:00';
+                }
+            }
+            $data[$k]['_stop_time'] = $end_time;
+        }
+        return Json::successlayui(['count' => $seckillList['list']['total'], 'data' => $data]);
+    }
+    public function create($id=0)
+    {
+        $this->assign('id', (int)$id);
+        return $this->fetch();
+    }
+    /**
+     * 获取产品详细信息
+     * @param int $id
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function get_product_info($id = 0)
+    {
+        $data['productInfo'] = [];
+        if ($id) {
+            $productInfo = Wholesale::get($id);
+            $data['productInfo'] = $productInfo;
+        }
+        $data['time_id'] = sys_data('whole_time');
+        return Json::successful($data);
+    }
+
+    /**
+     * 保存新建的资源
+     *
+     *
+     */
+    public function save($id)
+    {
+        $data = Util::postMore([
+            'title',
+            'info',
+            'keyword',
+            ['unit_name', '件'],
+            ['image', []],
+            ['images', []],
+            ['price',0],
+            ['cost',0],
+            ['postage', 0],
+            ['ot_price', 0],
+            ['give_integral', 0],
+            ['sort',0],
+            ['stock', 0],
+            ['description', ''],
+            ['start_time', ''],
+            ['stop_time', ''],
+            ['time_id', 0],
+            ['is_hot', 0],
+            ['is_news', 0],
+            ['num', 1],
+            ['is_show',1]
+        ]);
+        if (count($data['image']) < 1) return Json::fail('请上传产品图片');
+        if (count($data['images']) < 1) return Json::fail('请上传产品轮播图');
+        $data['image'] = $data['image'][0];
+        $data['images'] = json_encode($data['images']);
+        Wholesale::beginTrans();
+        if ($id) {
+            unset($data['sales']);
+            $attr_res =  Wholesale::edit($data, $id);
+
+            if ($attr_res) {
+                Wholesale::commitTrans();
+                return Json::success('修改成功!');
+            } else {
+                Wholesale::rollbackTrans();
+                return Json::fail(Wholesale::getErrorInfo());
+            }
+        } else {
+            $data['add_time'] = time();
+
+            $res = Wholesale::create($data);
+            if ($res) {
+                Wholesale::commitTrans();
+                return Json::success('添加产品成功!');
+            } else {
+                Wholesale::rollbackTrans();
+                return Json::fail(StoreProductAttr::getErrorInfo());
+            }
+        }
+    }
+
+}

+ 165 - 0
app/admin/view/order/level/index.php

@@ -0,0 +1,165 @@
+{extend name="public/container"}
+{block name="content"}
+<div class="row">
+    <div class="col-sm-12">
+        <div class="ibox">
+            <div class="ibox-content">
+                <div class="row">
+                    <div class="m-b m-l">
+                        <form action="" class="form-inline">
+                            <div id="upSearch" class="layui-col-lg12">
+                                <label class="layui-form-label">创建时间:</label>
+                                <div class="layui-input-block" data-type="data" v-cloak="">
+                                    <button class="layui-btn layui-btn-sm" type="button" v-for="item in dataList"
+                                            @click="setData(item)"
+                                            :class="{'layui-btn-primary':where.data!=item.value}">{{item.name}}
+                                    </button>
+                                    <button class="layui-btn layui-btn-sm" type="button" ref="time"
+                                            @click="setData({value:'zd',is_zd:true})"
+                                            :class="{'layui-btn-primary':where.data!='zd'}">自定义
+                                    </button>
+                                    <button type="button" class="layui-btn layui-btn-sm layui-btn-primary"
+                                            v-show="showtime==true" ref="date_time">
+                                    </button>
+                                </div>
+                                <input name='data' type='hidden' :value="where.data" />
+                            </div>
+                            <div class="layui-col-lg12">
+                                <select name="paid" aria-controls="editable" class="form-control input-sm">
+                                    <option value="-1">所有状态</option>
+                                    <option value="0" {eq name="where.paid" value="0"}selected="selected"{/eq}>待支付</option>
+                                    <option value="1" {eq name="where.paid" value="1"}selected="selected"{/eq}>已支付</option>
+                                </select>
+                                <div class="input-group">
+                                    <input type="text" name="key" value="{$where.key}" placeholder="请输入订单编号" class="input-sm form-control"> <span class="input-group-btn">
+                                            <button id='upDataSubmit' type="submit" class="btn btn-sm btn-primary"> <i class="fa fa-search"></i>搜索</button>
+                                        </span>
+                                </div>
+                            </div>
+
+                        </form>
+                    </div>
+
+                </div>
+                <div class="table-responsive">
+                    <table class="table table-striped  table-bordered">
+                        <thead>
+                        <tr>
+                            <th class="text-center">订单编号</th>
+                            <th class="text-center">昵称</th>
+                            <th class="text-center">名称</th>
+                            <th class="text-center">金额</th>
+                            <th class="text-center">创建时间</th>
+                            <th class="text-center">支付时间</th>
+                            <th class="text-center">支付方式</th>
+
+                        </tr>
+                        </thead>
+                        <tbody class="">
+                        {volist name="list" id="vo"}
+                        <tr>
+                            <td>
+                                {$vo.order_id}
+                            </td>
+                            <td class="text-center">
+                                {$vo.nickname}
+                            </td>
+
+                            <td class="text-center">
+                                {$vo.body}
+                            </td>
+                            <td class="text-center">
+                                {$vo.pay_price}
+                            </td>
+                            <td class="text-center">
+                                {:date("Y-m-d H:i:s",$vo.addtime)}
+                            </td>
+                            <td class="text-center">
+                                {$vo.pay_time}
+                            </td>
+                            <td class="text-center">
+                                {$vo.pay_type}
+                            </td>
+                        </tr>
+                        {/volist}
+                        </tbody>
+                    </table>
+                </div>
+                {include file="public/inner_page"}
+            </div>
+        </div>
+    </div>
+</div>
+<script src="{__ADMIN_PATH}js/layuiList.js"></script>
+{/block}
+{block name="script"}
+<script>
+    let upSearchData = '{$where.data}';
+    var showTime=false;
+    if(upSearchData){
+        if(upSearchData.length>11){
+            showTime = true
+        }
+    }
+    $('.btn-danger').on('click',function(){
+        window.t = $(this);
+        var _this = $(this),url =_this.data('url');
+        $eb.$swal('delete',function(){
+            $eb.axios.get(url).then(function(res){
+                console.log(res);
+                if(res.status == 200 && res.data.code == 200) {
+                    $eb.$swal('success',res.data.msg);
+                    _this.parents('tr').remove();
+                }else
+                    return Promise.reject(res.data.msg || '删除失败')
+            }).catch(function(err){
+                $eb.$swal('error',err);
+            });
+        })
+    });
+    require(['vue'], function (Vue) {
+        new Vue({
+            el: "#upSearch",
+            data: {
+                dataList: [
+                    {name: '全部', value: ''},
+                    {name: '今天', value: 'today'},
+                    {name: '昨天', value: 'yesterday'},
+                    {name: '最近7天', value: 'lately7'},
+                    {name: '最近30天', value: 'lately30'},
+                    {name: '本月', value: 'month'},
+                    {name: '本年', value: 'year'},
+                ],
+                where: {
+                    data:upSearchData,
+                },
+                showtime: showTime,
+            },
+            methods: {
+                setData: function (item) {
+                    var that = this;
+                    if (item.is_zd == true) {
+                        that.showtime = true;
+                        this.where.data = this.$refs.date_time.innerText;
+                    } else {
+                        this.showtime = false;
+                        this.where.data = item.value;
+                    }
+                },
+            },
+            mounted: function () {
+                let that = this;
+                layList.laydate.render({
+                    elem: this.$refs.date_time,
+                    trigger: 'click',
+                    eventElem: this.$refs.time,
+                    range: true,
+                    change: function (value) {
+                        that.where.data = value;
+                    }
+                });
+            }
+        })
+    });
+</script>
+{/block}

+ 1105 - 0
app/admin/view/ump/store_wholesale/create.php

@@ -0,0 +1,1105 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
+    <link href="{__FRAME_PATH}css/font-awesome.min.css" rel="stylesheet">
+    <link href="{__ADMIN_PATH}plug/umeditor/themes/default/css/umeditor.css" type="text/css" rel="stylesheet">
+    <script type="text/javascript" src="{__ADMIN_PATH}plug/umeditor/third-party/jquery.min.js"></script>
+    <script type="text/javascript" src="{__ADMIN_PATH}plug/umeditor/third-party/template.min.js"></script>
+    <script type="text/javascript" charset="utf-8" src="{__ADMIN_PATH}plug/umeditor/umeditor.config.js"></script>
+    <script type="text/javascript" charset="utf-8" src="{__ADMIN_PATH}plug/umeditor/umeditor.min.js"></script>
+    <script type="text/javascript" src="{__ADMIN_PATH}plug/umeditor/lang/zh-cn/zh-cn.js"></script>
+    <link rel="stylesheet" href="/static/plug/layui/css/layui.css">
+    <script src="/static/plug/layui/layui.js"></script>
+    <script src="{__PLUG_PATH}vue/dist/vue.min.js"></script>
+    <script src="/static/plug/axios.min.js"></script>
+    <script src="{__MODULE_PATH}widget/aliyun-oss-sdk-4.4.4.min.js"></script>
+    <script src="{__MODULE_PATH}widget/cos-js-sdk-v5.min.js"></script>
+    <script src="{__MODULE_PATH}widget/qiniu-js-sdk-2.5.5.js"></script>
+    <script src="{__MODULE_PATH}widget/plupload.full.min.js"></script>
+    <script src="{__MODULE_PATH}widget/videoUpload.js"></script>
+    <style>
+        .layui-form-item {
+            margin-bottom: 0px;
+        }
+
+        .pictrueBox {
+            display: inline-block !important;
+        }
+
+        .pictrue {
+            width: 60px;
+            height: 60px;
+            border: 1px dotted rgba(0, 0, 0, 0.1);
+            margin-right: 15px;
+            display: inline-block;
+            position: relative;
+            cursor: pointer;
+        }
+
+        .pictrue img {
+            width: 100%;
+            height: 100%;
+        }
+
+        .upLoad {
+            width: 58px;
+            height: 58px;
+            line-height: 58px;
+            border: 1px dotted rgba(0, 0, 0, 0.1);
+            border-radius: 4px;
+            background: rgba(0, 0, 0, 0.02);
+            cursor: pointer;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+        }
+
+        .rulesBox {
+            display: flex;
+            flex-wrap: wrap;
+            margin-left: 10px;
+        }
+
+        .layui-tab-content {
+            margin-top: 15px;
+        }
+
+        .ml110 {
+            margin: 18px 0 4px 110px;
+        }
+
+        .rules {
+            display: flex;
+        }
+
+        .rules-btn-sm {
+            height: 30px;
+            line-height: 30px;
+            font-size: 12px;
+            width: 109px;
+        }
+
+        .rules-btn-sm input {
+            width: 79% !important;
+            height: 84% !important;
+            padding: 0 10px;
+        }
+
+        .ml10 {
+            margin-left: 10px !important;
+        }
+
+        .ml40 {
+            margin-left: 40px !important;
+        }
+
+        .closes {
+            position: absolute;
+            left: 86%;
+            top: -18%;
+        }
+        .red {
+            color: red;
+        }
+        .layui-input-block .layui-video-box{
+            width: 22%;
+            height: 180px;
+            border-radius: 10px;
+            background-color: #707070;
+            margin-top: 10px;
+            position: relative;
+            overflow: hidden;
+        }
+        .layui-input-block .layui-video-box i{
+            color: #fff;
+            line-height: 180px;
+            margin: 0 auto;
+            width: 50px;
+            height: 50px;
+            display: inherit;
+            font-size: 50px;
+        }
+        .layui-input-block .layui-video-box .mark{
+            position: absolute;
+            width: 100%;
+            height: 30px;
+            top: 0;
+            background-color: rgba(0,0,0,.5);
+            text-align: center;
+        }
+        .store_box{
+            display: flex;
+        }
+        .info{
+            color: #c9c9c9;
+            padding-left: 10px;
+            line-height: 30px;
+        }
+        #listDetial{
+            height: 38px;
+            line-height: 1.3;
+            border-width: 1px;
+            border-style: solid;
+            padding:0 10px;
+            background-color: #fff;
+            border-radius: 2px;
+            border-color: #D2D2D2!important;
+            outline: 0;
+            width: 100%;
+            -webkit-appearance: none;
+            transition: all .3s;
+            -webkit-transition: all .3s;
+            box-sizing: border-box;
+        }
+    </style>
+</head>
+<body>
+<div class="layui-fluid">
+    <div class="layui-row layui-col-space15"  id="app" v-cloak="">
+        <div class="layui-card">
+            <div class="layui-card-header">
+                <span class="">{{id ? '商品修改': '商品添加' }}</span>
+                <button style="margin-left: 20px" type="button" class="layui-btn layui-btn-primary layui-btn-xs" @click="goBack">返回列表</button>
+            </div>
+            <div class="layui-card-body">
+                <form class="layui-form" action="" v-cloak="">
+                    <div class="layui-tab layui-tab-brief" lay-filter="docTabBrief">
+                        <ul class="layui-tab-title">
+                            <li class="layui-this" lay-id='1'>基础信息</li>
+                            <li lay-id='2'>商品详情</li>
+                        </ul>
+                        <div class="layui-tab-content">
+                            <div class="layui-tab-item layui-show">
+                                <div class="layui-row layui-col-space15">
+                                    <div class="layui-col-xs12 layui-col-sm12 layui-col-md12">
+                                        <div class="grid-demo grid-demo-bg1">
+                                            <div class="layui-form-item">
+                                                <label class="layui-form-label">商品名称<i class="red">*</i></label>
+                                                <div class="layui-input-block">
+                                                    <input type="text" name="title" lay-verify="title" autocomplete="off"
+                                                           placeholder="请输入商品名称" class="layui-input" v-model="formData.title" maxlength="100">
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                    <div class="layui-col-xs12 layui-col-sm12 layui-col-md12">
+                                        <div class="grid-demo grid-demo-bg1">
+                                            <div class="layui-form-item">
+                                                <label class="layui-form-label">单位</label>
+                                                <div class="layui-input-block">
+                                                    <input style="width: 40%" type="text" name="unit_name" lay-verify="title" autocomplete="off"
+                                                           placeholder="请输入单位" class="layui-input" v-model="formData.unit_name">
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                    <div class="layui-col-xs12 layui-col-sm12 layui-col-md12">
+                                        <div class="grid-demo grid-demo-bg1">
+                                            <div class="layui-form-item">
+                                                <label class="layui-form-label">时间</label>
+                                                <div class="layui-input-block">
+                                                    <input style="width: 40%" type="text" name="unit_name" id="date" lay-verify="date" autocomplete="off"
+                                                           placeholder="选择时间" class="layui-input" >
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                    <div class="layui-col-xs12 layui-col-sm12 layui-col-md12">
+                                        <div class="grid-demo grid-demo-bg1">
+                                            <div class="layui-form-item">
+                                                <label class="layui-form-label">商品封面图<i class="red">*</i></label>
+                                                <div class="pictrueBox">
+                                                    <div class="pictrue" v-if="formData.image" @click="uploadImage('image')">
+                                                        <img :src="formData.image"></div>
+                                                    <div class="upLoad" @click="uploadImage('image')" v-else>
+                                                        <i class="layui-icon layui-icon-camera" class="iconfont"
+                                                           style="font-size: 26px;"></i>
+                                                    </div>
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                    <div class="layui-col-xs12 layui-col-sm12 layui-col-md12">
+                                        <div class="grid-demo grid-demo-bg1">
+                                            <div class="layui-form-item">
+                                                <label class="layui-form-label">商品轮播图<i class="red">*</i></label>
+                                                <div class="pictrueBox pictrue" v-for="(item,index) in formData.images">
+                                                    <img :src="item">
+                                                    <i class="layui-icon closes" @click="deleteImage('images',index)">&#x1007</i>
+                                                </div>
+                                                <div class="pictrueBox">
+                                                    <div class="upLoad" @click="uploadImage('images')"
+                                                         v-if="formData.images.length <= rule.images.maxLength">
+                                                        <i class="layui-icon layui-icon-camera" class="iconfont"
+                                                           style="font-size: 26px;"></i>
+                                                    </div>
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                    <div class="layui-col-xs12 layui-col-sm12 layui-col-md12" v-if="formData.spec_type == 1">
+                                    </div>
+                                </div>
+                                <div class="layui-col-xs12 layui-col-sm12 layui-col-md12">
+                                    <div class="grid-demo grid-demo-bg1">
+                                        <div class="layui-form-item">
+                                            <label class="layui-form-label">时间</label>
+                                            <div class="layui-input-block">
+                                                <input list="browsers" id="listDetial" v-model="formData.time_id">
+                                                <datalist id="browsers">
+                                                    <option v-for="ls in tempList" :value="ls.id">{{'开始时间:'+ls.time+' - 持续时间:'+ls.continued}}</option>
+                                                </datalist>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+                                <div class="layui-row layui-col-space15">
+                                    <div class="layui-col-xs12 layui-col-sm4 layui-col-md4">
+                                        <div class="grid-demo grid-demo-bg1">
+                                            <div class="layui-form-item">
+                                                <label class="layui-form-label">商品状态</label>
+                                                <div class="layui-input-block">
+                                                    <input type="radio" name="is_show" lay-filter="is_show" value="1" title="上架"
+                                                           :checked="formData.is_show == 1 ? true : false">
+                                                    <input type="radio" name="is_show" lay-filter="is_show" value="0" title="下架"
+                                                           :checked="formData.is_show == 0 ? true : false">
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                    <div class="layui-col-xs12 layui-col-sm4 layui-col-md4">
+                                        <div class="grid-demo grid-demo-bg1">
+                                            <div class="layui-form-item">
+                                                <label class="layui-form-label">热卖单品</label>
+                                                <div class="layui-input-block">
+                                                    <input type="radio" name="is_hot" lay-filter="is_hot" value="1" title="开启"
+                                                           :checked="formData.is_hot == 1 ? true : false">
+                                                    <input type="radio" name="is_hot" lay-filter="is_hot" value="0" title="关闭"
+                                                           :checked="formData.is_hot == 0 ? true : false">
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                    <div class="layui-col-xs12 layui-col-sm4 layui-col-md4">
+                                        <div class="grid-demo grid-demo-bg1">
+                                            <div class="layui-form-item">
+                                                <label class="layui-form-label">新人礼包</label>
+                                                <div class="layui-input-block">
+                                                    <input type="radio" name="is_news" lay-filter="is_news" value="1" title="开启"
+                                                           :checked="formData.is_news == 1 ? true : false">
+                                                    <input type="radio" name="is_news" lay-filter="is_news" value="0" title="关闭"
+                                                           :checked="formData.is_news == 0 ? true : false">
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+                                <div class="layui-col-xs12 layui-col-sm4 layui-col-md4">
+                                    <div class="grid-demo grid-demo-bg1">
+                                        <div class="layui-form-item">
+                                            <label class="layui-form-label">价格</label>
+                                            <div class="layui-input-block">
+                                                <input type="number" name="price" lay-verify="price"
+                                                       autocomplete="off" placeholder="请输入价格" class="layui-input" v-model="formData.price">
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+                                <div class="layui-col-xs12 layui-col-sm4 layui-col-md4">
+                                    <div class="grid-demo grid-demo-bg1">
+                                        <div class="layui-form-item">
+                                            <label class="layui-form-label">成本</label>
+                                            <div class="layui-input-block">
+                                                <input type="number" name="cost" lay-verify="cost"
+                                                       autocomplete="off" placeholder="请输入成本" class="layui-input" v-model="formData.cost">
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+                                <div class="layui-col-xs12 layui-col-sm4 layui-col-md4">
+                                    <div class="grid-demo grid-demo-bg1">
+                                        <div class="layui-form-item">
+                                            <label class="layui-form-label">原价</label>
+                                            <div class="layui-input-block">
+                                                <input type="number" name="ot_price" lay-verify="ot_price"
+                                                       autocomplete="off" placeholder="请输入原价" class="layui-input" v-model="formData.ot_price">
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+                                <div class="layui-col-xs12 layui-col-sm4 layui-col-md4">
+                                    <div class="grid-demo grid-demo-bg1">
+                                        <div class="layui-form-item">
+                                            <label class="layui-form-label">库存</label>
+                                            <div class="layui-input-block">
+                                                <input type="number" name="stock" lay-verify="stock"
+                                                       autocomplete="off" placeholder="请输入库存" class="layui-input" v-model="formData.stock">
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+                                <div class="layui-col-xs12 layui-col-sm4 layui-col-md4">
+                                    <div class="grid-demo grid-demo-bg1">
+                                        <div class="layui-form-item">
+                                            <label class="layui-form-label">可的积分</label>
+                                            <div class="layui-input-block">
+                                                <input type="number" name="give_integral" lay-verify="title"
+                                                       autocomplete="off" placeholder="请输入可的积分" class="layui-input" v-model="formData.give_integral">
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+                                <div class="layui-col-xs12 layui-col-sm4 layui-col-md4">
+                                    <div class="grid-demo grid-demo-bg1">
+                                        <div class="layui-form-item">
+                                            <label class="layui-form-label">排序</label>
+                                            <div class="layui-input-block">
+                                                <input type="number" name="sort" lay-verify="title" autocomplete="off"
+                                                       placeholder="请输入排序" class="layui-input" v-model="formData.sort">
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
+                            <div class="layui-tab-item">
+                                <div class="layui-row layui-col-space15">
+                                    <textarea type="text/plain" name="description" id="myEditor" style="width:100%;">{{formData.description}}</textarea>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="layui-tab-content">
+                            <div class="layui-row layui-col-space15">
+                                <div class="layui-col-xs12 layui-col-sm12 layui-col-md12">
+                                    <div class="grid-demo grid-demo-bg1">
+                                        <div class="layui-form-item" v-if="id">
+                                            <button class="layui-btn layui-btn-primary layui-btn-sm" id="submit" type="button" @click="handleSubmit()">保存</button>
+                                            <button class="layui-btn layui-btn-primary layui-btn-sm" type="button" @click="back" v-if="layTabId != 1">上一步</button>
+                                            <button class="layui-btn layui-btn-normal layui-btn-sm" type="button" v-if="layTabId != 3" @click="next">下一步</button>
+                                        </div>
+                                        <div class="layui-form-item" v-else>
+                                            <button class="layui-btn layui-btn-primary layui-btn-sm" type="button" @click="back" v-if="layTabId != 1">上一步</button>
+                                            <button class="layui-btn layui-btn-normal layui-btn-sm" type="button" @click="next" v-if="layTabId ==1">下一步</button>
+                                            <button class="layui-btn layui-btn-normal layui-btn-sm" id="submit" type="button" v-if="layTabId == 2" @click="handleSubmit()">提交</button>
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </form>
+            </div>
+        </div>
+    </div>
+</div>
+<script src="{__ADMIN_PATH}js/layuiList.js"></script>
+<script>
+    var id = {$id};
+    new Vue({
+        el: '#app',
+        data: {
+            id:id,
+            //分类列表
+            cateList: [],
+            //运费模板
+            tempList: [],
+            upload:{
+                videoIng:false
+            },
+            formData: {
+                cate_id: [],
+                temp_id: 0,
+                commission:0,
+                title: '',
+                keyword: '',
+                unit_name: '',
+                postage: '',
+                store_info: '',
+                image: '',
+                video_link: '',
+                images: [],
+                price: 0,
+                cost: 0,
+                ot_price: 0,
+                stock: 0,
+                spec_type: 0,
+                attr: {
+                    pic: '',
+                    price: 0,
+                    cost: 0,
+                    ot_price: 0,
+                    stock: 0,
+                    bar_code: '',
+                    weight: 0,
+                    volume: 0,
+                    brokerage: 0,
+                    brokerage_two: 0,
+                },
+                where:{
+
+                    data:''
+                },
+                attrs: [],
+                description: '',
+                ficti: 0,
+                give_integral: 0,
+                sort: 0,
+                is_show: 1,
+                is_hot: 0,
+                is_benefit: 0,
+                is_best: 0,
+                is_news: 0,
+                is_good: 0,
+                is_sub:0,
+                time_id:'',
+                items: [
+                    // {
+                    //     value: '',
+                    //     detailValue:'',
+                    //     attrHidden:false,
+                    //     detail:[]
+                    // }
+                ],
+                activity:['秒杀','砍价','拼团'],
+            },
+            videoLink:'',
+            //批量添加属性
+            batchAttr:{
+                pic: '',
+                price: 0,
+                cost: 0,
+                ot_price: 0,
+                stock: 0,
+                bar_code: '',
+                weight: 0,
+                volume: 0,
+            },
+            //多属性header头
+            formHeader:[],
+            // 规格数据
+            formDynamic: {
+                attrsName: '',
+                attrsVal: ''
+            },
+            brokerage:{
+                brokerage: '',
+                brokerage_two: '',
+            },
+            activity:{'秒杀':'#1E9FFF','砍价':'#189688','拼团':'#FEB900'},
+            attr: [],//临时属性
+            newRule: false,//是否添加新规则
+            radioRule: ['is_sub','is_show', 'is_hot', 'is_benefit', 'is_new','is_good' ,'is_best', 'spec_type'],//radio 当选规则
+            rule: { //多图选择规则
+                images: {
+                    maxLength: 5
+                }
+            },
+            ruleList:[],
+            ruleIndex:-1,
+            progress: 0,
+            um: null,//编译器实例化
+            form: null,//layui.form
+            layTabId: 1,
+            ruleBool: id ? true : false,
+        },
+        watch:{
+            'formData.is_sub':function (n) {
+                if (n == 1) {
+                    this.formHeader.push({title:'一级返佣(元)'});
+                    this.formHeader.push({title:'二级级返佣(元)'});
+                } else {
+                    this.formHeader.pop();
+                    this.formHeader.pop();
+                }
+            },
+            'formData.spec_type':function (n) {
+                if (n) {
+                    this.render();
+                }
+            },
+            // 'formData.image':function (n) {
+            //     if(!this.batchAttr.pic){
+            //         this.batchAttr.pic = n;
+            //     }
+            //     if(!this.formData.attr.pic){
+            //         this.formData.attr.pic = n;
+            //     }
+            // }
+        },
+        methods: {
+            back:function(){
+                var that = this;
+                layui.use(['element'], function () {
+                    layui.element.tabChange('docTabBrief', that.layTabId == 1 ? 1 : parseInt(that.layTabId) - 1);
+                });
+            },
+            next:function(){
+                var that = this;
+                layui.use(['element'], function () {
+                    layui.element.tabChange('docTabBrief', that.layTabId == 3 ? 3 : parseInt(that.layTabId) + 1);
+                });
+            },
+            goBack:function(){
+                location.href = this.U({c:'store.StoreProduct',a:'index'});
+            },
+            U: function (opt) {
+                var m = opt.m || 'admin', c = opt.c || window.controlle || '', a = opt.a || 'index', q = opt.q || '',
+                    p = opt.p || {};
+                var params = Object.keys(p).map(function (key) {
+                    return key + '/' + p[key];
+                }).join('/');
+                var gets = Object.keys(q).map(function (key) {
+                    return key+'='+ q[key];
+                }).join('&');
+
+                return '/' + m + '/' + c + '/' + a + (params == '' ? '' : '/' + params) + (gets == '' ? '' : '?' + gets);
+            },
+            /**
+             * 提示
+             * */
+            showMsg: function (msg, success) {
+                $('#submit').removeAttr('disabled').text('提交');
+                layui.use(['layer'], function () {
+                    layui.layer.msg(msg, success);
+                });
+            },
+            addBrokerage:function(){
+                if (this.brokerage.brokerage >= 0 && this.brokerage.brokerage_two >= 0){
+                    var that = this;
+                    this.$set(this.formData,'attrs',this.formData.attrs.map(function (item) {
+                        item.brokerage = that.brokerage.brokerage;
+                        item.brokerage_two = that.brokerage.brokerage_two;
+                        return item;
+                    }));
+                } else {
+                    return this.showMsg('请填写返佣金额在进行批量添加');
+                }
+            },
+            batchClear:function(){
+                this.$set(this,'batchAttr',{
+                    pic: '',
+                    price: 0,
+                    cost: 0,
+                    ot_price: 0,
+                    stock: 0,
+                    bar_code: '',
+                    weight: 0,
+                    volume: 0,
+                });
+            },
+            /**
+             * 批量添加
+             * */
+            batchAdd:function(){
+                var that = this;
+                this.$set(this.formData,'attrs',this.formData.attrs.map(function (item) {
+                    if (that.batchAttr.pic) {
+                        item.pic = that.batchAttr.pic;
+                    }
+                    if (that.batchAttr.price > 0){
+                        item.price = that.batchAttr.price;
+                    }
+                    if (that.batchAttr.cost > 0){
+                        item.cost = that.batchAttr.cost;
+                    }
+                    if (that.batchAttr.ot_price > 0){
+                        item.ot_price = that.batchAttr.ot_price;
+                    }
+                    if (that.batchAttr.stock > 0){
+                        item.stock = that.batchAttr.stock;
+                    }
+                    if (that.batchAttr.bar_code != ''){
+                        item.bar_code = that.batchAttr.bar_code;
+                    }
+                    if (that.batchAttr.weight > 0){
+                        item.weight = that.batchAttr.weight;
+                    }
+                    if (that.batchAttr.volume > 0){
+                        item.volume = that.batchAttr.volume;
+                    }
+                    return item;
+                }));
+
+            },
+            /**
+             * 获取商品信息
+             * */
+            getProductInfo: function () {
+                var that = this;
+                that.requestGet(that.U({c:"ump.StoreWholesale",a:'get_product_info',q:{id:that.id}})).then(function (res) {
+                    that.$set(that,'cateList',res.data.cateList);
+                    that.$set(that,'tempList',res.data.time_id);
+                    var productInfo = res.data.productInfo || {};
+                    if(productInfo.id && that.id){
+                        that.$set(that,'formData',productInfo);
+                        that.generate();
+                    }
+                    that.getRuleList();
+                    that.init();
+                }).catch(function (res) {
+                    that.showMsg(res.msg);
+                })
+            },
+            /**
+             * 给某个属性添加属性值
+             * @param item
+             * */
+            addDetail: function (item) {
+                if (!item.detailValue) return false;
+                if (item.detail.find(function (val) {
+                    if(item.detailValue == val){
+                        return true;
+                    }
+                })) {
+                    return this.showMsg('添加的属性值重复');
+                }
+                item.detail.push(item.detailValue);
+                item.detailValue = '';
+            },
+            /**
+             * 删除某个属性值
+             * @param item 父级循环集合
+             * @param inx 子集index
+             * */
+            deleteValue: function (item, inx) {
+                if (item.detail.length > 1) {
+                    item.detail.splice(inx, 1);
+                } else {
+                    return this.showMsg('请设置至少一个属性');
+                }
+            },
+            /**
+             * 删除某条属性
+             * @param index
+             * */
+            deleteItem: function (index) {
+                this.formData.items.splice(index, 1);
+            },
+            /**
+             * 创建属性
+             * */
+            createAttrName: function () {
+                if (this.formDynamic.attrsName && this.formDynamic.attrsVal) {
+                    if (this.formData.items.find(function (val) {
+                        if (val.value == this.formDynamic.attrsName) {
+                            return true;
+                        }
+                    }.bind(this))) {
+                        return this.showMsg('添加的属性重复');
+                    }
+                    this.formData.items.push({
+                        value: this.formDynamic.attrsName,
+                        detailValue: '',
+                        attrHidden: false,
+                        detail: [this.formDynamic.attrsVal]
+                    });
+                    this.formDynamic.attrsName = '';
+                    this.formDynamic.attrsVal = '';
+                    this.newRule = false;
+                } else {
+                    return this.showMsg('请添加完整的规格!');
+                }
+            },
+            /**
+             * 删除图片
+             * */
+            deleteImage: function (key, index) {
+                var that = this;
+                if (index != undefined) {
+                    that.formData[key].splice(index, 1);
+                    that.$set(that.formData, key, that.formData[key]);
+                } else {
+                    that.$set(that.formData, key, '');
+                }
+            },
+            createFrame: function (title, src, opt) {
+                opt === undefined && (opt = {});
+                var h = 0;
+                if (window.innerHeight < 800 && window.innerHeight >= 700) {
+                    h = window.innerHeight - 50;
+                } else if (window.innerHeight < 900 && window.innerHeight >= 800) {
+                    h = window.innerHeight - 100;
+                } else if (window.innerHeight < 1000 && window.innerHeight >= 900) {
+                    h = window.innerHeight - 150;
+                } else if (window.innerHeight >= 1000) {
+                    h = window.innerHeight - 200;
+                } else {
+                    h = window.innerHeight;
+                }
+                var area = [(opt.w || window.innerWidth / 2) + 'px', (!opt.h || opt.h > h ? h : opt.h) + 'px'];
+                layui.use('layer',function () {
+                    return layer.open({
+                        type: 2,
+                        title: title,
+                        area: area,
+                        fixed: false, //不固定
+                        maxmin: true,
+                        moveOut: false,//true  可以拖出窗外  false 只能在窗内拖
+                        anim: 5,//出场动画 isOutAnim bool 关闭动画
+                        offset: 'auto',//['100px','100px'],//'auto',//初始位置  ['100px','100px'] t[ 上 左]
+                        shade: 0,//遮罩
+                        resize: true,//是否允许拉伸
+                        content: src,//内容
+                        move: '.layui-layer-title'
+                    });
+                });
+            },
+            changeIMG: function (name, value) {
+                if (this.getRule(name).maxLength !== undefined) {
+                    var that = this;
+                    value.map(function (v) {
+                        that.formData[name].push(v);
+                    });
+                    this.$set(this.formData, name, this.formData[name]);
+                } else {
+                    if(name == 'batchAttr.pic'){
+                        this.batchAttr.pic = value;
+                    } else {
+                        if (name.indexOf('.') !== -1) {
+                            var key = name.split('.');
+                            if (key.length == 2){
+                                this.formData[key[0]][key[1]] = value;
+                            } else if(key.length == 3){
+                                this.formData[key[0]][key[1]][key[2]] = value;
+                            } else if(key.length == 4){
+                                this.$set(this.formData[key[0]][key[1]][key[2]],key[3],value)
+                            }
+                        } else {
+                            this.formData[name] = value;
+                        }
+                    }
+                }
+            },
+            getRule: function (name) {
+                return this.rule[name] || {};
+            },
+            uploadImage: function (name) {
+                return this.createFrame('选择图片',this.U({c:"widget.images",a:'index',p:{fodder:name}}),{h:545,w:900});
+            },
+            uploadVideo: function () {
+                if (this.videoLink) {
+                    this.formData.video_link = this.videoLink;
+                } else {
+                    $(this.$refs.filElem).click();
+                }
+            },
+            delVideo: function () {
+                var that = this;
+                that.$set(that.formData, 'video_link', '');
+            },
+            insertEditor: function (list) {
+                this.um.execCommand('insertimage', list);
+            },
+            insertEditorVideo: function (src) {
+                this.um.setContent('<div><video style="width: 99%" src="'+src+'" class="video-ue" controls="controls" width="100"><source src="'+src+'"></source></video></div><br>',true);
+            },
+            getContent: function () {
+                return this.um.getContent();
+            },
+            /**
+             * 监听radio字段
+             */
+            eeventRadio: function () {
+                var that = this;
+                that.radioRule.map(function (val) {
+                    that.form.on('radio(' + val + ')', function (res) {
+                        that.formData[val] = res.value;
+                    });
+                })
+            },
+            init: function () {
+                var that = this;
+                window.UMEDITOR_CONFIG.toolbar = [
+                    // 加入一个 test
+                    'source | undo redo | bold italic underline strikethrough | superscript subscript | forecolor backcolor | removeformat |',
+                    'insertorderedlist insertunorderedlist | selectall cleardoc paragraph | fontfamily fontsize',
+                    '| justifyleft justifycenter justifyright justifyjustify |',
+                    'link unlink | emotion selectimgs video  | map',
+                    '| horizontal print preview fullscreen', 'drafts', 'formula'
+                ];
+                UM.registerUI('selectimgs', function (name) {
+                    var me = this;
+                    var $btn = $.eduibutton({
+                        icon: 'image',
+                        click: function () {
+                            that.createFrame('选择图片', "{:Url('widget.images/index',['fodder'=>'editor'])}");
+                        },
+                        title: '选择图片'
+                    });
+
+                    this.addListener('selectionchange', function () {
+                        //切换为不可编辑时,把自己变灰
+                        var state = this.queryCommandState(name);
+                        $btn.edui().disabled(state == -1).active(state == 1)
+                    });
+                    return $btn;
+
+                });
+                UM.registerUI('video', function (name) {
+                    var me = this;
+                    var $btn = $.eduibutton({
+                        icon: 'video',
+                        click: function () {
+                            that.createFrame('选择视频', "{:Url('widget.video/index',['fodder'=>'video'])}");
+                        },
+                        title: '选择视频'
+                    });
+
+                    this.addListener('selectionchange', function () {
+                        //切换为不可编辑时,把自己变灰
+                        var state = this.queryCommandState(name);
+                        $btn.edui().disabled(state == -1).active(state == 1)
+                    });
+                    return $btn;
+
+                });
+                //实例化编辑器
+                this.um = UM.getEditor('myEditor', {initialFrameWidth: '99%', initialFrameHeight: 400});
+                this.um.setContent(that.formData.description);
+                that.$nextTick(function () {
+                    layui.use(['form','element','laydate'], function () {
+                        that.form = layui.form;
+                        that.laydate = layui.laydate;
+                        that.form.render();
+                        that.form.on('select(temp_id)', function (data) {
+                            that.$set(that.formData, 'temp_id', data.value);
+                        });
+                        that.form.on('select(rule_index)', function (data) {
+                            that.ruleIndex = data.value;
+                        });
+                        layui.element.on('tab(docTabBrief)', function(){
+                            that.layTabId = this.getAttribute('lay-id');
+                        });
+                        that.laydate.render({
+                            elem: '#date'
+                            ,type: 'date'
+                            ,range: true,
+                            change:function (value, date, endDate) {
+                                that.formData.start_time = `${date.year}-${date.month}-${date.date}`;
+                                that.formData.stop_time = `${endDate.year}-${endDate.month}-${endDate.date}`;
+                            }
+                        });
+                        that.eeventRadio();
+                    });
+
+                    // layui.config({
+                    //     base : '/static/plug/layui/'
+                    // }).extend({
+                    //     selectN: './selectN',
+                    // }).use('selectM',function () {
+                    //     var selectM = layui.selectM;
+                    //     selectM({
+                    //         //元素容器【必填】
+                    //         elem: '#cate_id'
+                    //         //候选数据【必填】
+                    //         ,data: that.cateList
+                    //         //默认值
+                    //         ,selected: that.formData.cate_id || []
+                    //         //最多选中个数,默认5
+                    //         ,max : 10
+                    //         ,name: 'cate_id'
+                    //         ,model: 'formData.cate_id'
+                    //         //值的分隔符
+                    //         ,delimiter: ','
+                    //         //候选项数据的键名
+                    //         ,field: {idName:'value',titleName:'label',statusName:'disabled'}
+                    //     });
+                    // });
+                })
+            },
+            requestPost: function (url, data) {
+                return new Promise(function (resolve, reject) {
+                    axios.post(url, data).then(function (res) {
+                        if (res.status == 200 && res.data.code == 200) {
+                            resolve(res.data)
+                        } else {
+                            reject(res.data);
+                        }
+                    }).catch(function (err) {
+                        reject({msg:err})
+                    });
+                })
+            },
+            requestGet: function (url) {
+                return new Promise(function (resolve, reject) {
+                    axios.get(url).then(function (res) {
+                        if (res.status == 200 && res.data.code == 200) {
+                            resolve(res.data)
+                        } else {
+                            reject(res.data);
+                        }
+                    }).catch(function (err) {
+                        reject({msg:err})
+                    });
+                })
+            },
+            generates: function () {
+                var that = this;
+                that.generate(1);
+            },
+            generate: function (type = 0) {
+                var that = this;
+                this.requestPost(that.U({c:"store.StoreProduct",a:'is_format_attr',p:{id:that.id,type:type}}), {attrs:this.formData.items}).then(function (res) {
+                    that.$set(that.formData, 'attrs', res.data.value);
+                    that.$set(that, 'formHeader', res.data.header);
+                    if (that.id && that.formData.is_sub == 1 && that.formData.spec_type == 1) {
+                        that.formHeader.push({title:'一级返佣(元)'});
+                        that.formHeader.push({title:'二级级返佣(元)'});
+                    }
+                }).catch(function (res) {
+                    return that.showMsg(res.msg);
+                });
+            },
+            handleSubmit:function () {
+                var that = this, cate_id = $('input[name="cate_id"]').val();
+                // if (cate_id != '') {
+                //     this.formData.cate_id = cate_id.split(',');
+                // }
+                // if (!that.formData.cate_id.length) {
+                //     return that.showMsg('请选择商品分类');
+                // }
+                // if (!that.formData.temp_id) {
+                //     return that.showMsg('请选择运费模板');
+                // }
+                if (!that.formData.title) {
+                    return that.showMsg('请填写商品名称');
+                }
+                if (!that.formData.image) {
+                    return that.showMsg('请填选择商品图');
+                }
+                if (!that.formData.images.length) {
+                    return that.showMsg('请填选择商品轮播图');
+                }
+                that.formData.description = that.getContent();
+                $('#submit').attr('disabled', 'disabled').text('保存中...');
+                that.requestPost(that.U({c:'ump.StoreWholesale',a:'save',p:{id:that.id}}),that.formData).then(function (res) {
+                    that.confirm();
+                }).catch(function (res) {
+                    that.showMsg(res.msg);
+                });
+            },
+            confirm: function(){
+                var that = this;
+                layui.use(['layer'], function () {
+                    var layer = layui.layer;
+                    layer.confirm(that.id ? '修改成功是否返回产品列表' : '添加成功是否返回产品列表', {
+                        btn: ['返回列表',that.id ? '继续修改' : '继续添加'] //按钮
+                    }, function(){
+                        location.href = that.U({c:'ump.StoreWholesale',a:'index'});
+                    }, function(){
+                        location.reload();
+                    });
+                });
+            },
+            render:function(){
+                this.$nextTick(function(){
+                    layui.use(['form'], function () {
+                        layui.form.render('select');
+                    });
+                })
+            },
+            // 移动
+            handleDragStart (e, item) {
+                this.dragging = item;
+            },
+            handleDragEnd (e, item) {
+                this.dragging = null
+            },
+            handleDragOver (e) {
+                e.dataTransfer.dropEffect = 'move'
+            },
+            handleDragEnter (e, item) {
+                e.dataTransfer.effectAllowed = 'move'
+                if (item === this.dragging) {
+                    return
+                }
+                var newItems = [...this.formData.activity];
+                var src = newItems.indexOf(this.dragging);
+                var dst = newItems.indexOf(item);
+                newItems.splice(dst, 0, ...newItems.splice(src, 1))
+                this.formData.activity = newItems;
+            },
+            getRuleList:function (type) {
+                var that = this;
+                that.requestGet(that.U({c:'store.StoreProduct',a:'get_rule'})).then(function (res) {
+                    that.$set(that,'ruleList',res.data);
+                    if(type !== undefined){
+                        that.render();
+                    }
+                });
+            },
+            addRule:function(){
+                return this.createFrame('添加商品规则',this.U({c:'store.StoreProductRule',a:'create'}));
+            },
+            allRule:function () {
+                if (this.ruleIndex != -1) {
+                    var rule = this.ruleList[this.ruleIndex];
+                    if (rule) {
+                        this.ruleBool = true;
+                        var rule_value = rule.rule_value.map(function (item) {
+                            return item;
+                        });
+                        this.$set(this.formData,'items',rule_value);
+                        this.$set(this.formData,'attrs',[]);
+                        this.$set(this,'formHeader',[]);
+                        return true;
+                    }
+                }
+                this.showMsg('选择的属性无效');
+            }
+        },
+        mounted: function () {
+            var that = this;
+            axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
+            that.getProductInfo();
+            window.$vm = that;
+            window.changeIMG = that.changeIMG;
+            window.insertEditor = that.insertEditor;
+            window.insertEditorVideo = that.insertEditorVideo;
+            window.successFun = function(){
+                that.getRuleList(1);
+            }
+            $(that.$refs.filElem).change(function () {
+                var inputFile = this.files[0];
+                that.requestPost(that.U({c:"widget.video",a:'get_signature'})).then(function (res) {
+                    AdminUpload.upload(res.data.uploadType,{
+                        token: res.data.uploadToken || '',
+                        file: inputFile,
+                        accessKeyId: res.data.accessKey || '',
+                        accessKeySecret: res.data.secretKey || '',
+                        bucketName: res.data.storageName || '',
+                        region: res.data.storageRegion || '',
+                        domain: res.data.domain || '',
+                        uploadIng:function (progress) {
+                            that.upload.videoIng = true;
+                            that.progress = progress;
+                        }
+                    }).then(function (res) {
+                        //成功
+                        that.$set(that.formData, 'video_link', res.url);
+                        that.progress = 0;
+                        that.upload.videoIng = false;
+                        return that.showMsg('上传成功');
+                    }).catch(function (err) {
+                        //失败
+                        console.info(err);
+                        return that.showMsg('上传错误请检查您的配置');
+                    });
+                }).catch(function (res) {
+                    return that.showMsg(res.msg || '获取密钥失败,请检查您的配置');
+                });
+            })
+
+
+        }
+    });
+</script>
+</body>
+</html>
+<script>
+    // import Layout from "../../../../../public/static/plug/iview/dist/iview";
+    // export default {
+    //     components: {Layout}
+    // }
+</script>

+ 243 - 0
app/admin/view/ump/store_wholesale/index.php

@@ -0,0 +1,243 @@
+{extend name="public/container"}
+{block name="head_top"}
+<script type="text/javascript" src="{__PLUG_PATH}jquery.downCount.js"></script>
+{/block}
+{block name="content"}
+<div class="layui-fluid">
+    <div class="layui-row layui-col-space15"  id="app">
+        <div class="layui-col-md12">
+            <div class="layui-card">
+                <div class="layui-card-header">批发商品搜索</div>
+                <div class="layui-card-body">
+                    <div class="alert alert-success alert-dismissable">
+                        <button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button>
+                        目前拥有{$countSeckill}个秒杀商品
+                    </div>
+                    <form class="layui-form">
+                        <div class="layui-form-item">
+                            <div class="layui-inline">
+                                <label class="layui-form-label">搜  索:</label>
+                                <div class="layui-input-inline">
+                                    <input type="text" name="store_name" lay-verify="store_name" style="width: 100%" autocomplete="off" placeholder="请输入商品名称,关键字,编号" class="layui-input">
+                                </div>
+                            </div>
+                            <div class="layui-inline">
+                                <label class="layui-form-label">批发状态:</label>
+                                <div class="layui-input-inline">
+                                    <select name="status" lay-verify="status">
+                                        <option value="">全部</option>
+                                        <option value="1">开启</option>
+                                        <option value="0">关闭</option>
+                                    </select>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="layui-form-item">
+                            <label class="layui-form-label">
+                                <button class="layui-btn layui-btn-sm" lay-submit="" lay-filter="search" style="font-size:14px;line-height: 9px;">
+                                    <i class="layui-icon layui-icon-search layuiadmin-button-btn"></i>搜索</button>
+                                <button lay-submit="export" lay-filter="export" class="layui-btn layui-btn-primary layui-btn-sm">
+                                    <i class="layui-icon layui-icon-delete layuiadmin-button-btn" ></i> Excel导出</button>
+                            </label>
+                        </div>
+                    </form>
+                </div>
+            </div>
+        </div>
+        <div class="layui-col-md12">
+            <div class="layui-card">
+                <div class="layui-card-header">秒杀商品列表</div>
+                <div class="layui-card-body">
+                    <div class="layui-btn-container">
+                        <a class="layui-btn layui-btn-sm" href="{:Url('create')}">添加商品</a>
+                    </div>
+                    <table class="layui-hide" id="seckillList" lay-filter="seckillList"></table>
+                    <script type="text/html" id="status">
+                        <input type='checkbox' name='status' lay-skin='switch' value="{{d.id}}" lay-filter='status' lay-text='开启|关闭'  {{ d.status == 1 ? 'checked' : '' }}>
+                    </script>
+                    <script type="text/html" id="stopTime">
+                        <div class="count-time-{{d.id}}" data-time="{{d._stop_time}}">
+                            <span class="days">00</span>
+                            :
+                            <span class="hours">00</span>
+                            :
+                            <span class="minutes">00</span>
+                            :
+                            <span class="seconds">00</span>
+                        </div>
+                    </script>
+                    <script type="text/html" id="statusCn">
+                        {{ d.status == 1 ? d.start_name : '关闭' }}
+                    </script>
+                    <script type="text/html" id="barDemo">
+                        <button type="button" class="layui-btn layui-btn-xs" onclick="dropdown(this)">操作<span class="caret"></span></button>
+                        <ul class="layui-nav-child layui-anim layui-anim-upbit">
+                            <li>
+                                <a href="javascript:void(0);" onclick="$eb.createModalFrame('{{d.title}}-编辑','{:Url('edit')}?id={{d.id}}')"><i class="layui-icon layui-icon-edit"></i> 编辑活动</a>
+                            </li>
+                            <li>
+                                <a href="javascript:void(0);" class="delstor" lay-event='delstor'><i class="layui-icon layui-icon-delete"></i> 删除</a>
+                            </li>
+                        </ul>
+                    </script>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+{/block}
+{block name="script"}
+<script src="{__ADMIN_PATH}js/layuiList.js"></script>
+<script src="{__FRAME_PATH}js/content.min.js?v=1.0.0"></script>
+<script>
+    setTime();
+    function setTime() {
+        setTimeout(function () {
+            $eb.axios.get("{:Url('get_seckill_id')}").then(function(res){
+                $.each(res.data.count,function (index,item) {
+                    var time = $('.count-time-'+item).attr('data-time');
+                    if(time != ''){
+                        $('.count-time-'+item).downCount({
+                            date: time,
+                            offset: +8
+                        });
+                    }
+                })
+            }).catch(function(err){
+                console.log(err);
+            });
+        },2000);
+    }
+</script>
+<script>
+    layList.form.render();
+    layList.tableList('seckillList',"{:Url('getlist')}",function () {
+        return [
+            {field: 'id', title: 'ID', sort: true,width:'6%',event:'id'},
+            {field: 'image', title: '商品图片', width: '10%',templet: '<p><img src="{{d.image}}" alt="{{d.title}}" class="open_image" data-image="{{d.image}}"></p>'},
+            {field: 'title', title: '活动标题'},
+            {field: 'info', title: '活动简介',width:'20%'},
+            {field: 'ot_price', title: '原价',width:'6%'},
+            {field: 'price', title: '批发价',width:'6%'},
+            {field: 'start_name', title: '秒杀状态',width:'6%',toolbar:"#statusCn"},
+            {field: 'stop_time', title: '结束时间', width: '8%',toolbar: '#stopTime'},
+            {field: 'status', title: '状态',width:'6%',toolbar:"#status"},
+            {field: 'right', title: '操作',width:'10%', align: 'center', toolbar: '#barDemo'}
+        ]
+    });
+    layList.tool(function (event,data,obj) {
+        switch (event) {
+            case 'delstor':
+                var url=layList.U({c:'ump.store_seckill',a:'delete',q:{id:data.id}});
+                $eb.$swal('delete',function(){
+                    $eb.axios.get(url).then(function(res){
+                        if(res.status == 200 && res.data.code == 200) {
+                            $eb.$swal('success',res.data.msg);
+                            obj.del();
+                        }else
+                            return Promise.reject(res.data.msg || '删除失败')
+                    }).catch(function(err){
+                        $eb.$swal('error',err);
+                    });
+                })
+                break;
+        }
+    })
+    $(document).click(function (e) {
+        $('.layui-nav-child').hide();
+    })
+    function dropdown(that){
+        var oEvent = arguments.callee.caller.arguments[0] || event;
+        oEvent.stopPropagation();
+        var offset = $(that).offset();
+        var top=offset.top-$(window).scrollTop();
+        var index = $(that).parents('tr').data('index');
+        $('.layui-nav-child').each(function (key) {
+            if (key != index) {
+                $(this).hide();
+            }
+        })
+        if($(document).height() < top+$(that).next('ul').height()){
+            $(that).next('ul').css({
+                'padding': 10,
+                'top': - ($(that).parent('td').height() / 2 + $(that).height() + $(that).next('ul').height()/2),
+                'min-width': 'inherit',
+                'position': 'absolute'
+            }).toggle();
+        }else{
+            $(that).next('ul').css({
+                'padding': 10,
+                'top':$(that).parent('td').height() / 2 + $(that).height(),
+                'min-width': 'inherit',
+                'position': 'absolute'
+            }).toggle();
+        }
+    }
+    layList.search('search',function(where){
+        layList.reload(where);
+        setTime();
+    });
+    layList.search('export',function(where){
+        location.href=layList.U({c:'ump.store_seckill',a:'save_excel',q:{status:where.status,store_name:where.store_name}});
+    })
+    layList.switch('status',function (odj,value,name) {
+        if (odj.elem.checked == true) {
+            layList.baseGet(layList.Url({
+                c: 'ump.store_seckill',
+                a: 'set_seckill_status',
+                p: {status: 1, id: value}
+            }), function (res) {
+                layList.msg(res.msg);
+            }, function () {
+                odj.elem.checked = false;
+                layui.form.render();
+                layer.open({
+                    type: 1
+                    ,offset: 'auto'
+                    ,id: 'layerDemoauto' //防止重复弹出
+                    ,content: '<div style="padding: 20px 100px;">请先配置规格</div>'
+                    ,btn: '设置规格'
+                    ,btnAlign: 'c' //按钮居中
+                    ,shade: 0 //不显示遮罩
+                    ,yes: function(){
+                        layer.closeAll();
+                        $eb.createModalFrame('设置规格','{:Url('attr_list')}?id='+value+'',{h:1000,w:1400});
+                    }
+                });
+            });
+        } else {
+            layList.baseGet(layList.Url({
+                c: 'ump.store_seckill',
+                a: 'set_seckill_status',
+                p: {status: 0, id: value}
+            }), function (res) {
+                layList.msg(res.msg);
+            });
+        }
+    })
+    $('.js-group-btn').on('click',function(){
+        $('.js-group-btn').css({zIndex:1});
+        $(this).css({zIndex:2});
+    });
+    $('#delstor').on('click',function(){
+        window.t = $(this);
+        var _this = $(this),url =_this.data('url');
+        $eb.$swal('delete',function(){
+            $eb.axios.get(url).then(function(res){
+                console.log(res);
+                if(res.status == 200 && res.data.code == 200) {
+                    $eb.$swal('success',res.data.msg);
+                    _this.parents('tr').remove();
+                }else
+                    return Promise.reject(res.data.msg || '删除失败')
+            }).catch(function(err){
+                $eb.$swal('error',err);
+            });
+        })
+    });
+    $(document).on('click',".open_image",function (e) {
+        var image = $(this).data('image');
+        $eb.openImage(image);
+    });
+</script>
+{/block}

+ 152 - 0
app/api/controller/activity/WholeController.php

@@ -0,0 +1,152 @@
+<?php
+namespace app\api\controller\activity;
+use app\models\store\Package;
+use app\models\store\StoreWholesale;
+use app\Request;
+use crmeb\services\QrcodeService;
+use crmeb\services\UtilService;
+
+class WholeController
+{
+    /**
+     * 秒杀产品时间区间
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public function index()
+    {
+
+        //秒杀时间段
+        $seckillTime = sys_data('whole_time') ?? [];
+        $seckillTimeIndex = 0;
+        if (count($seckillTime)) {
+            foreach ($seckillTime as $key => &$value) {
+                $currentHour = date('H');
+                $activityEndHour = bcadd((int)$value['time'], (int)$value['continued'], 0);
+                if ($activityEndHour > 24) {
+                    $value['time'] = strlen((int)$value['time']) == 2 ? (int)$value['time'] . ':00' : '0' . (int)$value['time'] . ':00';
+                    $value['state'] = '即将开始';
+                    $value['status'] = 2;
+                    $value['stop'] = (int)bcadd(strtotime(date('Y-m-d')), bcmul($activityEndHour, 3600, 0));
+                } else {
+                    if ($currentHour >= (int)$value['time'] && $currentHour < $activityEndHour) {
+                        $value['time'] = strlen((int)$value['time']) == 2 ? (int)$value['time'] . ':00' : '0' . (int)$value['time'] . ':00';
+                        $value['state'] = '抢购中';
+                        $value['stop'] = (int)bcadd(strtotime(date('Y-m-d')), bcmul($activityEndHour, 3600, 0));
+                        $value['status'] = 1;
+                        if (!$seckillTimeIndex) $seckillTimeIndex = $key;
+                    } else if ($currentHour < (int)$value['time']) {
+                        $value['time'] = strlen((int)$value['time']) == 2 ? (int)$value['time'] . ':00' : '0' . (int)$value['time'] . ':00';
+                        $value['state'] = '即将开始';
+                        $value['status'] = 2;
+                        $value['stop'] = (int)bcadd(strtotime(date('Y-m-d')), bcmul($activityEndHour, 3600, 0));
+                    } else if ($currentHour >= $activityEndHour) {
+                        $value['time'] = strlen((int)$value['time']) == 2 ? (int)$value['time'] . ':00' : '0' . (int)$value['time'] . ':00';
+                        $value['state'] = '已结束';
+                        $value['status'] = 0;
+                        $value['stop'] = (int)bcadd(strtotime(date('Y-m-d')), bcmul($activityEndHour, 3600, 0));
+                    }
+                }
+            }
+        }
+        $data['lovely'] = sys_config('seckill_header_banner');
+        if (strstr($data['lovely'], 'http') === false && strlen(trim($data['lovely']))) $data['lovely'] = sys_config('site_url') . $data['lovely'];
+        $data['lovely'] = str_replace('\\', '/', $data['lovely']);
+        $data['seckillTime'] = $seckillTime;
+        $data['seckillTimeIndex'] = $seckillTimeIndex;
+        $data['seckillCont'] = StoreWholesale::getWholeContStatus();
+        return app('json')->successful($data);
+    }
+
+    /**
+     * 秒杀产品列表
+     * @param Request $request
+     * @param $time
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public function lst(Request $request, $time)
+    {
+        list($page, $limit) = UtilService::getMore([
+            ['page', 0],
+            ['limit', 0],
+        ], $request, true);
+        if (!$time) return app('json')->fail('参数错误');
+        $seckillInfo = StoreWholesale::WholeList($time, $page, $limit);
+        if (count($seckillInfo)) {
+            foreach ($seckillInfo as $key => &$item) {
+
+            }
+        }
+        return app('json')->successful($seckillInfo);
+    }
+
+    /**
+     * 秒杀产品详情
+     * @param Request $request
+     * @param $id
+     * @return mixed
+     */
+    public function detail(Request $request, $id, $time = 0, $status = 1)
+    {
+        $storeInfo = StoreWholesale::getValidProduct($id);
+        if ($storeInfo)
+            $storeInfo = $storeInfo->hidden(['cost', 'add_time', 'is_del'])->toArray();
+        else
+            $storeInfo = [];
+        if (!$id || !$storeInfo) return app('json')->fail('商品不存在或已下架!');
+
+        $siteUrl = sys_config('site_url');
+        $storeInfo['image'] = set_file_url($storeInfo['image'], $siteUrl);
+        $storeInfo['image_base'] = set_file_url($storeInfo['image'], $siteUrl);
+        $storeInfo['code_base'] = QrcodeService::getWechatQrcodePath($id . '_seckill_detail_wap.jpg', '/activity/seckill_detail/' . $id . '/' . $time . '/' .$status);
+        $uid = $request->uid();
+        $storeInfo['uid'] = $uid;
+        $data['storeInfo'] = $storeInfo;
+        $user = $request->user();
+        $data['isSeckillEnd'] = StoreWholesale::checkStatus($id);
+        return app('json')->successful($data);
+    }
+    /**
+     * 预约
+     * @param Request $request
+     */
+    public function reserve(Request $request)
+    {
+        list($package_manager,$price,$day,$proportion,$pass) = UtilService::postMore(
+            [
+                ['package_manager',0],
+                ['price',0],
+                ['day',0],
+                ['proportion',0],
+                ['pass',0]
+            ],$request,true
+        );
+        if($package_manager==0) return app('json')->fail('包编号错误');
+        if($price==0) return app('json')->fail('价值不能为空');
+        if($day==0) return app('json')->fail('收益天数错误');
+        if($proportion==0) return app('json')->fail('收益比例不能为空');
+        $rs = Package::reserve($request->uid(),$package_manager,$price,$day,$proportion,$pass);
+        if($rs)
+        {
+            return app('json')->successful($rs);
+        }
+        else
+        {
+            return app('json')->fail(Package::getErrorInfo());
+        }
+    }
+
+    /**
+     * 新人批发
+     * @param Request $request
+     */
+    public function news(Request $request)
+    {
+        return app('json')->successful(StoreWholesale::where('is_news',1)->where('is_del',0)->where('is_show',1)->select()->toArray());
+    }
+}

+ 377 - 0
app/models/order/Level.php

@@ -0,0 +1,377 @@
+<?php
+namespace app\models\order;
+use app\models\system\SystemStoreMember;
+use app\models\system\SystemUserLevel;
+use app\models\user\User;
+use app\models\user\UserLevel;
+use app\models\user\WechatUser;
+use crmeb\basic\BaseModel;
+use crmeb\services\AlipayService;
+use crmeb\services\MiniProgramService;
+use crmeb\services\SystemConfigService;
+use crmeb\services\WechatService;
+use crmeb\repositories\PaymentRepositories;
+use crmeb\traits\ModelTrait;
+use app\models\user\UserBill;
+use think\facade\Log;
+
+class Level extends BaseModel
+{
+    use ModelTrait;
+    /**
+     * 数据表主键
+     * @var string
+     */
+    protected $pk = 'id';
+
+    /**
+     * 模型名称
+     * @var string
+     */
+    protected $name = 'order_level';
+    protected $insert = ['addtime'];
+    protected static $payType = ['weixin' => '微信支付', 'yue' => '余额支付', 'ali' => '支付宝支付'];
+
+    /**
+     * 生成订单唯一id
+     * @param $uid 用户uid
+     * @return string
+     */
+    public static function getNewOrderId()
+    {
+        list($msec, $sec) = explode(' ', microtime());
+        $msectime = number_format((floatval($msec) + floatval($sec)) * 1000, 0, '', '');
+        $orderId = 'lv' . $msectime . mt_rand(10000, 99999);
+        while (self::be(['order_id' => $orderId])) $orderId = 'lv' . $msectime . mt_rand(10000, 99999);
+        return $orderId;
+    }
+
+    /**
+     * 创建订单
+     * @param $uid
+     * @param $level_id
+     * @param $payType
+     * @param $mark
+     * @return Level|bool|\think\Model
+     */
+    public static function createLevelOrder($uid, $level_id, $payType,$spread_uid=0,$store_id=0)
+    {
+        Level::where('uid',$uid)->where('paid',0)->delete();
+        self::beginTrans();
+        try {
+            if (!array_key_exists($payType, self::$payType)) return self::setErrorInfo('选择支付方式有误!', true);
+            $userInfo = User::getUserInfo($uid);
+            if (!$userInfo) return self::setErrorInfo('用户不存在!', true);
+            $levelInfo = SystemUserLevel::get(['id' => $level_id, 'is_del' => 0]);
+            if (!$levelInfo) return self::setErrorInfo('等级不存在', true);
+            list($where['uid'],$where['level_id'],$where['pay_type'],$where['paid']) = [$uid,$level_id,$payType,0];
+            $info = self::where($where)->find();
+            if($info)
+            {
+                $order_id = self::getNewOrderId();
+                self::edit(['pay_price'=>$levelInfo->money,'order_id'=>$order_id],$info['id']);
+                $info['pay_price'] = $levelInfo->money;
+                $info['order_id'] = $order_id;
+                return $info;
+            }
+            $orderInfo = [
+                'uid' => $uid,
+                'order_id' => self::getNewOrderId(),
+                'level_id' => $level_id,
+                'paid' => 0,
+                'is_del' => 0,
+                'pay_price' => $levelInfo->money,
+                'pay_type' => $payType,
+                'body'     => '开通会员-'.$levelInfo->name,
+                'addtime'  => time(),
+                'spread_uid'=>$spread_uid,
+                'store_id'=>$store_id,
+            ];
+
+            $order = self::create($orderInfo);
+            if (!$order) return self::setErrorInfo('订单生成失败!');
+            self::commitTrans();
+            return $order;
+        } catch (\PDOException $e) {
+            self::rollbackTrans();
+            return self::setErrorInfo('生成订单时SQL执行错误错误原因:' . $e->getMessage());
+        } catch (\Exception $e) {
+            self::rollbackTrans();
+            return self::setErrorInfo('生成订单时系统错误错误原因:' . $e->getMessage());
+        }
+    }
+    public static function paySuccess($orderId, $paytype = 'weixin')
+    {
+        $order = self::where('order_id', $orderId)->find()->toArray();
+        $user = User::where('uid', $order['uid'])->find();
+        if (!$user) return false;
+        $res1 = self::where('order_id', $orderId)->update(['paid' => 1, 'pay_type' => $paytype, 'paytime' => time()]);//订单改为支付
+
+        //送等值金豆
+        User::where('uid',$user['uid'])->inc('integral',$order['pay_price'])->update();
+        UserBill::income('黄金会员送金豆',$order['uid'],'integral','level',$order['pay_price'],$order['id'],bcadd($user['integral'],$order['pay_price'],2),'黄金会员送金豆'.$order['pay_price']);
+
+        if($user['level']<2)
+            $res2 = UserLevel::setUserLevel($order['uid'], $order['level_id']);
+        else
+            $res2= true;
+        $res = $res1 && $res2 ;
+        //User::setSpreadLevel($order['spread_uid'],$order['uid']);
+        return false !== $res;
+    }
+    /**
+     * TODO 小程序JS支付
+     * @param $orderId
+     * @param string $field
+     * @return array|string
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public static function jsPay($orderId, $field = 'order_id')
+    {
+        if (is_string($orderId))
+            $orderInfo = self::where($field, $orderId)->find();
+        else
+            $orderInfo = $orderId;
+        if (!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!');
+        if ($orderInfo['paid']) exception('支付已支付!');
+        if ($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
+        $openid = WechatUser::getOpenId($orderInfo['uid']);
+        return MiniProgramService::jsPay($openid, $orderInfo['order_id'], $orderInfo['pay_price'], 'user_level','会员升级');
+    }
+    /**
+     * 微信app支付
+     * @param $orderId
+     * @param string $field
+     * @return array|string
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public static function appPay($order,$field = 'order_id')
+    {
+        if(is_string($order))
+            $orderInfo = self::where($field,$order)->find();
+        else
+            $orderInfo = $order;
+        if(!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!');
+        if($orderInfo['paid']) exception('支付已支付!');
+        //if($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
+        if($orderInfo['pay_price']==0) self::jsPayPrice($order,$orderInfo['uid']);
+        $openid = WechatUser::uidToOpenid($orderInfo['uid'],'openid');
+        $wechat = SystemConfigService::more(['weixin_open_appid', 'weixin_open_appsecret']);
+        $payment = SystemConfigService::more(['pay_weixin_mchid', 'pay_weixin_client_cert', 'pay_weixin_client_key', 'pay_weixin_key', 'pay_weixin_open']);
+
+        $config = array(
+            'appid' => $wechat['weixin_open_appid'],			//填写高级调用功能的app id
+            'appsecret' => $wechat['weixin_open_appsecret'], 		//填写高级调用功能的app secret
+            'mchid' => $payment['pay_weixin_mchid'],			//商户id
+            'key' => $payment['pay_weixin_key'], 			//填写你设定的key
+            'sslcert_path' => $payment['pay_weixin_client_cert'],
+            'sslkey_path' => $payment['pay_weixin_client_key'],
+            'transfer_rsa_public_path' => '',	//企业转账到银行卡rsa公钥证书文件路径
+        );
+        $wechatpay = new \JiaLeo\Payment\Wechatpay\AppPay($config);
+        $pay_data = [
+            'body' =>self::getSubstrUTf8('充值VIP',30), //内容
+            'attach' =>'user_level', //商家数据包
+            'out_trade_no' => $orderInfo['order_id'], //商户订单号
+            'total_fee' =>bcmul($orderInfo['pay_price'],100,0), //支付价格(单位:分)
+            'notify_url' => sysConfig('site_url') . '/api/wechat/notify', //后台回调地址
+        ];
+
+        $url = $wechatpay->handle($pay_data);
+        return $url;
+    }
+    public static function alipay($orderId, $field = 'order_id')
+    {
+        if (is_string($orderId))
+            $orderInfo = self::where($field, $orderId)->find();
+        else
+            $orderInfo = $orderId;
+        if ($orderInfo['paid']) exception('支付已支付!');
+        if ($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
+        $alipay = SystemConfigService::more(['alipay_app_id', 'alipay_pub_key','alipay_private_key','alipay_key']);
+        $notifyUrl = sys_config('site_url') . '/api/alipay/notify';
+        $aliPay = new AlipayService();
+        $aliPay->setAppid($alipay['alipay_app_id']);
+        $aliPay->setNotifyUrl($notifyUrl);
+        $aliPay->setRsaPrivateKey($alipay['alipay_private_key']);
+        $aliPay->setTotalFee($orderInfo['pay_price']);
+        $aliPay->setOutTradeNo($orderInfo['order_id']);
+        $aliPay->setOrderName('支付会员');
+        $aliPay->setPassbackParams(['attach' =>'user_level']);
+        $orderStr = $aliPay->getOrderStr();
+        return $orderStr;
+    }
+
+    /**
+     * 微信公众号JS支付
+     * @param $orderId
+     * @param string $field
+     * @return array|string
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public static function wxPay($orderId, $field = 'order_id')
+    {
+        if (is_string($orderId))
+            $orderInfo = self::where($field, $orderId)->find();
+        else
+            $orderInfo = $orderId;
+        if (!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!');
+        if ($orderInfo['paid']) exception('支付已支付!');
+        if ($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
+        $openid = WechatUser::uidToOpenid($orderInfo['uid'], 'openid');
+        return WechatService::jsPay($openid, $orderInfo['order_id'], $orderInfo['pay_price'], 'user_level','会员升级');
+    }
+
+    /**
+     * 微信h5支付
+     * @param $orderId
+     * @param string $field
+     * @return array|string
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public static function h5Pay($orderId, $field = 'order_id')
+    {
+        if (is_string($orderId))
+            $orderInfo = self::where($field, $orderId)->find();
+        else
+            $orderInfo = $orderId;
+        if (!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!');
+        if ($orderInfo['paid']) exception('支付已支付!');
+        if ($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
+        return WechatService::paymentPrepare(null, $orderInfo['order_id'], $orderInfo['pay_price'], 'user_level','会员升级' , '', 'MWEB');
+    }
+
+
+    /**
+     * 余额支付
+     * @param $order_id
+     * @param $uid
+     * @param string $formId
+     * @return bool
+     * @throws \think\Exception
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public static function yuePay($order_id, $uid, $formId = '')
+    {
+        $orderInfo = self::where('uid', $uid)->where('order_id', $order_id)->find();
+        if (!$orderInfo) return self::setErrorInfo('订单不存在!');
+        if ($orderInfo['paid']) return self::setErrorInfo('该订单已支付!');
+        $userInfo = User::getUserInfo($uid);
+        if ($userInfo['now_money'] < $orderInfo['pay_price'])
+            return self::setErrorInfo(['status' => 'pay_deficiency', 'msg' => '余额不足' . floatval($orderInfo['pay_price'])]);
+        self::beginTrans();
+        $res1 = false !== User::bcDec($uid, 'now_money', $orderInfo['pay_price'], 'uid');
+        $res2 = UserBill::expend('会员升级', $uid, 'now_money', 'pay_product', $orderInfo['pay_price'], $orderInfo['id'], $userInfo['now_money'], '余额支付' . floatval($orderInfo['pay_price']) . '元升级' . SystemUserLevel::where(['id' => $orderInfo['level_id']])->value('name'));
+
+        $res3 = self::paySuccess($order_id, 'yue');//余额支付成功
+        try {
+            PaymentRepositories::yuePayProduct($userInfo, $orderInfo);
+        } catch (\Exception $e) {
+            self::rollbackTrans();
+            return self::setErrorInfo($e->getMessage());
+        }
+        $res = $res1 && $res2 && $res3;
+        self::checkTrans($res);
+        return $res;
+    }
+
+    public static function jsPayPrice($order_id, $uid, $formId = '')
+    {
+        $orderInfo = self::where('uid', $uid)->where('order_id', $order_id)->where('is_del', 0)->find();
+        if (!$orderInfo) return self::setErrorInfo('订单不存在!');
+        if ($orderInfo['paid']) return self::setErrorInfo('该订单已支付!');
+        $userInfo = User::getUserInfo($uid);
+        self::beginTrans();
+        $res1 = UserBill::expend('会员升级', $uid, 'now_money', 'pay_product', $orderInfo['pay_price'], $orderInfo['id'], $userInfo['now_money'], '微信支付' . floatval($orderInfo['pay_price']) . '元升级' . SystemUserLevel::where(['id' => $orderInfo['level_id']])->value('name'));
+        $res2 = self::paySuccess($order_id, 'weixin', $formId);//微信支付为0时
+        $res = $res1 && $res2;
+        self::checkTrans($res);
+        return $res;
+    }
+    /**
+     * TODO 一级返佣
+     * @param $orderInfo
+     * @return bool
+     * @throws \think\Exception
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public static function backBrokerage($levelInfo, bool $open = true)
+    {
+
+        $userInfo = User::getUserInfo($levelInfo['uid']);
+        //TODO 当前用户不存在 没有上级 或者 当用用户上级时自己  直接返回
+        if (!$userInfo || !$userInfo['spread_uid'] || $userInfo['spread_uid'] == $levelInfo['uid']) return true;
+        $sp_user = User::where('uid',$levelInfo['spread_uid'])->find();
+        $spread_consumer = sys_config('spread_consumer');
+        User::where('uid',$levelInfo['spread_uid'])->inc('consumer',$spread_consumer)->update();
+        UserBill::income('推荐会员赠送消费券',$levelInfo['spread_uid'],'consumer','spread_add',$spread_consumer,$levelInfo['id'],bcadd($sp_user['consumer'],$spread_consumer,2),"推荐会员赠送消费券".$spread_consumer);
+        return true;
+    }
+
+    /**
+     * TODO 二级推广
+     * @param $orderInfo
+     * @return bool
+     * @throws \think\Exception
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public static function backBrokerageTwo($levelInfo, bool $open = true)
+    {
+        //TODO 获取购买商品的用户
+        $userInfo = User::getUserInfo($levelInfo['uid']);
+        //TODO 获取上推广人
+        $userInfoTwo = User::getUserInfo($userInfo['spread_uid']);
+        //TODO 上推广人不存在 或者 上推广人没有上级  或者 当用用户上上级时自己  直接返回
+        if (!$userInfoTwo || !$userInfoTwo['spread_uid'] || $userInfoTwo['spread_uid'] == $levelInfo['uid']) return true;
+        //TODO 获取后台分销类型  1 指定分销 2 人人分销
+        if (!User::be(['uid' => $userInfoTwo['spread_uid']])) return true;
+
+        $brokeragePrice =  bcmul($levelInfo['pay_price'],sys_config('vip_two_brokerage')/100,2);
+        //TODO 返佣金额小于等于0 直接返回不返佣金
+        if ($brokeragePrice <= 0) return true;
+        //TODO 获取上上级推广员信息
+        $spreadUserInfoTwo = User::getUserInfo($userInfoTwo['spread_uid']);
+        //TODO 获取上上级推广员返佣之后余额
+        $balance = bcadd($spreadUserInfoTwo['brokerage_price'], $brokeragePrice, 2);
+        $mark = '二级推广人' . $userInfo['nickname'] . '开通会员' . floatval($levelInfo['pay_price']) . '元,奖励推广佣金' . floatval($brokeragePrice)."元";
+        $open && self::beginTrans();
+        //TODO 添加返佣记录
+        $res1 = UserBill::income('获得推广佣金', $userInfoTwo['spread_uid'], 'now_money', 'brokerage', $brokeragePrice, $levelInfo['id'], $balance, $mark);
+        //TODO 添加用户余额
+        $res2 = self::bcInc($userInfoTwo['spread_uid'], 'brokerage_price', $brokeragePrice, 'uid');
+        $res = $res1 && $res2;
+        $open && self::checkTrans($res);
+        return $res;
+    }
+    /**
+     * 获取会员升级订单
+     */
+    public static function orderlist($where)
+    {
+        $model = new self;
+        if(isset($where['data']) && $where['data'] !='') $model = $model->getModelTime($where,$model,"addtime");
+        if(isset($where['paid']) && $where['paid'] >-1)  $model = $model->where('paid',$where['paid']);
+        if(isset($where['key']) && $where['key'] !='') $model = $model->where('order_id','like',"%".$where['key']."%");
+        $model = $model->order('id desc');
+        return self::page($model, function ($v) {
+            $info = User::where('uid',$v['uid'])->find();
+            $v['nickname'] = $info['nickname'];
+            $v['avatar'] = $info['avatar'];
+        }, $where);
+    }
+
+}

+ 545 - 0
app/models/store/Package.php

@@ -0,0 +1,545 @@
+<?php
+namespace app\models\store;
+use app\models\system\SystemUserLevel;
+use app\models\user\User;
+use app\models\user\UserBill;
+use crmeb\basic\BaseModel;
+use crmeb\services\UtilService;
+use crmeb\traits\ModelTrait;
+use think\Exception;
+use think\facade\Log;
+use think\Model;
+
+class Package extends BaseModel
+{
+    use ModelTrait;
+
+    /**
+     * 预约
+     * @param $uid
+     * @param $package_manager
+     * @param $price
+     * @param $day
+     * @param $proportion
+     * @return Package|bool|Model
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public static function reserve($uid,$package_manager,$price,$day,$proportion,$pass)
+    {
+        $data['uid'] = $uid;
+        $data['package_manager'] = $package_manager;
+        //if(!self::is_valid()) return self::setErrorInfo('非活动时间,不能预约');
+        $start = strtotime(date("Y-m-d"));
+        if(self::where('package_manager',$package_manager)->where('uid',$uid)->where('add_time','>=',$start)->find())
+        {
+            return self::setErrorInfo('你已报名,无需重复报名');
+        }
+        $data['add_time'] = time();
+        $data['order_id'] = self::getNewOrderId();
+        $data['proportion'] = $proportion;
+        $data['price'] = $price;
+        $data['day'] = $day;
+        $data['am'] = date("H")>12?0:1;
+        $data['pass'] = $pass;
+        return self::create($data);
+    }
+
+    /**
+     * 是否活动时间
+     */
+    public static function is_valid()
+    {
+        $am= explode("~",sys_config('start_time'));
+        $pm = explode("~",sys_config('end_time'));
+        if((date("H:i")>$am[0] && date("H:i")<$am[1]))
+        {
+            return 1;
+        }
+        elseif((date("H:i")>$pm[0] && date("H:i")<$pm[1]))
+        {
+            return 2;
+        }
+        return 0;
+    }
+
+    /**
+     * 兑换
+     * @param $uid
+     * @param $package_manager
+     * @param $price
+     * @param $day
+     * @param $proportion
+     * @param $consume_pass
+     * @param int $type
+     * @param int $am
+     */
+    public static function create_order($uid,$tu_uid=0,$id,$price)
+    {
+        $user = User::find($uid);
+        $H = date("H");
+        if ($type==1 && $H < 12 ) {
+            return self::setErrorInfo("推荐兑换只能在下午市进行");
+        }
+        if($type>0 && $consume_pass==0 || $user['now_money']<$consume_pass)
+        {
+            return self::setErrorInfo('通行证少于'.$consume_pass.",请先买通行证!");
+        }
+        if( $user['brokerage_price']<$price)
+        {
+            return self::setErrorInfo('收益少于'.$price);
+        }
+        $i = date("i");
+        if ($i < 30) {
+            $start = strtotime(date("Y-m-d H:00:00"));
+            $end = strtotime(date("Y-m-d H:29:59"));
+        } else {
+            $start = strtotime(date("Y-m-d H:30:00"));
+            $end = strtotime(date("Y-m-d H:59:59"));
+        }
+        if(self::where('package_manager',$package_manager)->where('uid',$uid)->where('add_time','>=',$start)->where('add_time','<=',$end)->find())
+        {
+            return self::setErrorInfo('你已报名,无需重复报名');
+        }
+
+        $data['uid'] =$uid;
+        $data['package_manager'] = $package_manager;
+        $data['add_time'] = time();
+        $data['order_id'] = self::getNewOrderId();
+        $data['proportion'] = $proportion;
+        $data['price'] = $price;
+        $data['day'] = $day;
+        $data['consume_pass'] =$consume_pass;
+        $data['am'] = date("H")>12?0:1;
+        $data['pass'] = $pass;
+        $data['type'] = $type;
+        $data['status'] = 4;
+        $res = self::create($data);
+        User::where('uid',$uid)->dec('now_money',$consume_pass)->dec('brokerage_price',$price)->update();
+        UserBill::expend("兑换包扣通证",$uid,'now_money','pay_money',$consume_pass,$res['id'],bcsub($user['now_money'],$consume_pass,2),'兑换包扣除'.$consume_pass."通行证");
+        UserBill::expend("兑换包扣收益",$uid,'now_money','pay_money',$price,$res['id'],bcsub($user['brokerage_price'],$price,2),'兑换包扣除'.$price."收益");
+        return  $res;
+    }
+
+    /**
+     * 生成订单唯一id
+     * @param $uid 用户uid
+     * @return string
+     */
+    public static function getNewOrderId()
+    {
+        list($msec, $sec) = explode(' ', microtime());
+        $msectime = number_format((floatval($msec) + floatval($sec)) * 1000, 0, '', '');
+        $orderId = 'pk' . $msectime . mt_rand(10000, 99999);
+        while (self::be(['order_id' => $orderId])) $orderId = 'pk' . $msectime . mt_rand(10000, 99999);
+        return $orderId;
+    }
+
+
+    /**
+     * 我的订单
+     * @return bool|string
+     */
+    public static function getlist()
+    {
+        $rs = sys_data('package_manager');
+        $am= explode("~",sys_config('start_time'));
+        $pm= explode("~",sys_config('end_time'));
+        foreach ($rs as &$v) {
+            $v['cts'] =self::where('package_manager',$v['id'])->where('add_time','>=',strtotime(date("Y-m-d ")))->where('add_time','<',strtotime(date("Y-m-d ").$v['end']))->count();
+            $v['cts'] = bcadd($v['virtual'],$v['cts']);
+        }
+
+        return $rs;
+    }
+
+    /**
+     * 收货确认
+     * @param $id
+     */
+    public static function take($id)
+    {
+        $info = self::find($id);
+        $data['start_day'] = time();
+        $data['end_day'] = strtotime("+".$info['day']." days");
+        $data['status'] = 3;
+        $data['sum_revenue'] = bcdiv(bcmul(bcmul($info['proportion'],$info['day'],4),$info['price'],4),100,2);
+        $data['paid'] = 1;
+        self::beginTrans();
+        try {
+            User::where('uid',$info['uid'])->inc('now_money',$info['pass'])->update();
+            $user = User::where('uid',$info['uid'])->find();
+            UserBill::income('通证收益',$info['uid'],'now_money','sign',$info['pass'],$info['id'],$user['now_money'],'包收益通证'.$info['pass']);
+            $res = self::edit($data,$id);
+            $res1 =  self::backBrokerage($info);
+            if($info['last_id']>0) self::edit(['status'=>6],$info['last_id']);
+            self::commitTrans();
+        }
+        catch (Exception $e)
+        {
+            Log::error('收货错误:' .$e->getFile().'行'.$e->getLine()."原因:".$e->getMessage());
+            self::setErrorInfo('收货确认错误',true);
+        }
+        return true;
+
+    }
+
+    /**
+     * 定时执行
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public static function make_package()
+    {
+        self::startTrans();
+        try {
+            $package_manager = sys_data('package_manager');
+            $package = [];
+            foreach ($package_manager as $v) {
+                if(date("H:i") == $v['open'])
+                $package[] = $v;
+            }
+            $uids = User::where('is_sys', 1)->column('uid');
+            foreach ($package as $v)
+            {
+                $arr = self::where('status', 0)->where('package_manager',$v['id'])->where('add_time','<',strtotime(date("Y-m-d ").$v['end'].":00"))->select();
+                if ($arr) {
+                    $ids = [];
+                    $sum = $v['one'];
+                    if (sizeof($arr->toArray()) > $sum) {
+                        $ids = self::getrand($arr->toArray(), $sum);
+                    } else {
+                        foreach ($arr as $v1) {
+                            $ids[] = $v1['id'];
+                        }
+                    }
+                    foreach ($ids as $v2) {
+
+                        $info = self::where('status', 4)->where('uid','not in',$uids)->where('add_time','<',strtotime("-30 minute"))->where('package_manager', $v['id'])->find();
+                        $last_id = 0;
+                        if ($info) {
+                            $to_uid = $info['uid'];
+                            $last_id = $info['id'];
+                            self::edit(['status' => 5], $info['id']);
+                        } else {
+                            $to_uid = User::where('is_sys', 1)->order('sys_pay asc,uid asc')->value('uid');
+                            User::where('uid', $to_uid)->inc('sys_pay', 1)->update();
+
+                        }
+                        self::edit(['to_uid' => $to_uid, 'status' => 1,'last_id'=>$last_id,'lottery_time'=>time()], $v2);
+                    }
+
+                }
+            }
+            self::checkTrans(true);
+        }catch (Exception $e)
+        {
+            self::setErrorInfo('生成出错'.$e->getMessage(),true);
+        }
+    }
+    /**
+     * 定时执行老
+     */
+    public static function make_package2()
+    {
+        self::startTrans();
+        try {
+            $H = date("H");
+            $package_manager = sys_data('package_manager');
+            $package = [];
+            foreach ($package_manager as $v) {
+                $package[$v['id']] = $v;
+            }
+            $model = new self;
+            $model = $model->where('add_time','<',strtotime("-30 minute"));
+            $where = null;
+            if ($H < 13) {
+                $model = $model->where('am', 1);
+                $where['am'] = 1;
+            } else {
+                $model = $model->where('am', 0);
+                $where['am'] = 0;
+            }
+            $rs = $model->where('status', 0)->group('package_manager')->field('package_manager,count(package_manager) as ct')->select();
+
+            foreach ($rs as $v) {
+                $arr = self::where('status', 0)->where($where)->where('add_time','<',strtotime("-30 minute"))->where('package_manager', $v['package_manager'])->select();
+                if ($arr) {
+                    $ids = [];
+                    $sum = $package[$v['package_manager']]['one'];
+                    if (sizeof($arr->toArray()) > $sum) {
+                        $ids = self::getrand($arr->toArray(), $sum);
+                    } else {
+                        foreach ($arr as $v1) {
+                            $ids[] = $v1['id'];
+                        }
+                    }
+                    foreach ($ids as $v2) {
+                        $info = self::where('status', 4)->where($where)->where('add_time','<',strtotime("-30 minute"))->where('package_manager', $v['package_manager'])->find();
+                        $last_id = 0;
+                        if ($info) {
+                            $to_uid = $info['uid'];
+                            $last_id = $info['id'];
+                            self::edit(['status' => 5], $info['id']);
+                        } else {
+                            $to_uid = User::where('is_sys', 1)->order('sys_pay asc,uid asc')->value('uid');
+                            User::where('uid', $to_uid)->inc('sys_pay', 1)->update();
+                        }
+                        self::edit(['to_uid' => $to_uid, 'status' => 1,'last_id'=>$last_id,'lottery_time'=>time()], $v2);
+                    }
+                }
+            }
+            self::checkTrans(true);
+        }catch (Exception $e)
+        {
+            self::setErrorInfo('生成出错'.$e->getMessage(),true);
+        }
+    }
+
+    /**
+     * 返现
+     * @param $info
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public static function backBrokerage($info)
+    {
+        $userinfo = User::find($info['uid']);
+        $spreaduser = User::where('uid',$userinfo['spread_uid'])->find();
+        $twouser = User::where('uid',$spreaduser['spread_uid'])->find();
+        $bksum = bcdiv(bcmul($info['price'],bcmul($info['proportion'],$info['day'],2),2),100,2);
+        if($spreaduser['level']>0) {
+            $recommend = bcmul(bcdiv(sys_config('recommend'),100,2), $bksum, 2);
+            $mark = "订单号" . $info['order_id'] . '产生推荐奖,奖励推广佣金' . $recommend;
+            $res1 = UserBill::income('推荐奖', $spreaduser['uid'], 'now_money', 'brokerage', $recommend, $info['id'], bcadd($recommend, $spreaduser['brokerage_price'], 2), $mark);
+            $res2 = User::where('uid', $spreaduser['uid'])->inc('brokerage_price', $recommend)->update();
+        }
+        //二代推荐
+        if($twouser && $twouser['level']>1)
+        {
+            $recommend = bcmul(bcdiv(sys_config('two_recommend'),100,2), $bksum, 2);
+            $mark = "订单号" . $info['order_id'] . '产生推荐奖,奖励推广佣金' . $recommend;
+            $res1 = UserBill::income('二代推荐奖', $twouser['uid'], 'now_money', 'brokerage', $recommend, $info['id'], bcadd($recommend, $twouser['brokerage_price'], 2), $mark);
+            $res2 = User::where('uid', $twouser['uid'])->inc('brokerage_price', $recommend)->update();
+        }
+
+        $userlist = User::select()->toArray();
+        $pids = UtilService::getparentid($userlist, $info['uid']);
+        $levels = SystemUserLevel::where('is_del',0)->where('is_show',1)->field('id,name,peer_award,team_award')->select();
+        $levela = [];$current_level = $spreaduser['level'];
+        foreach ($levels as $v)
+        {
+            $levela[$v['id']]['peer_award'] = $v['peer_award'];
+            $levela[$v['id']]['team_award'] = $v['team_award'];
+            $levela[$v['id']]['sbl'] = false;
+            $levela[$v['id']]['use'] = false;
+        }
+        if($pids) {
+            foreach ($pids as $v) {
+                if ($v['level'] >= $current_level && $levela[$v['level']]['team_award'] > 0) {
+                    //处理第一次
+                    if ($levela[$v['level']]['use']==false) {
+                        $level_award = $levela[$v['level']]['team_award'];
+                        $levela[$v['level']]['use'] = true;
+                    } else {
+                        if ($levela[$v['level']]['sbl']==false) {
+                            $level_award = $levela[$v['level']]['peer_award'];
+                            $levela[$v['level']]['sbl'] = true;
+                        }
+                    }
+                    if ($v['level'] > $current_level) {
+                        $current_level = $v['level'];
+                    } else {
+                        if ($v['level'] == $current_level && $levela[$v['level']]['sbl'] == true) {
+                            $current_level++;
+                        }
+                    }
+                    $proportion = bcmul($bksum, bcdiv($level_award, 100, 2), 2);
+                    if($proportion==0) continue;
+                    if ($levela[$v['level']]['sbl'] == true) {
+                        $mark = "订单号" . $info['order_id'] . '产生平级奖,奖励推广佣金' . $proportion;
+                        $res1 = UserBill::income('平级奖', $v['uid'], 'now_money', 'brokerage', $proportion, $info['id'], bcadd($proportion, $v['brokerage_price'], 2), $mark);
+                        $res2 = User::where('uid', $v['uid'])->inc('brokerage_price', $proportion)->update();
+                    } else {
+                        $mark = "订单号" . $info['order_id'] . '产生团队奖,奖励推广佣金' . $proportion;
+                        $res1 = UserBill::income('团队奖', $v['uid'], 'now_money', 'brokerage', $proportion, $info['id'], bcadd($proportion, $v['brokerage_price'], 2), $mark);
+                        $res2 = User::where('uid', $v['uid'])->inc('brokerage_price', $proportion)->update();
+                    }
+
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 订单无效
+     * @param $id
+     */
+    public static function invalid($id,$re='')
+    {
+        $data['status'] = -2;
+        $data['re'] = $re;
+        $last_id = self::where('id',$id)->value('last_id');
+        if($last_id>0) self::edit(['status'=>4],$last_id);
+        return self::edit($data,$id);
+    }
+
+    /**
+     * 支付超时
+     */
+    public static function time_out()
+    {
+        $list = self::where('status',1)->where('lottery_time','<',strtotime("-".sys_config('time_out')." minute"))->select();
+        foreach ($list as $v)
+        {
+            if($v['last_id']>0) self::edit(['status'=>4],$v['last_id']);
+            self::edit(['status'=>-3],$v['id']);
+            $user =User::where('uid',$v['uid'])->find();
+            User::where('uid',$v['uid'])->inc('notpay',1)->update();
+            if($user['notpay']<9)
+            {
+                if(bcadd($user['notpay'],1) % 3==0)
+                {
+                    $mark = "累计提时" .bcadd($user['notpay'],1) . '扣通行证100';
+                    $res1 = UserBill::expend('支付超时', $v['uid'], 'now_money', 'pay_money', 100, 0, bcsub($v['now_money'],100, 2), $mark);
+                    $res2 = User::where('uid', $v['uid'])->dec('now_money', 100)->update();
+                }
+            }
+            else
+            {
+                if($user['status'] ==1)
+                User::where('uid',$v['uid'])->update(['status'=>0]);
+            }
+        }
+        return ;
+    }
+    /**
+     * 获取中奖用户编号
+     * 先根据投入积分求出未中奖用户,然后在获取中奖用户
+     * @param $user
+     * @return array
+     */
+    public static function getrand($user, $prize_person_num = 1)
+    {
+        $user_arr = []; //随机数组
+        $n = 0;
+        $count = 0;$sum = 0;
+        foreach ($user as $v)
+        {
+            $sum += bcadd(100,0,0);
+        }
+        foreach ($user as $v) {
+            $user_arr [$n] = [
+                'id' => $v['id'],
+                "start" => $count,
+                "end" => $count + ($sum-bcadd(100,0,0)),
+            ];
+            $n++;
+            $count +=($sum-bcadd(100,0,0))+1;
+        }
+        $prize_arr = [];
+        $n = $prize_person_num;   //中奖人数
+        while (sizeof($prize_arr) < $n) {
+            $random = mt_rand(0, $count);   //随机数
+            foreach ($user_arr as $item) {
+                if ($random >= $item['start'] && $random <= $item['end'] && !in_array($item['id'],$prize_arr)) {
+                    $prize_arr[] = $item['id'];
+                    break;
+                }
+            }
+        }
+        return $prize_arr;
+    }
+
+    /**
+     * 获取列表
+     * @param $where
+     */
+    public static function lst($where)
+    {
+        $model = new self;
+        if(isset($where['data']) && $where['data']!='') $model = $model->getModelTime($where,$model);
+        if(isset($where['uid']) && $where['uid']>0) $model = $model->where('uid',$where['uid']);
+        if(isset($where['to_uid']) && $where['to_uid']>0) $model = $model->where('to_uid',$where['to_uid']);
+        if(isset($where['status']) && $where['status']>-4) $model = $model->where('status',$where['status']);
+        if(isset($where['type']) && $where['type']>-1) $model = $model->where('type',$where['type']);
+        $count = $model->value('count(id)')?:0;
+        $data = $model->order('id desc')->page($where['page'],$where['limit'])->select();
+        foreach ($data as &$v)
+        {
+            $v['user'] = User::where('uid',$v['uid'])->field('real_name,avatar,phone')->find()->toArray();
+            if($v['to_uid']>0) {
+                $v['touser'] = User::where('uid', $v['to_uid'])->field('real_name,avatar,phone,wx_qr,wx_no,alipay_no,alipay_name,account_Bank,bank_card,bank_name,bank_branch')->find()->toArray();
+            }
+        }
+        return compact('count','data');
+    }
+
+
+    /**
+     * 每天分账
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public static function day()
+    {
+        self::beginTrans();
+        try {
+            $list = self::where('status', 3)->where('end_day', '>', date("Y-m-d 00:00:00"))->where('sum_revenue', 'exp', '>use_revenue')->field('id,uid,order_id,sum_revenue/day as revenue,sum_revenue,use_revenue,price,pass')->select();
+
+            if ($list) {
+                foreach ($list->toarray() as $v) {
+                    if (floatval($v['sum_revenue']) - floatval($v['revenue']) - floatval($v['use_revenue']) > 0) {
+                        $data['use_revenue'] = bcadd($v['use_revenue'], $v['revenue'], 2);
+                        $number = $v['revenue'];
+                    } else {
+                        $data['use_revenue'] = $v['sum_revenue'];
+                        $number = bcsub($v['sum_revenue'], $v['use_revenue'], 2);
+                        $data['status'] = 4;
+                    }
+                    self::edit($data, $v['id']);
+                    $brokerage_price = User::where('uid', $v['uid'])->value('brokerage_price');
+                    User::where('uid',$v['uid'])->inc('brokerage_price',bcmul($number,0.8,2))->inc("integral",bcmul($number,0.2,2))->update();
+                    $mark = sprintf("订单号:%s,订单金额%d,当天收益%f,积分%f", $v['order_id'], $v['price'], bcmul($number,0.8,2),bcmul($number,0.2,2));
+                    UserBill::income('每天收益', $v['uid'], 'now_money', 'brokerage', bcmul($number,0.8,2), $v['id'], bcadd($brokerage_price, bcmul($number,0.8,2)), $mark);
+                    UserBill::income('每天收益积分', $v['uid'], 'integral', 'add', bcmul($number,0.2,2), $v['id'], bcadd($brokerage_price, bcmul($number,0.2,2)), $mark);
+
+                    unset($data);
+                }
+            }
+            self::commitTrans();
+        }
+        catch (Exception $e)
+        {
+            return  self::setErrorInfo('生成出错',true);
+        }
+        return true;
+    }
+    /**
+     * 获取会员升级订单
+     */
+    public static function orderlist($where)
+    {
+        $model = new self;
+        if(isset($where['data']) && $where['data'] !='') $model = $model->getModelTime($where,$model,"add_time");
+        if(isset($where['paid']) && $where['paid'] >-1)  $model = $model->where('paid',$where['paid']);
+        if(isset($where['status']) && $where['status'] >-4)  $model = $model->where('status',$where['status']);
+        if(isset($where['key']) && $where['key'] !='') $model = $model->where('order_id','like',"%".$where['key']."%");
+        $model = $model->order('id desc');
+        return self::page($model, function ($v) {
+            $v['user'] = User::where('uid',$v['uid'])->field('nickname,real_name,avatar,phone')->find()->toArray();
+            if($v['to_uid']>0) {
+                $v['touser'] = User::where('uid', $v['to_uid'])->field('real_name,real_name,avatar,phone,wx_qr,wx_no,alipay_no,alipay_name,account_Bank,bank_card,bank_name,bank_branch')->find()->toArray();
+            }
+            else
+            {
+                $v['touser'] = null;
+            }
+        }, $where);
+    }
+}

+ 314 - 0
app/models/store/StoreWholesale.php

@@ -0,0 +1,314 @@
+<?php
+namespace app\models\store;
+use crmeb\basic\BaseModel;
+use crmeb\services\PHPExcelService;
+use crmeb\traits\ModelTrait;
+use app\admin\model\system\SystemGroupData;
+
+class StoreWholesale extends BaseModel
+{
+    use ModelTrait;
+    protected function getImagesAttr($value)
+    {
+        return json_decode($value, true) ?: [];
+    }
+
+    public function getDescriptionAttr($value)
+    {
+        return htmlspecialchars_decode($value);
+    }
+    public static function lst($where)
+    {
+
+    }
+    public static function getWholeCount()
+    {
+        $seckillTime = sys_data('Whole_time') ?: [];//秒杀时间段
+        $timeInfo = ['time' => 0, 'continued' => 0];
+        foreach ($seckillTime as $key => $value) {
+            $currentHour = date('H');
+            $activityEndHour = bcadd((int)$value['time'], (int)$value['continued'], 0);
+            if ($currentHour >= (int)$value['time'] && $currentHour < (int)$activityEndHour && (int)$activityEndHour < 24) {
+                $timeInfo = $value;
+                break;
+            }
+        }
+
+        if ($timeInfo['time'] == 0) return 0;
+        $activityEndHour = bcadd((int)$timeInfo['time'], (int)$timeInfo['continued'], 0);
+        $startTime = bcadd(strtotime(date('Y-m-d')), bcmul($timeInfo['time'], 3600, 0));
+        $stopTime = bcadd(strtotime(date('Y-m-d')), bcmul($activityEndHour, 3600, 0));
+        echo $startTime;
+        return self::where('is_del', 0)->where('status', 1)->where('start_time', '<=', $startTime)->where('stop_time', '>=', $stopTime)->count();
+    }
+    /**
+     * 获取批发列表
+     * @param $time
+     * @param int $page
+     * @param int $limit
+     * @return array
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public static function WholeList($time, $page = 0, $limit = 20)
+    {
+        if ($page) $list = self::alias('n')->where('n.is_del', 0)->where('n.status', 1)->where('n.start_time', '<=', time())->where('n.stop_time', '>=', time() - 86400)->where('n.time_id', $time)->field('n.*')->order('n.sort desc')->page($page, $limit)->select();
+        else $list = self::alias('n')->where('n.is_del', 0)->where('n.status', 1)->where('n.start_time', '<=', time())->where('n.stop_time', '>=', time() - 86400)->where('n.time_id', $time)->field('n.*')->order('sort desc')->select();
+        if ($list) return $list->hidden(['cost', 'add_time', 'is_del'])->toArray();
+        return [];
+    }
+    /**
+     * 获取所有批发产品
+     * @param string $field
+     * @return array
+     */
+    public static function getListAll($offset = 0, $limit = 10, $field = 'id,image,title,price,ot_price,start_time,stop_time,stock,sales')
+    {
+        $time = time();
+        $model = self::where('is_del', 0)->where('status', 1)->where('stock', '>', 0)->field($field)
+            ->where('start_time', '<', $time)->where('stop_time', '>', $time)->order('sort DESC,add_time DESC');
+        $model = $model->limit($offset, $limit);
+        $list = $model->select();
+        if ($list) return $list->toArray();
+        else return [];
+    }
+    /**
+     * 获取热门推荐的批发产品
+     * @param int $limit
+     * @param string $field
+     * @return array
+     */
+    public static function getHotList($limit = 0, $field = 'id,image,title,price,ot_price,start_time,stop_time,stock')
+    {
+        $time = time();
+        $model = self::where('is_hot', 1)->where('is_del', 0)->where('status', 1)->where('stock', '>', 0)->field($field)
+            ->where('start_time', '<', $time)->where('stop_time', '>', $time)->order('sort DESC,add_time DESC');
+        if ($limit) $model->limit($limit);
+        $list = $model->select();
+        if ($list) return $list->toArray();
+        else return [];
+    }
+    /**
+     * 获取批发是否有开启
+     * @return bool
+     */
+    public static function getWholeContStatus()
+    {
+        $time = time();
+        $count = self::where('is_del', 0)->where('status', 1)->where('start_time', '<', $time)->where('stop_time', '>', $time)->count();
+        return $count ? true : false;
+    }
+    /** 获取批发产品库存
+     * @param $id
+     * @return mixed
+     */
+    public static function getProductStock($id)
+    {
+        return self::where('id', $id)->value('stock');
+    }
+    /**
+     * 获取一条产品
+     * @param $id
+     * @param string $field
+     * @return array|false|\PDOStatement|string|\think\Model
+     */
+    public static function getValidProduct($id, $field = '*')
+    {
+        $time = time();
+        $info = self::alias('n')->where('n.id', $id)->where('n.is_del', 0)->where('n.status', 1)->where('n.start_time', '<', $time)->where('n.stop_time', '>', $time - 86400)->field('n.*')->find();
+        if ($info['id']) {
+            return $info;
+        } else {
+            return [];
+        }
+    }
+    /**
+     * 获取批发是否已结束
+     * @param $seckill_id
+     * @return bool
+     */
+    public static function isWholeEnd($seckill_id)
+    {
+        $time_id = self::where('id', $seckill_id)->value('time_id');
+        //秒杀时间段
+        $seckillTime = sys_data('Whole_time') ?? [];
+        $seckillTimeIndex = 0;
+        $activityTime = [];
+        if (count($seckillTime)) {
+            foreach ($seckillTime as $key => &$value) {
+                $currentHour = date('H');
+                $activityEndHour = bcadd((int)$value['time'], (int)$value['continued'], 0);
+                if ($activityEndHour > 24) {
+                    $value['time'] = strlen((int)$value['time']) == 2 ? (int)$value['time'] . ':00' : '0' . (int)$value['time'] . ':00';
+                    $value['state'] = '即将开始';
+                    $value['status'] = 2;
+                    $value['stop'] = (int)bcadd(strtotime(date('Y-m-d')), bcmul($activityEndHour, 3600, 0));
+                } else {
+                    if ($currentHour >= (int)$value['time'] && $currentHour < $activityEndHour) {
+                        $value['time'] = strlen((int)$value['time']) == 2 ? (int)$value['time'] . ':00' : '0' . (int)$value['time'] . ':00';
+                        $value['state'] = '抢购中';
+                        $value['stop'] = (int)bcadd(strtotime(date('Y-m-d')), bcmul($activityEndHour, 3600, 0));
+                        $value['status'] = 1;
+                        if (!$seckillTimeIndex) $seckillTimeIndex = $key;
+                    } else if ($currentHour < (int)$value['time']) {
+                        $value['time'] = strlen((int)$value['time']) == 2 ? (int)$value['time'] . ':00' : '0' . (int)$value['time'] . ':00';
+                        $value['state'] = '即将开始';
+                        $value['status'] = 2;
+                        $value['stop'] = (int)bcadd(strtotime(date('Y-m-d')), bcmul($activityEndHour, 3600, 0));
+                    } else if ($currentHour >= $activityEndHour) {
+                        $value['time'] = strlen((int)$value['time']) == 2 ? (int)$value['time'] . ':00' : '0' . (int)$value['time'] . ':00';
+                        $value['state'] = '已结束';
+                        $value['status'] = 0;
+                        $value['stop'] = (int)bcadd(strtotime(date('Y-m-d')), bcmul($activityEndHour, 3600, 0));
+                    }
+                }
+
+                if ($value['id'] == $time_id) {
+                    $activityTime = $value;
+                    break;
+                }
+            }
+        }
+        if (time() < $activityTime['stop'])
+            return true;
+        else
+            return false;
+    }
+    /**
+     * 检查批发活动状态
+     * @param $seckill_id
+     * @return bool
+     */
+    public static function checkStatus($seckill_id)
+    {
+        $time_id = self::where('id', $seckill_id)->value('time_id');
+        //秒杀时间段
+        $seckillTime = sys_data('Whole_time') ?? [];
+        $seckillTimeIndex = 0;
+        $activityTime = [];
+        if (count($seckillTime)) {
+            foreach ($seckillTime as $key => &$value) {
+                $currentHour = date('H');
+                $activityEndHour = bcadd((int)$value['time'], (int)$value['continued'], 0);
+                if ($activityEndHour > 24) {
+                    $value['time'] = strlen((int)$value['time']) == 2 ? (int)$value['time'] . ':00' : '0' . (int)$value['time'] . ':00';
+                    $value['state'] = '即将开始';
+                    $value['status'] = 2;
+                    $value['stop'] = (int)bcadd(strtotime(date('Y-m-d')), bcmul($activityEndHour, 3600, 0));
+                } else {
+                    if ($currentHour >= (int)$value['time'] && $currentHour < $activityEndHour) {
+                        $value['time'] = strlen((int)$value['time']) == 2 ? (int)$value['time'] . ':00' : '0' . (int)$value['time'] . ':00';
+                        $value['state'] = '抢购中';
+                        $value['stop'] = (int)bcadd(strtotime(date('Y-m-d')), bcmul($activityEndHour, 3600, 0));
+                        $value['status'] = 1;
+                        if (!$seckillTimeIndex) $seckillTimeIndex = $key;
+                    } else if ($currentHour < (int)$value['time']) {
+                        $value['time'] = strlen((int)$value['time']) == 2 ? (int)$value['time'] . ':00' : '0' . (int)$value['time'] . ':00';
+                        $value['state'] = '即将开始';
+                        $value['status'] = 2;
+                        $value['stop'] = (int)bcadd(strtotime(date('Y-m-d')), bcmul($activityEndHour, 3600, 0));
+                    } else if ($currentHour >= $activityEndHour) {
+                        $value['time'] = strlen((int)$value['time']) == 2 ? (int)$value['time'] . ':00' : '0' . (int)$value['time'] . ':00';
+                        $value['state'] = '已结束';
+                        $value['status'] = 0;
+                        $value['stop'] = (int)bcadd(strtotime(date('Y-m-d')), bcmul($activityEndHour, 3600, 0));
+                    }
+                }
+
+                if ($value['id'] == $time_id) {
+                    $activityTime = $value;
+                    break;
+                }
+            }
+        }
+        return $activityTime;
+    }
+    public static function SaveExcel($where)
+    {
+        $model = new self;
+        if ($where['status'] != '') $model = $model->where('status', $where['status']);
+        if ($where['store_name'] != '') $model = $model->where('title|id', 'LIKE', "%$where[store_name]%");
+        $list = $model->order('id desc')->where('is_del', 0)->select();
+        count($list) && $list = $list->toArray();
+        $excel = [];
+        foreach ($list as $item) {
+            if ($item['status']) {
+                if ($item['start_time'] > time())
+                    $item['start_name'] = '活动未开始';
+                else if ($item['stop_time'] < time())
+                    $item['start_name'] = '活动已结束';
+                else if ($item['stop_time'] > time() && $item['start_time'] < time())
+                    $item['start_name'] = '正在进行中';
+            } else $item['start_name'] = '关闭';
+            $excel[] = [
+                $item['id'],
+                $item['title'],
+                $item['info'],
+                $item['ot_price'],
+                $item['price'],
+                $item['stock'],
+                $item['start_name'],
+                $item['stop_time'],
+                $item['stop_time'],
+                $item['status'] ? '开启' : '关闭',
+            ];
+        }
+        PHPExcelService::setExcelHeader(['编号', '活动标题', '活动简介', '原价', '秒杀价', '库存', '秒杀状态', '结束时间', '状态'])
+            ->setExcelTile('秒杀产品导出', ' ', ' 生成时间:' . date('Y-m-d H:i:s', time()))
+            ->setExcelContent($excel)
+            ->ExcelSave();
+    }
+    /**
+     * @param $where
+     * @return array
+     */
+    public static function systemPage($where)
+    {
+        $model = new self;
+        $model = $model->alias('s');
+        if ($where['status'] != '') $model = $model->where('s.status', $where['status']);
+        if ($where['store_name'] != '') $model = $model->where('s.title|s.id', 'LIKE', "%$where[store_name]%");
+        $model = $model->page(bcmul($where['page'], $where['limit'], 0), $where['limit']);
+        $model = $model->order('s.id desc');
+        $model = $model->where('s.is_del', 0);
+        return self::page($model, function ($item) {
+            $item['store_name'] = $item['title'];
+            if ($item['status']) {
+                if (strtotime($item['start_time']) > time())
+                    $item['start_name'] = '活动未开始';
+                else if (bcadd(strtotime($item['stop_time']), 86400) < time())
+                    $item['start_name'] = '活动已结束';
+                else if (bcadd(strtotime($item['stop_time']), 86400) > time() && strtotime($item['start_time']) < time()) {
+                    $config = SystemGroupData::get($item['time_id']);
+
+                    if ($config) {
+                        $arr = json_decode($config->value, true);
+                        $now_hour = date('H', time());
+                        $start_hour = $arr['time']['value'];
+                        $continued = $arr['continued']['value'];
+                        $end_hour = $start_hour + $continued;
+                        if ($start_hour > $now_hour) {
+                            $item['start_name'] = '活动未开始';
+                        } elseif ($end_hour < $now_hour) {
+                            $item['start_name'] = '活动已结束';
+                        } else {
+                            $item['start_name'] = '正在进行中';
+                        }
+                    } else {
+                        $item['start_name'] = '正在进行中';
+                    }
+                }
+            } else $item['start_name'] = '关闭';
+
+        }, $where, $where['limit']);
+    }
+    /**
+     * 获取批发产品id
+     * @return array
+     */
+    public static function getWholeIdAll()
+    {
+        return self::where('is_del', 0)->column('id', 'id');
+    }
+}