quanwei
2025-12-04 12913c1069347ea4b1f6ab87f480da0f8d8c646a
供需求功能
110 files added
30 files modified
18463 ■■■■■ changed files
admin/app/api/controller/plus/release/Cart.php 81 ●●●●● patch | view | raw | blame | history
admin/app/api/controller/plus/release/Cash.php 78 ●●●●● patch | view | raw | blame | history
admin/app/api/controller/plus/release/DemandIndex.php 98 ●●●●● patch | view | raw | blame | history
admin/app/api/controller/plus/release/DemandProject.php 122 ●●●●● patch | view | raw | blame | history
admin/app/api/controller/plus/release/Order.php 154 ●●●●● patch | view | raw | blame | history
admin/app/api/controller/plus/release/Project.php 72 ●●●●● patch | view | raw | blame | history
admin/app/api/controller/plus/release/SupplyIndex.php 99 ●●●●● patch | view | raw | blame | history
admin/app/api/controller/plus/release/SupplyProject.php 130 ●●●●● patch | view | raw | blame | history
admin/app/api/controller/product/Product.php 16 ●●●●● patch | view | raw | blame | history
admin/app/api/model/order/Cart.php 7 ●●●●● patch | view | raw | blame | history
admin/app/api/model/plus/release/Cart.php 231 ●●●●● patch | view | raw | blame | history
admin/app/api/model/plus/release/Cash.php 92 ●●●●● patch | view | raw | blame | history
admin/app/api/model/plus/release/DemandApply.php 86 ●●●●● patch | view | raw | blame | history
admin/app/api/model/plus/release/DemandProject.php 157 ●●●●● patch | view | raw | blame | history
admin/app/api/model/plus/release/DemandUser.php 31 ●●●●● patch | view | raw | blame | history
admin/app/api/model/plus/release/Order.php 275 ●●●●● patch | view | raw | blame | history
admin/app/api/model/plus/release/Project.php 34 ●●●●● patch | view | raw | blame | history
admin/app/api/model/plus/release/ReleaseCategory.php 20 ●●●●● patch | view | raw | blame | history
admin/app/api/model/plus/release/Setting.php 19 ●●●●● patch | view | raw | blame | history
admin/app/api/model/plus/release/SupplyApply.php 86 ●●●●● patch | view | raw | blame | history
admin/app/api/model/plus/release/SupplyProject.php 186 ●●●●● patch | view | raw | blame | history
admin/app/api/model/plus/release/SupplyUser.php 31 ●●●●● patch | view | raw | blame | history
admin/app/api/model/plus/release/Tag.php 20 ●●●●● patch | view | raw | blame | history
admin/app/api/model/plus/team/Cash.php 154 ●●●●● patch | view | raw | blame | history
admin/app/api/model/product/Product.php 11 ●●●● patch | view | raw | blame | history
admin/app/api/model/supplier/Supplier.php 6 ●●●● patch | view | raw | blame | history
admin/app/api/service/order/paysuccess/type/PayTypeSuccessFactory.php 3 ●●●●● patch | view | raw | blame | history
admin/app/api/service/order/paysuccess/type/ReleasePaySuccessService.php 124 ●●●●● patch | view | raw | blame | history
admin/app/branch/model/activityProduct/ActivityProduct.php 15 ●●●●● patch | view | raw | blame | history
admin/app/common/enum/order/OrderTypeEnum.php 6 ●●●●● patch | view | raw | blame | history
admin/app/common/model/order/Order.php 2 ●●● patch | view | raw | blame | history
admin/app/common/model/plus/bonus/User.php 27 ●●●● patch | view | raw | blame | history
admin/app/common/model/plus/shareholder/Apply.php 81 ●●●● patch | view | raw | blame | history
admin/app/common/model/plus/team/Apply.php 2 ●●● patch | view | raw | blame | history
admin/app/common/model/plus/vip/GradeLog.php 2 ●●● patch | view | raw | blame | history
admin/app/common/model/plus/vip/Order.php 2 ●●●●● patch | view | raw | blame | history
admin/app/common/model/release/Capital.php 26 ●●●●● patch | view | raw | blame | history
admin/app/common/model/release/Cart.php 231 ●●●●● patch | view | raw | blame | history
admin/app/common/model/release/Cash.php 64 ●●●●● patch | view | raw | blame | history
admin/app/common/model/release/DemandApply.php 82 ●●●●● patch | view | raw | blame | history
admin/app/common/model/release/DemandProject.php 157 ●●●●● patch | view | raw | blame | history
admin/app/common/model/release/DemandUser.php 67 ●●●●● patch | view | raw | blame | history
admin/app/common/model/release/Order.php 109 ●●●●● patch | view | raw | blame | history
admin/app/common/model/release/Project.php 70 ●●●●● patch | view | raw | blame | history
admin/app/common/model/release/ReleaseCategory.php 41 ●●●●● patch | view | raw | blame | history
admin/app/common/model/release/ReleaseProjectImage.php 33 ●●●●● patch | view | raw | blame | history
admin/app/common/model/release/ReleaseProjectTag.php 47 ●●●●● patch | view | raw | blame | history
admin/app/common/model/release/Setting.php 398 ●●●●● patch | view | raw | blame | history
admin/app/common/model/release/SupplyApply.php 82 ●●●●● patch | view | raw | blame | history
admin/app/common/model/release/SupplyProject.php 186 ●●●●● patch | view | raw | blame | history
admin/app/common/model/release/SupplyUser.php 67 ●●●●● patch | view | raw | blame | history
admin/app/common/model/release/Tag.php 35 ●●●●● patch | view | raw | blame | history
admin/app/common/model/supplier/User.php 12 ●●●●● patch | view | raw | blame | history
admin/app/common/model/user/User.php 3 ●●●● patch | view | raw | blame | history
admin/app/shop/controller/plus/release/Cash.php 80 ●●●●● patch | view | raw | blame | history
admin/app/shop/controller/plus/release/DemandApply.php 38 ●●●●● patch | view | raw | blame | history
admin/app/shop/controller/plus/release/DemandProject.php 49 ●●●●● patch | view | raw | blame | history
admin/app/shop/controller/plus/release/DemandUser.php 51 ●●●●● patch | view | raw | blame | history
admin/app/shop/controller/plus/release/Order.php 86 ●●●●● patch | view | raw | blame | history
admin/app/shop/controller/plus/release/ReleaseCategory.php 63 ●●●●● patch | view | raw | blame | history
admin/app/shop/controller/plus/release/Setting.php 139 ●●●●● patch | view | raw | blame | history
admin/app/shop/controller/plus/release/SupplyApply.php 38 ●●●●● patch | view | raw | blame | history
admin/app/shop/controller/plus/release/SupplyProject.php 48 ●●●●● patch | view | raw | blame | history
admin/app/shop/controller/plus/release/SupplyUser.php 51 ●●●●● patch | view | raw | blame | history
admin/app/shop/controller/plus/release/Tag.php 66 ●●●●● patch | view | raw | blame | history
admin/app/shop/controller/plus/shareholder/Setting.php 4 ●●● patch | view | raw | blame | history
admin/app/shop/controller/plus/team/Setting.php 4 ●●● patch | view | raw | blame | history
admin/app/shop/model/order/Order.php 12 ●●●●● patch | view | raw | blame | history
admin/app/shop/model/order/OrderProduct.php 19 ●●●●● patch | view | raw | blame | history
admin/app/shop/model/plus/release/Capital.php 13 ●●●●● patch | view | raw | blame | history
admin/app/shop/model/plus/release/Cash.php 339 ●●●●● patch | view | raw | blame | history
admin/app/shop/model/plus/release/DemandApply.php 82 ●●●●● patch | view | raw | blame | history
admin/app/shop/model/plus/release/DemandProject.php 58 ●●●●● patch | view | raw | blame | history
admin/app/shop/model/plus/release/DemandUser.php 68 ●●●●● patch | view | raw | blame | history
admin/app/shop/model/plus/release/Order.php 167 ●●●●● patch | view | raw | blame | history
admin/app/shop/model/plus/release/ReleaseCategory.php 45 ●●●●● patch | view | raw | blame | history
admin/app/shop/model/plus/release/Setting.php 83 ●●●●● patch | view | raw | blame | history
admin/app/shop/model/plus/release/SupplyApply.php 82 ●●●●● patch | view | raw | blame | history
admin/app/shop/model/plus/release/SupplyProject.php 62 ●●●●● patch | view | raw | blame | history
admin/app/shop/model/plus/release/SupplyUser.php 92 ●●●●● patch | view | raw | blame | history
admin/app/shop/model/plus/release/Tag.php 47 ●●●●● patch | view | raw | blame | history
admin/app/shop/model/plus/shareholder/Bonus.php 6 ●●●● patch | view | raw | blame | history
admin/app/shop/model/plus/shareholder/User.php 52 ●●●●● patch | view | raw | blame | history
mobile/pages.json 162 ●●●● patch | view | raw | blame | history
mobile/pages/product/category.vue 621 ●●●●● patch | view | raw | blame | history
mobile/pages/shop/shop_list.vue 96 ●●●●● patch | view | raw | blame | history
mobile/pages/user/my_shop/product_add.vue 21 ●●●● patch | view | raw | blame | history
mobile/pages/user/my_shop/product_edit.vue 77 ●●●● patch | view | raw | blame | history
mobile/pages3/release/demandapply/apply.vue 258 ●●●●● patch | view | raw | blame | history
mobile/pages3/release/demandindex/index.vue 368 ●●●●● patch | view | raw | blame | history
mobile/pages3/release/demandorder/detail.vue 100 ●●●●● patch | view | raw | blame | history
mobile/pages3/release/demandorder/index.vue 549 ●●●●● patch | view | raw | blame | history
mobile/pages3/release/demandorder/popup/evaluate.vue 178 ●●●●● patch | view | raw | blame | history
mobile/pages3/release/demandproject/edit.vue 393 ●●●●● patch | view | raw | blame | history
mobile/pages3/release/demandproject/index.vue 422 ●●●●● patch | view | raw | blame | history
mobile/pages3/release/demandproject/release.vue 381 ●●●●● patch | view | raw | blame | history
mobile/pages3/release/project/detail.vue 1023 ●●●●● patch | view | raw | blame | history
mobile/pages3/release/project/list.vue 439 ●●●●● patch | view | raw | blame | history
mobile/pages3/release/supplyapply/apply.vue 258 ●●●●● patch | view | raw | blame | history
mobile/pages3/release/supplycash/apply/apply.vue 338 ●●●●● patch | view | raw | blame | history
mobile/pages3/release/supplycash/list/list.vue 200 ●●●●● patch | view | raw | blame | history
mobile/pages3/release/supplyindex/index.vue 373 ●●●●● patch | view | raw | blame | history
mobile/pages3/release/supplyorder/detail.vue 129 ●●●●● patch | view | raw | blame | history
mobile/pages3/release/supplyorder/index.vue 414 ●●●●● patch | view | raw | blame | history
mobile/pages3/release/supplyorder/popup/evaluate.vue 178 ●●●●● patch | view | raw | blame | history
mobile/pages3/release/supplyproject/edit.vue 411 ●●●●● patch | view | raw | blame | history
mobile/pages3/release/supplyproject/index.vue 422 ●●●●● patch | view | raw | blame | history
mobile/pages3/release/supplyproject/release.vue 397 ●●●●● patch | view | raw | blame | history
shop_vue/src/api/plus/release.js 154 ●●●●● patch | view | raw | blame | history
shop_vue/src/components/setlink/part/Menu.vue 10 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/cash/Cash.vue 333 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/cash/dialog/Edit.vue 94 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/demand/apply/Apply.vue 169 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/demand/apply/dialog/Edit.vue 88 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/demand/user/User.vue 205 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/demand/user/dialog/Edit.vue 91 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/demandproject/Edit.vue 79 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/demandproject/dialog/Edit.vue 92 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/demandproject/index.vue 214 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/index.vue 185 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/order/Order.vue 281 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/order/dialog/Edit.vue 182 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/releasecategory/Add.vue 103 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/releasecategory/Edit.vue 106 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/releasecategory/index.vue 130 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/setting/Setting.vue 58 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/setting/part/Settlement.vue 104 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/supply/apply/Apply.vue 168 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/supply/apply/dialog/Edit.vue 88 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/supply/user/User.vue 205 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/supply/user/dialog/Edit.vue 92 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/supplyproject/Edit.vue 78 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/supplyproject/dialog/Edit.vue 92 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/supplyproject/index.vue 215 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/tag/Add.vue 86 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/tag/Edit.vue 85 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/release/tag/index.vue 147 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/shareholder/setting/part/Basic.vue 57 ●●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/team/setting/part/Basic.vue 32 ●●●● patch | view | raw | blame | history
shop_vue/src/views/plus/vip/grade/part/Log.vue 18 ●●●● patch | view | raw | blame | history
admin/app/api/controller/plus/release/Cart.php
New file
@@ -0,0 +1,81 @@
<?php
namespace app\api\controller\plus\repair;
use app\api\controller\Controller;
use app\api\model\plus\repair\Cart as CartModel;
use app\api\model\settings\Setting as SettingModel;
use app\api\model\product\Product as ProductModel;
/**
 * 购物车控制器
 */
class Cart extends Controller
{
    private $user;
    // $model
    private $model;
    /**
     * 构造方法
     */
    public function initialize()
    {
        $this->user = $this->getUser();
        $this->model = new CartModel();
    }
    /**
     * 购物车列表
     */
    public function lists()
    {
        // 购物车列表
        $projectList = $this->model->getList($this->user);
        //是否显示店铺信息
        $store_open = SettingModel::getStoreOpen();
        return $this->renderSuccess('', compact('projectList', 'store_open'));
    }
    /**
     * 加入购物车
     * @param int $project_id 项目id
     * @param int $project_num 数量
     */
    public function add()
    {
        $data = $this->request->param();
        $project_id = $data['project_id'];
        $project_num = $data['total_num'];
        $model = $this->model;
        if (!$model->add($this->user, $project_id, $project_num)) {
            return $this->renderError($model->getError() ?: '加入购物车失败');
        }
        // 购物车商品总数量
        $totalNum = $model->getProductNum($this->user);
        return $this->renderSuccess('加入购物车成功', ['cart_total_num' => $totalNum]);
    }
    /**
     * 减少购物车商品数量
     * @param $project_id
     * @return array
     */
    public function sub($project_id)
    {
        $this->model->sub($this->user, $project_id);
        return $this->renderSuccess('');
    }
    /**
     * 删除购物车中指定商品
     * @return array
     */
    public function delete($cart_id)
    {
        $this->model->setDelete($this->user, $cart_id);
        return $this->renderSuccess('删除成功');
    }
}
admin/app/api/controller/plus/release/Cash.php
New file
@@ -0,0 +1,78 @@
<?php
namespace app\api\controller\plus\release;
use app\api\controller\Controller;
use app\api\model\plus\release\Setting;
use app\api\model\plus\release\SupplyUser as SupplyUserModel;
use app\api\model\plus\release\Cash as CashModel;
use app\api\model\settings\Message as MessageModel;
/**
 * 提现
 */
class Cash extends Controller
{
    private $user;
    private $Release;
    private $setting;
    /**
     * 构造方法
     */
    public function initialize()
    {
        // 用户信息
        $this->user = $this->getUser();
        // 用户信息
        $this->Release = SupplyUserModel::detail($this->user['user_id']);
        // 设置
        $this->setting = Setting::getAll();
    }
    /**
     * 提现信息
     */
    public function index($platform = '')
    {
        // 如果来源是小程序, 则获取小程序订阅消息id.获取售后通知.
        $template_arr = MessageModel::getMessageByNameArr($platform, ['release_cash_user']);
        return $this->renderSuccess('', [
            // 用户信息
            'release' => $this->Release,
            // 结算设置
            'settlement' => $this->setting['settlement']['values'],
            // 小程序消息
            'template_arr' => $template_arr
        ]);
    }
    /**
     * 提交提现申请
     */
    public function submit($data)
    {
        $formData = json_decode(htmlspecialchars_decode($data), true);
        $model = new CashModel;
        if ($model->submit($this->Release, $formData)) {
            return $this->renderSuccess('申请提现成功');
        }
        return $this->renderError($model->getError() ?: '提交失败');
    }
    /**
     * 提现明细
     */
    public function lists($status = -1)
    {
        $model = new CashModel;
        return $this->renderSuccess('', [
            // 提现明细列表
            'list' => $model->getList($this->user['user_id'], (int)$status,$this->postData()),
        ]);
    }
}
admin/app/api/controller/plus/release/DemandIndex.php
New file
@@ -0,0 +1,98 @@
<?php
namespace app\api\controller\plus\release;
use app\api\controller\Controller;
use app\api\model\plus\release\DemandApply as DemandApplyModel;
use app\api\model\plus\release\DemandUser as DemandUserModel;
use app\api\model\settings\Message as MessageModel;
use app\common\exception\BaseException;
/**
 * 首页
 */
class DemandIndex extends Controller
{
    // 当前用户
    private $user;
    /**
     * 构造方法
     */
    public function initialize()
    {
        $this->user = $this->getUser();   // 用户信息
        // 需求方信息
        $this->release = DemandUserModel::detail($this->user['user_id']);
    }
    /**
     * 信息
     */
    public function index()
    {
        $is_release = $this->isReleaseUser();
        return $this->renderSuccess('', [
            'is_release' => $is_release,
            // 当前是否在申请中
            'is_applying' => DemandApplyModel::isApplying($this->user['user_id']),
            // 当前用户信息
            'user' => $this->user,
            // 信息
            'release' => $this->release,
            // 背景图
            'background' => '',
        ]);
    }
    /**
     * 当前用户是否为
     */
    private function isReleaseUser()
    {
        return !!$this->release && !$this->release['is_delete'];
    }
    /**
     * 申请状态
     */
    public function apply($platform= '')
    {
        $reason='';
        $user = $this->user;
        $applyData = (new DemandApplyModel())->getDatail($user['user_id']);
        if(!empty($applyData) && $applyData["apply_status"]["value"]==30){
            $reason = $applyData["reject_reason"];
        }
        return $this->renderSuccess('', [
            // 当前是否为
            'is_release' => $this->isReleaseUser(),
            'reason' => $reason,//被驳回的原因
            // 当前是否在申请中
            'is_applying' => DemandApplyModel::isApplying($user['user_id']),
            // 如果来源是小程序, 则获取小程序订阅消息id.获取售后通知.
            'template_arr' => MessageModel::getMessageByNameArr($platform, ['demand_apply_user']),
        ]);
    }
    /**
     * 提交申请
     */
    public function submit()
    {
        $data = $this->postData();
        if (empty($data['name']) || empty($data['mobile'])) {
            throw new BaseException(['msg' => '姓名或者手机号不能为空']);
        }
        $model = new DemandApplyModel;
        if ($model->submit($this->user, $data)) {
            return $this->renderSuccess('成功');
        }
        return $this->renderError($model->getError() ?: '提交失败');
    }
}
admin/app/api/controller/plus/release/DemandProject.php
New file
@@ -0,0 +1,122 @@
<?php
namespace app\api\controller\plus\release;
use app\api\controller\Controller;
use app\api\model\plus\release\DemandProject as ProjectModel;
use app\api\model\plus\release\DemandUser as DemandUserModel;
use app\api\model\plus\release\ReleaseCategory as ReleaseCategoryModel;
use app\common\model\plus\release\ReleaseProjectImage as ReleaseProjectImageModel;
/**
 * 项目
 */
class DemandProject extends Controller
{
     // 当前用户
    private $user;
    // 用户信息
    private $demand;
    /**
     * 构造方法
     */
    public function initialize()
    {
        // 用户信息
        $this->user = $this->getUser();
        // 用户信息
        $this->demand = DemandUserModel::detail($this->user['user_id']);
    }
    /**
     * 列表
     */
    public function index()
    {
        $postData = $this->postData();
        $model = new ProjectModel;
        $user_id = $this->demand['user_id'];
        return $this->renderSuccess('', [
            // 用户信息
            'demanduser' => $this->demand,
            // 列表
            'list' => $model->getList($user_id,$postData),
        ]);
    }
    /**
     * 默认数据
     */
    public function defaultData()
    {
        return $this->renderSuccess('', [
            'category_list' => ReleaseCategoryModel::getALL(),
        ]);
    }
    /**
     * 详情
     */
    public function detail()
    {
        $postData = $this->postData();
        $detail = ProjectModel::detail($postData["project_id"]);
        if(!empty($detail["finish_time"])){
            $detail["finish_time"] = date("Y-m-d",$detail["finish_time"]);
        }
        $detail["image_list"] = ReleaseProjectImageModel::getImage($postData["project_id"]);
        return $this->renderSuccess('', [
            'detail' => $detail,
            'category_list' => ReleaseCategoryModel::getALL(),
        ]);
    }
    /**
     * 添加
     */
    public function add()
    {
        $postData = $this->postData();
        $model = new ProjectModel;
        if ($model->add($postData,$this->demand)) {
            return $this->renderSuccess('提交成功');
        }
        return $this->renderError($model->getError() ?: '提交失败');
    }
    /**
     * 修改
     */
    public function edit()
    {
        $postData = $this->postData();
        $model = new ProjectModel;
        if(empty($this->demand)){
            return $this->renderError('信息失效,请重新登录');
        }
        // 新增记录
        if ($model->edit($postData)) {
            return $this->renderSuccess('修改成功');
        }
        return $this->renderError($model->getError() ?: '修改失败');
    }
    /**
     * 删除
     */
    public function delete()
    {
        $postData = $this->postData();
        $model= new ProjectModel();
        if ($model->setDelete($postData["project_id"])) {
            return $this->renderSuccess('删除成功');
        }
        return $this->renderError($model->getError() ?: '删除失败');
    }
}
admin/app/api/controller/plus/release/Order.php
New file
@@ -0,0 +1,154 @@
<?php
namespace app\api\controller\plus\release;
use app\api\controller\Controller;
use app\api\model\plus\release\Order as OrderModel;
use app\common\exception\BaseException;
use app\common\enum\order\OrderTypeEnum;
use app\common\enum\order\OrderPayTypeEnum;
/**
 * 订单
 */
class Order extends Controller
{
    // 当前用户
    private $user;
    /**
     * 构造方法
     */
    public function initialize()
    {
        // 用户信息
        $this->user = $this->getUser();;
    }
    /**
     * 订单列表
     */
    public function lists()
    {
        $model = new OrderModel;
        return $this->renderSuccess('', [
            // 列表
            'list' => $model->getList($this->user['user_id'],$this->postData()),
        ]);
    }
    /**
     *详情
     */
    public function detail($id)
    {
        $detail = OrderModel::detail($id);
        return $this->renderSuccess('', compact('detail'));
    }
    /**
     *提交上传
     */
    public function submit()
    {
        $params = $this->request->param();
        // 用户信息
        $user = $this->getUser();
        // 生成记录
        $model = new OrderModel();
        $id = $model->submit($user,$params);
        if (!$id) {
            return $this->renderError($model->getError() ?: '提交失败');
        }
        // 在线支付
        $payment = OrderModel::onOrderPayment($user, $model, $params['pay_type'], $params['pay_source']);
        // 返回结算信息
        return $this->renderSuccess(['success' => '支付成功', 'error' => '订单未支付'], [
            'id' => $id,   // 订单id
            'pay_type' => $params['pay_type'],  // 支付方式
            'payment' => $payment,               // 微信支付参数
            'order_type' => OrderTypeEnum::RELEASE, //订单类型
        ]);
    }
    /**
     *创建订单
     */
    public function createOrder()
    {
        $params = $this->request->param();
        // 用户信息
        $user = $this->getUser();
        // 生成记录
        $model = new OrderModel();
        $result = $model->createOrder($user,$params);
        if(!$result){
            return $this->renderError($model->getError() ?: '操作失败');
        }
        return $this->renderSuccess('操作成功');
    }
    /**
     * 订单支付
     */
    public function pay()
    {
        $params = $this->request->param();
        // 用户信息
        $user = $this->getUser();
        $model = new OrderModel();
        $detail = $model::detail($params["id"]);
        if (!$detail) {
            return $this->renderError($detail->getError() ?: '失败');
        }
        if($params["pay_type"] == OrderPayTypeEnum::BALANCE){
            (new OrderModel())->onPaymentByBalance($detail['order_no']);
        }
        // 在线支付
        $payment = OrderModel::onOrderPayment($user, $detail, $params['pay_type'], $params['pay_source']);
        // 返回结算信息
        return $this->renderSuccess(['success' => '支付成功', 'error' => '订单未支付'], [
            'id' => $detail["id"],   // 订单id
            'pay_type' => $params['pay_type'],  // 支付方式
            'payment' => $payment,               // 微信支付参数
            'order_type' => OrderTypeEnum::RELEASE, //订单类型
        ]);
    }
    /**
     *完成订单
     */
    public function finish($id)
    {
        $params = $this->request->param();
        $model = OrderModel::detail($id);
        if($model["is_settled"] == 2){
            return $this->renderError('该订单已完成');
        }
        $result = $model->finish($params);
        if(!$result){
            return $this->renderError($model->getError() ?: '操作失败');
        }
        return $this->renderSuccess('操作成功');
    }
    /**
     * 取消订单
     */
    public function cancel($id)
    {
        $model = OrderModel::detail($id);
        $user = $this->getUser();
        if ($model->cancel($user)) {
            return $this->renderSuccess('取消成功');
        }
        return $this->renderError($model->getError() ?: '取消失败');
    }
}
admin/app/api/controller/plus/release/Project.php
New file
@@ -0,0 +1,72 @@
<?php
namespace app\api\controller\plus\release;
use app\api\controller\Controller;
use app\api\model\plus\release\Project as ProjectModel;
use app\common\model\plus\release\ReleaseProjectTag as ReleaseProjectTagModel;
use app\common\model\plus\release\ReleaseCategory as ReleaseCategoryModel;
use app\common\model\plus\release\ReleaseProjectImage as ReleaseProjectImageModel;
use app\api\model\plus\release\DemandUser as DemandUserModel;
use app\api\model\plus\release\SupplyUser as SupplyUserModel;
/**
 * 项目
 */
class Project extends Controller
{
     // 当前用户
    private $user;
    /**
     * 构造方法
     */
    public function initialize()
    {
        // 用户信息
        $this->user = $this->getUser();
    }
    /**
     * 列表
     */
    public function index()
    {
        $postData = $this->postData();
        $model = new ProjectModel;
        $user_id = $this->user['user_id'];
        return $this->renderSuccess('', [
            // 列表
            'list' => $model->getList($user_id,$postData),
            'category_list' => ReleaseCategoryModel::getALL(),
        ]);
    }
    /**
     * 详情
     */
    public function detail()
    {
        $postData = $this->postData();
        $detail = ProjectModel::detail($postData["project_id"]);
        if(!empty($detail["finish_time"])){
            $detail["finish_time"] = date("Y-m-d",$detail["finish_time"]);
        }
        $detail["image_list"] = ReleaseProjectImageModel::getImage($postData["project_id"]);
        $detail["tag_list"] = ReleaseProjectTagModel::getTagName($postData["project_id"]);
        if($detail["product_type"] == 0){
            //需求项目获取其手机号
            $user = DemandUserModel::detail($detail['user_id']);
        }else{
            $user = SupplyUserModel::detail($detail['user_id']);
        }
        return $this->renderSuccess('', [
            'detail' => $detail,
            'user' => $user,
        ]);
    }
}
admin/app/api/controller/plus/release/SupplyIndex.php
New file
@@ -0,0 +1,99 @@
<?php
namespace app\api\controller\plus\release;
use app\api\controller\Controller;
use app\api\model\plus\release\SupplyApply as SupplyApplyModel;
use app\api\model\plus\release\SupplyUser as SupplyUserModel;
use app\api\model\settings\Message as MessageModel;
use app\common\exception\BaseException;
/**
 * 首页
 */
class SupplyIndex extends Controller
{
    // 当前用户
    private $user;
    /**
     * 构造方法
     */
    public function initialize()
    {
        $this->user = $this->getUser();   // 用户信息
        // 信息
        $this->release = SupplyUserModel::detail($this->user['user_id']);
    }
    /**
     * 信息
     */
    public function index()
    {
        $is_release = $this->isReleaseUser();
        return $this->renderSuccess('', [
            // 当前是否
            'is_release' => $is_release,
            // 当前是否在申请中
            'is_applying' => SupplyApplyModel::isApplying($this->user['user_id']),
            // 当前用户信息
            'user' => $this->user,
            // 信息
            'release' => $this->release,
            // 背景图
            'background' => '',
        ]);
    }
    /**
     * 当前用户是否为
     */
    private function isReleaseUser()
    {
        return !!$this->release && !$this->release['is_delete'];
    }
    /**
     * 申请状态
     */
    public function apply($platform= '')
    {
        $reason='';
        $user = $this->user;
        $applyData = (new SupplyApplyModel())->getDatail($user['user_id']);
        if(!empty($applyData) && $applyData["apply_status"]["value"]==30){
            $reason = $applyData["reject_reason"];
        }
        return $this->renderSuccess('', [
            // 当前是否为
            'is_release' => $this->isReleaseUser(),
            'reason' => $reason,//被驳回的原因
            // 当前是否在申请中
            'is_applying' => SupplyApplyModel::isApplying($user['user_id']),
            // 如果来源是小程序, 则获取小程序订阅消息id.获取售后通知.
            'template_arr' => MessageModel::getMessageByNameArr($platform, ['supply_apply_user']),
        ]);
    }
    /**
     * 提交申请
     */
    public function submit()
    {
        $data = $this->postData();
        if (empty($data['name']) || empty($data['mobile'])) {
            throw new BaseException(['msg' => '姓名或者手机号不能为空']);
        }
        $model = new SupplyApplyModel;
        if ($model->submit($this->user, $data)) {
            return $this->renderSuccess('成功');
        }
        return $this->renderError($model->getError() ?: '提交失败');
    }
}
admin/app/api/controller/plus/release/SupplyProject.php
New file
@@ -0,0 +1,130 @@
<?php
namespace app\api\controller\plus\release;
use app\api\controller\Controller;
use app\api\model\plus\release\SupplyProject as ProjectModel;
use app\api\model\plus\release\SupplyUser as SupplyUserModel;
use app\api\model\plus\release\ReleaseCategory as ReleaseCategoryModel;
use app\api\model\plus\release\Tag as TagModel;
use app\common\model\plus\release\ReleaseProjectTag as ReleaseProjectTagModel;
use app\common\model\plus\release\ReleaseProjectImage as ReleaseProjectImageModel;
/**
 * 项目
 */
class SupplyProject extends Controller
{
     // 当前用户
    private $user;
    // 用户信息
    private $supply;
    /**
     * 构造方法
     */
    public function initialize()
    {
        // 用户信息
        $this->user = $this->getUser();
        // 用户信息
        $this->supply = SupplyUserModel::detail($this->user['user_id']);
    }
    /**
     * 列表
     */
    public function index()
    {
        $postData = $this->postData();
        $model = new ProjectModel;
        $user_id = $this->supply['user_id'];
        return $this->renderSuccess('', [
            // 用户信息
            'supplyuser' => $this->supply,
            // 列表
            'list' => $model->getList($user_id,$postData),
        ]);
    }
    /**
     * 默认数据
     */
    public function defaultData()
    {
        return $this->renderSuccess('', [
            'category_list' => ReleaseCategoryModel::getALL(),
            'tag_list' => TagModel::getALL(),
        ]);
    }
    /**
     * 详情
     */
    public function detail()
    {
        $postData = $this->postData();
        $detail = ProjectModel::detail($postData["project_id"]);
        if(!empty($detail["finish_time"])){
            $detail["finish_time"] = date("Y-m-d",$detail["finish_time"]);
        }
        $detail["image_list"] = ReleaseProjectImageModel::getImage($postData["project_id"]);
        //获取某个项目的标签
        $projectTagId = ReleaseProjectTagModel::getTagId($detail["project_id"]);
        $tag_list = TagModel::getALL();
        foreach($tag_list as &$val){
            $val["checked"] = false;
            if(in_array($val["tag_id"],$projectTagId)){
                $val["checked"] = true;
            }
        }
        return $this->renderSuccess('', [
            'detail' => $detail,
            'category_list' => ReleaseCategoryModel::getALL(),
            'tag_list' => $tag_list,
        ]);
    }
    /**
     * 添加
     */
    public function add()
    {
        $postData = $this->postData();
        $model = new ProjectModel;
        if ($model->add($postData,$this->supply)) {
            return $this->renderSuccess('提交成功');
        }
        return $this->renderError($model->getError() ?: '提交失败');
    }
    /**
     * 修改
     */
    public function edit()
    {
        $postData = $this->postData();
        $model = new ProjectModel;
        // 新增记录
        if ($model->edit($postData)) {
            return $this->renderSuccess('修改成功');
        }
        return $this->renderError($model->getError() ?: '修改失败');
    }
    /**
     * 删除
     */
    public function delete()
    {
        $postData = $this->postData();
        $model= new ProjectModel();
        if ($model->setDelete($postData["project_id"])) {
            return $this->renderSuccess('删除成功');
        }
        return $this->renderError($model->getError() ?: '删除失败');
    }
}
admin/app/api/controller/product/Product.php
@@ -111,6 +111,22 @@
               $store = storeModel::detail($store_id);
            }
        }
        $cart=new CartModel();
        if ($product['spec_type']==20&&!empty($user)){
            foreach ($product['sku'] as $key => $value) {
                $cartData=$cart
                    ->when('spec_sku_id', $value['spec_sku_id'])
                    ->when('product_id', $product_id)
                    ->when('user_id', $user['user_id'])
                    ->find();
                if($cartData){
                    $product['sku'][$key]['cart'] = $cartData;
                }else{
                    $product['sku'][$key]['cart'] = ['total_num'=>0];
                }
            }
        }
        return $this->renderSuccess('', [
            // 商品详情
admin/app/api/model/order/Cart.php
@@ -241,7 +241,14 @@
            ->where('cart_id', 'in', explode(',', $cartIds))
            ->delete();
    }
    public function getCartCount($user_id, $product_id)
    {
        $cart=$this->where('user_id',$user_id)->where('product_id',$product_id)->find();
        $total_num=$this->where('user_id',$user_id)->where('product_id',$product_id)->sum('total_num');
        $cart['total_num']=$total_num;
        return $cart;
    }
    /**
     * 设置错误信息
     */
admin/app/api/model/plus/release/Cart.php
New file
@@ -0,0 +1,231 @@
<?php
namespace app\api\model\plus\repair;
use app\api\model\order\Order as OrderModel;
use think\facade\Cache;
use app\api\model\plus\repair\Project as ProjectModel;
use app\common\model\supplier\Supplier as SupplierModel;
use app\common\library\helper;
use app\common\model\plus\repair\Cart as CartModel;
/**
 * 购物车管理
 */
class Cart extends CartModel
{
    // 错误信息
    public $error = '';
    /**
     * 购物车列表 (含商品信息)
     */
    public function getList($user, $cart_ids = [])
    {
        // 获取购物车商品列表
        return $this->getOrderProjectList($user, $cart_ids);
    }
    /**
     * 获取购物车列表
     */
    public function getCartList($cartIds = null)
    {
        if (empty($cartIds)) return static::$cart;
        $cartList = [];
        $indexArr = (strpos($cartIds, ',') !== false) ? explode(',', $cartIds) : [$cartIds];
        foreach ($indexArr as $index) {
            isset(static::$cart[$index]) && $cartList[$index] = static::$cart[$index];
        }
        return $cartList;
    }
    /**
     * 获取购物车中的商品列表
     */
    public function getOrderProjectList($user, $cart_ids = [])
    {
        // 购物车列表
        $projectList = [];
        // 获取购物车列表
        $model = $this;
        if ($cart_ids) {
            $model = $model->where('cart_id', 'in', explode(',', $cart_ids));
        }
        $cartList = $model->where('user_id', '=', $user['user_id'])->select();
        if (empty($cartList)) {
            $this->setError('当前购物车没有项目');
            return $projectList;
        }
        // 购物车中所有商品id集
        $projectIds = array_unique(helper::getArrayColumn($cartList, 'project_id'));
        // 获取并格式化商品数据
        $sourceData = (new ProjectModel)->getListByIds($projectIds);
        $sourceData = helper::arrayColumn2Key($sourceData, 'project_id');
        // 供应商信息
        $supplierData = [];
        // 格式化购物车数据列表
        foreach ($cartList as $key => $item) {
            // 判断商品不存在则自动删除
            if (!isset($sourceData[$item['project_id']])) {
                $this->delete($key);
                continue;
            }
            // 项目信息
            $project = clone $sourceData[$item['project_id']];
            // 判断商品是否已删除
            if (empty($project)) {
                $this->delete($key);
                continue;
            }
            // 购买数量
            $project['total_num'] = $item['total_num'];
            // 总价
            $project['total_price'] = bcmul($project['price'], $item['total_num'], 2);
            // 总佣金
            $project['total_money'] = bcmul($project['money'], $item['total_num'], 2);
            // 供应商
            $project['shop_supplier_id'] = $item['shop_supplier_id'];
            //购物车id
            $project['cart_id'] = $item['cart_id'];
            $projectList[] = $project;
        }
        $supplierIds = array_unique(helper::getArrayColumn($projectList, 'shop_supplier_id'));
        foreach($supplierIds as $supplierId){
            $supplierData[] = [
                'shop_supplier_id' => $supplierId,
                'supplier' => SupplierModel::detail($supplierId),
                'projectList' => $this->getProjectBySupplier($supplierId, $projectList)
            ];
        }
        return $supplierData;
    }
    private function getProjectBySupplier($supplierId, $projectList)
    {
        $result = [];
        foreach ($projectList as $project){
            if($project['shop_supplier_id'] == $supplierId){
                array_push($result, $project);
            }
        }
        return $result;
    }
    /**
     * 加入购物车
     */
    public function add($user, $projectId, $projectNum)
    {
        $model = $this;
        // 获取信息
        $project = ProjectModel::detail($projectId);
        // 获取商品购物车信息
        $cartDetail = $model->where('user_id', '=', $user['user_id'])
            ->where('project_id', '=', $projectId)
            ->find();
        // 验证能否加入
        if (!$project_price = $this->checkProject($project)) {
            return false;
        }
        // 记录到购物车列表
        if ($cartDetail) {
            return $cartDetail->save(['total_num' => $cartDetail['total_num'] + $projectNum]);
        } else {
            return $this->save([
                'user_id' => $user['user_id'],
                'project_id' => $projectId,
                'total_num' => $projectNum,
                'join_price' => $project_price,
                'shop_supplier_id' => $project['shop_supplier_id'],
                'app_id' => self::$app_id,
            ]);
        }
    }
    /**
     * 验证是否可以下单
     */
    private function checkProject($project)
    {
        // 判断项目
        if (!$project) {
            $this->setError('很抱歉,信息不存在');
            return false;
        }
        return $project['price'];
    }
    /**
     * 减少购物车中某商品数量
     */
    public function sub($user, $projectId)
    {
        $cartDetail = $this->where('user_id', '=', $user['user_id'])
            ->where('project_id', '=', $projectId)
            ->find();
        if ($cartDetail['total_num'] <= 1) {
            return $cartDetail->delete();
        } else {
            $cartDetail->save(['total_num' => $cartDetail['total_num'] - 1]);
        }
    }
    /**
     * 删除购物车中指定商品
     * @param string $cartIds (支持字符串ID集)
     */
    public function setDelete($user, $cart_id)
    {
        return $this->where('user_id', '=', $user['user_id'])->where('cart_id', 'in', explode(',', $cart_id))->delete();
    }
    /**
     * 获取当前用户购物车商品总数量(含件数)
     */
    public function getTotalNum($user)
    {
        $num = $this->where('user_id', '=', $user['user_id'])->sum('total_num');
        return $num ? $num : 0;
    }
    /**
     * 获取当前用户购物车商品总数量(不含件数)
     */
    public function getProductNum($user)
    {
        return $this->where('user_id', '=', $user['user_id'])->count();
    }
    /**
     * 清空当前用户购物车
     */
    public function clearAll($user, $cartIds)
    {
        return $this->where('user_id', '=', $user['user_id'])
            ->where('cart_id', 'in', explode(',', $cartIds))
            ->delete();
    }
    /**
     * 设置错误信息
     */
    private function setError($error)
    {
        empty($this->error) && $this->error = $error;
    }
    /**
     * 获取错误信息
     */
    public function getError()
    {
        return $this->error;
    }
}
admin/app/api/model/plus/release/Cash.php
New file
@@ -0,0 +1,92 @@
<?php
namespace app\api\model\plus\release;
use app\common\exception\BaseException;
use app\common\model\plus\release\Cash as CashModel;
use app\api\model\user\UserAuth;
/**
 * 提现明细模型
 */
class Cash extends CashModel
{
    /**
     * 隐藏字段
     */
    protected $hidden = [
        'update_time',
    ];
    /**
     * 获取提现明细
     */
    public function getList($user_id, $apply_status = -1,$limit=15)
    {
        $model = $this;
        $apply_status > -1 && $model = $model->where('apply_status', '=', $apply_status);
        return $model->where('user_id', '=', $user_id)->order(['create_time' => 'desc'])
            ->paginate($limit);
    }
    /**
     * 提交申请
     */
    public function submit($release, $data)
    {
        // 数据验证
        $this->validation($release, $data);
        // 新增申请记录
        $this->save(array_merge($data, [
            'user_id' => $release['user_id'],
            'apply_status' => 10,
            'app_id' => self::$app_id,
        ]));
        // 冻结用户资金
        $release->freezeMoney($data['money']);
        return true;
    }
    /**
     * 数据验证
     */
    private function validation($release, $data)
    {
        // 结算设置
        $settlement = Setting::getItem('settlement');
        // 最低提现佣金
        if ($data['money'] <= 0) {
            throw new BaseException(['msg' => '提现金额不正确']);
        }
        if ($release['money'] <= 0) {
            throw new BaseException(['msg' => '当前用户没有可提现佣金']);
        }
        if ($data['money'] > $release['money']) {
            throw new BaseException(['msg' => '提现金额不能大于可提现佣金']);
        }
        if ($data['money'] < $settlement['min_money']) {
            throw new BaseException(['msg' => '最低提现金额为' . $settlement['min_money']]);
        }
        if (!in_array($data['pay_type'], $settlement['pay_type'])) {
            throw new BaseException(['msg' => '提现方式不正确']);
        }
        if ($data['pay_type'] == '20') {
            if (empty($data['alipay_name']) || empty($data['alipay_account'])) {
                throw new BaseException(['msg' => '请补全提现信息']);
            }
        } elseif ($data['pay_type'] == '30') {
            if (empty($data['bank_name']) || empty($data['bank_account']) || empty($data['bank_card'])) {
                throw new BaseException(['msg' => '请补全提现信息']);
            }
        } elseif ($data['pay_type'] == '10') {
            //微信支付需要实名认证
            $auth = UserAuth::detail($release['user_id']);
            if(empty($auth)){
                throw new BaseException(['msg' => '请先到个人中心->设置->实名认证']);
            }elseif(!empty($auth) && $auth["auth_status"] != 1){
                throw new BaseException(['msg' => '您的实名认证还未审核通过']);
            }
        }
    }
}
admin/app/api/model/plus/release/DemandApply.php
New file
@@ -0,0 +1,86 @@
<?php
namespace app\api\model\plus\release;
use app\common\model\plus\release\DemandApply as ApplyModel;
/**
 * 申请模型
 */
class DemandApply extends ApplyModel
{
    /**
     * 隐藏字段
     * @var array
     */
    protected $hidden = [
        'create_time',
        'update_time',
    ];
    /**
     * 是否为申请中
     */
    public static function isApplying($user_id)
    {
        $detail = self::detail(['user_id' => $user_id]);
        return $detail ? ((int)$detail['apply_status']['value'] === 10) : false;
    }
    /**
     * 获取最新的一条申请数据
     */
    public function getDatail($user_id)
    {
        $detail = $this->where(['user_id' => $user_id])->order("create_time desc")->find();
        return $detail;
    }
    /**
     * 提交申请
     */
    public function submit($user, $data)
    {
        // 数据整理
        $data = [
            'user_id' => $user['user_id'],
            'real_name' => trim($data['name']),
            'mobile' => trim($data['mobile']),
            // 'province_id' => trim($data['province_id']),
            // 'city_id' => trim($data['city_id']),
            // 'region_id' => trim($data['region_id']),
            // 'location_address' => $data['location_address'],
            // 'longitude' => $data['longitude'],
            // 'latitude' => $data['latitude'],
            // 'detail' => $data['detail'],
            'apply_type' => 10,
            'apply_status' => 10,
            'apply_time' => time(),
            'app_id' => self::$app_id,
        ];
        return $this->add($user, $data);
    }
    /**
     * 更新申请信息
     */
    private function add($user, $data)
    {
        // 实例化模型
        $model = self::detail(['user_id' => $user['user_id']]) ?: $this;
        // 更新记录
        $this->startTrans();
        try {
            // 保存申请信息
            $model->save($data);
            $this->commit();
            return true;
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            $this->rollback();
            return false;
        }
    }
}
admin/app/api/model/plus/release/DemandProject.php
New file
@@ -0,0 +1,157 @@
<?php
namespace app\api\model\plus\release;
use app\common\model\plus\release\Project as ProjectModel;
use app\common\model\plus\release\ReleaseProjectImage as ReleaseProjectImageModel;
/**
 * 模型
 */
class DemandProject extends ProjectModel
{
    /**
     * 获取提现明细
     */
    public function getList($user_id, $postdata)
    {
        $model = $this;
        if(!empty($postdata["keyword"])){
            $model = $model->where('name', 'like', '%'.$postdata["keyword"].'%');
        }
        return $model->where('is_delete', '=', 0)
            ->where('project_type', '=', 0)
            ->where('user_id', '=', $user_id)
            ->order(['create_time' => 'desc'])
            ->paginate($postdata);
    }
    /**
     * 新增记录
     */
    public function add($postdata,$demand)
    {
        $data = json_decode($postdata["formData"],true);
        if (empty($data['name'])) {
                $this->error = '请输入标题';
                return false;
         }
        if (empty($data['category_id'])) {
                $this->error = '请选择分类';
                return false;
         }
        if (empty($data['price'])) {
                $this->error = '请输入您的预算';
                return false;
        }
       if (empty($data['content'])) {
                $this->error = '请输入您的详细需求';
                return false;
        }
        $save_data =[
            'user_id'=>$demand["user_id"],
            'name'=>$data["name"],
            'category_id'=>$data["category_id"],
            'price'=>$data["price"],
            'content'=>$data["content"],
            'detail'=>$data["detail"],
            'show_phone'=>$data["show_phone"],
            'is_show'=>$data["is_show"],
            'app_id'=>self::$app_id,
        ];
        if(!empty($data["finish_time"]) && $data["finish_time"] != '请选择日期'){
            $save_data["finish_time"] = strtotime($data["finish_time"]);
        }else{
            $save_data["finish_time"] = '';
        }
          return $this->transaction(function () use ($data, $save_data) {
            // 记录内容
            $this->save($save_data);
            // 记录图片
            $this->saveAllImages($this['project_id'],$data);
            return $this['project_id'];
        });
    }
    /**
     * 更新记录
     */
    public function edit($postdata)
    {
        $data = json_decode($postdata["formData"],true);
        if (empty($data['name'])) {
                $this->error = '请输入标题';
                return false;
         }
        if (empty($data['category_id'])) {
                $this->error = '请选择分类';
                return false;
         }
        if (empty($data['price'])) {
                $this->error = '请输入您的预算';
                return false;
        }
       if (empty($data['content'])) {
                $this->error = '请输入您的详细需求';
                return false;
        }
         $save_data =[
            'name'=>$data["name"],
            'category_id'=>$data["category_id"],
            'price'=>$data["price"],
            'content'=>$data["content"],
            'detail'=>$data["detail"],
            'show_phone'=>$data["show_phone"],
            'is_show'=>$data["is_show"],
            'status'=>0,
        ];
        if(!empty($data["finish_time"]) && $data["finish_time"] != '请选择日期'){
            $save_data["finish_time"] = strtotime($data["finish_time"]);
        }else{
            $save_data["finish_time"] = '';
        }
        return $this->transaction(function () use ($data, $save_data) {
            // 记录内容
            $this->where("project_id","=",$data["project_id"])->save($save_data);
            // 记录图片
            $this->saveAllImages($data["project_id"],$data);
            return true;
        });
    }
     /**
     * 记录图片
     */
    private function saveAllImages($id,$formData)
    {
        (new ReleaseProjectImageModel())->where("project_id","=",$id)->delete();
        // 生成图片数据
        if(!empty($formData['image_list'])){
            $imageData = [];
            foreach ($formData['image_list'] as $imageId) {
                $imageData[] = [
                    'project_id' => $id,
                    'image_id' => !empty($imageId['image_id']) ? $imageId['image_id'] : $imageId['file_id'],
                    'app_id' => self::$app_id
                ];
            }
            $model = new ReleaseProjectImageModel;
            return !empty($imageData) && $model->saveAll($imageData);
        }
        return true;
    }
    /**
     * 软删除
     */
    public function setDelete($id)
    {
        return $this->where("project_id","=",$id)->save(['is_delete' => 1]);
    }
}
admin/app/api/model/plus/release/DemandUser.php
New file
@@ -0,0 +1,31 @@
<?php
namespace app\api\model\plus\release;
use app\common\model\plus\release\DemandUser as UserModel;
/**
 * 用户模型
 */
class DemandUser extends UserModel
{
    /**
     * 隐藏字段
     */
    protected $hidden = [
        'create_time',
        'update_time',
    ];
    /**
     * 资金冻结
     */
    public function freezeMoney($money)
    {
        return $this->save([
            'money' => $this['money'] - $money,
            'freeze_money' => $this['freeze_money'] + $money,
        ]);
    }
}
admin/app/api/model/plus/release/Order.php
New file
@@ -0,0 +1,275 @@
<?php
namespace app\api\model\plus\release;
use app\api\service\order\PaymentService;
use app\common\enum\order\OrderTypeEnum;
use app\common\model\plus\release\Order as OrderModel;
use app\common\model\plus\release\Project as ProjectModel;
use app\common\model\plus\release\DemandUser as DemandUserModel;
use app\common\exception\BaseException;
use app\common\enum\order\OrderPayTypeEnum;
use app\api\service\order\paysuccess\type\ReleasePaySuccessService;
use app\common\service\order\OrderService;
use app\common\model\plus\release\SupplyUser as SupplyUserModel;
use app\api\model\plus\release\Setting;
/**
 * 订单模型
 */
class Order extends OrderModel
{
    /**
     * 隐藏字段
     */
    protected $hidden = [
        'update_time',
    ];
    /**
     * 获取用户订单列表
     */
    public function getList($user_id,$postData =[])
    {
        $model = $this;
        if(!empty($postData["state_active"])){
            if($postData["state_active"] == 10){
                //未支付,确认订单
                $model = $model->where('pay_status', '=', 10);
            }else if ($postData["state_active"] == 20){
                //已付款,进行中
                $model = $model->where('order_status', '=', 10)->where('pay_status', '=', 20);
            }else if ($postData["state_active"] == 30){
                //已完成
                $model = $model->where('order_status', '=', 30);
            }else if ($postData["state_active"] == 40){
                //已取消
                $model = $model->where('order_status', '=', 20);
            }
        }
        if(!empty($postData["keyword"])){
            $model = $model->where('project_name', 'like', '%' . trim($postData["keyword"]) . '%');
        }
        if(empty($postData["product_type"])){
            //获取需求订单
            $model = $model->where('demand_user_id', '=', $user_id);
        }else{
            //获取服务订单
            $model = $model->where('supply_user_id', '=', $user_id);
        }
        $data = $model->with(['demanduser','supplyuser','project'])
            ->order(['create_time' => 'desc'])
            ->paginate($postData);
        return $data;
    }
    /**
     * 详情
     */
    public static function detail($id)
    {
        if (!$model = parent::detail($id)) {
            throw new BaseException(['msg' => '信息不存在']);
        }
        return $model;
    }
    /**
     * 提交
     */
    public function submit($user,$params)
    {
        $project_id=$params["project_id"];
        $pay_type = $params["pay_type"];
        //获取项目信息
        $project = ProjectModel::detail($project_id);
        $order_price = $project["price"];
        //获取抽成比例
        $settlement = Setting::getItem('settlement');
        $order_rate = empty($settlement["order_rate"]) ? 0 : $settlement["order_rate"]/100;
        $order_money = $project["price"];
        if($order_rate > 0){
            $order_money = $order_money - $order_money*$order_rate;
        }
        $project_type = $project["project_type"];//项目类型
        if ($order_price == 0) {
            $pay_type = OrderPayTypeEnum::BALANCE;
        }
        if($project["user_id"] == $user["user_id"]){
            $this->error = '创建失败';
            return false;
        }
        if ($pay_type == OrderPayTypeEnum::BALANCE && $user['balance'] < $order_price) {
            $this->error = '用户余额不足,无法使用余额支付';
            return false;
        }
        $data = [
            'demand_user_id' => empty($project["product_type"]) ? $project["user_id"] : $user["user_id"],
            'supply_user_id' => !empty($project["product_type"]) ? $project["user_id"] : $user["user_id"],
            'order_price' => $order_price,
            'pay_price' => $order_price,
            'pay_type' => $pay_type,
            'project_id' => $project["project_id"],
            'project_name' => $project["name"],
            'project_type' => $project_type,
            'money' => floor($order_money*100)/100,
            'order_no' => $this->orderNo(),
            'app_id' => self::$app_id
        ];
        return $this->transaction(function () use ($data) {
            // 记录内容
            $this->save($data);
            // 余额支付标记订单已支付
            if ($data['pay_type'] == OrderPayTypeEnum::BALANCE) {
                $this->onPaymentByBalance($data['order_no']);
            }
            return $this['id'];
        });
    }
    /**
     * 生成订单号
     */
    public function orderNo()
    {
        return OrderService::createOrderNo();
    }
    /**
     * 余额支付标记订单已支付
     */
    public function onPaymentByBalance($orderNo)
    {
        // 获取订单详情
        $PaySuccess = new ReleasePaySuccessService($orderNo);
        // 发起余额支付
        return $PaySuccess->onPaySuccess(OrderPayTypeEnum::BALANCE);
    }
    /**
     * 构建支付请求的参数
     */
    public static function onOrderPayment($user, $order, $payType, $pay_source)
    {
        //如果来源是h5,首次不处理,payH5再处理
        if ($pay_source == 'h5') {
            return [];
        }
        if ($payType == OrderPayTypeEnum::WECHAT) {
            return self::onPaymentByWechat($user, $order, $pay_source);
        }
        return [];
    }
    /**
     * 构建微信支付请求
     */
    protected static function onPaymentByWechat($user, $order, $pay_source)
    {
        return PaymentService::wechat(
            $user,
            $order["order_no"],
            OrderTypeEnum::RELEASE,
            $pay_source,
            $order["pay_price"],
            0,
        );
    }
    /**
     * 供应方创建订单,不需要支付
     */
    public function createOrder($user,$params)
    {
        $project_id=$params["project_id"];
        $pay_type = 10;
        //获取项目信息
        $project = ProjectModel::detail($project_id);
        $order_price = $project["price"];
        //获取抽成比例
        $settlement = Setting::getItem('settlement');
        $order_rate = empty($settlement["order_rate"]) ? 0 : $settlement["order_rate"]/100;
        $order_money = $project["price"];
        if($order_rate > 0){
            $order_money = $order_money - $order_money*$order_rate;
        }
        $project_type = $project["project_type"];//项目类型
        if($project["user_id"] == $user["user_id"]){
            $this->error = '创建失败';
            return false;
        }
        $data = [
            'demand_user_id' => empty($project["product_type"]) ? $project["user_id"] : $user["user_id"],
            'supply_user_id' => !empty($project["product_type"]) ? $project["user_id"] : $user["user_id"],
            'order_price' => $order_price,
            'pay_price' => $order_price,
            'pay_type' => $pay_type,
            'project_id' => $project["project_id"],
            'project_name' => $project["name"],
            'project_type' => $project_type,
            'money' => floor($order_money*100)/100,
            'order_no' => $this->orderNo(),
            'app_id' => self::$app_id
        ];
        return $this->save($data);
    }
    /**
     * 完成
     */
    public function finish($params)
    {
        return $this->transaction(function () use ($params) {
            //给供应方发放金钱
            (new SupplyUserModel())->where("user_id","=",$this["supply_user_id"])->inc("money",$this["money"])->update();
            $data["order_status"] = 30;
            $data["evaluate_content"] = $params["evaluate_content"];
            $data["server_score"] = $params["server_score"];
            $data["score"] = empty($params["score"]) ? 10 : $params["score"];
            $data["finish_time"] = time();
            return $this->save($data);
        });
    }
    /**
     * 取消订单
     */
    public function cancel($user)
    {
        if ($this['order_status'] == 30) {
            $this->error = '已完成不可取消';
            return false;
        }
        //订单不能取消
        if($this['order_status'] != 10){
            $this->error = '该订单已取消';
            return false;
        }
        // 订单取消事件
        return $this->transaction(function () use ($user) {
            // 订单是否已支付
            $isPay = $this['pay_status'] == 20;
            // 更新订单状态
            return $this->save(['order_status' => $isPay ? 21 : 20]);
        });
    }
}
admin/app/api/model/plus/release/Project.php
New file
@@ -0,0 +1,34 @@
<?php
namespace app\api\model\plus\release;
use app\common\model\plus\release\Project as ProjectModel;
/**
 * 模型
 */
class Project extends ProjectModel
{
    /**
     * 获取提现明细
     */
    public function getList($user_id, $postdata)
    {
        $model = $this;
        if(!empty($postdata["keyword"])){
            $model = $model->where('name', 'like', '%'.$postdata["keyword"].'%');
        }
        if(!empty($postdata["category_id"])){
            $model = $model->where('category_id', '=', $postdata["category_id"]);
        }
        return $model->with(['category','user'])->where('is_delete', '=', 0)
            ->where('project_type', '=', $postdata["product_type"])
            ->where('status', '=', 1)
            ->where('is_show', '=', 1)
            ->where('user_id', '<>', $user_id)
            ->order(['create_time' => 'desc'])
            ->paginate($postdata);
    }
}
admin/app/api/model/plus/release/ReleaseCategory.php
New file
@@ -0,0 +1,20 @@
<?php
namespace app\api\model\plus\release;
use app\common\model\plus\release\ReleaseCategory as ReleaseCategoryModel;
/**
 * 分类模型
 */
class ReleaseCategory extends ReleaseCategoryModel
{
    /**
     * 隐藏字段
     */
    protected $hidden = [
        'app_id',
        'update_time'
    ];
}
admin/app/api/model/plus/release/Setting.php
New file
@@ -0,0 +1,19 @@
<?php
namespace app\api\model\plus\release;
use app\common\model\plus\release\Setting as SettingModel;
/**
 * 设置模型
 */
class Setting extends SettingModel
{
    /**
     * 隐藏字段
     */
    protected $hidden = [
        'update_time',
    ];
}
admin/app/api/model/plus/release/SupplyApply.php
New file
@@ -0,0 +1,86 @@
<?php
namespace app\api\model\plus\release;
use app\common\model\plus\release\SupplyApply as ApplyModel;
/**
 * 申请模型
 */
class SupplyApply extends ApplyModel
{
    /**
     * 隐藏字段
     * @var array
     */
    protected $hidden = [
        'create_time',
        'update_time',
    ];
    /**
     * 是否为申请中
     */
    public static function isApplying($user_id)
    {
        $detail = self::detail(['user_id' => $user_id]);
        return $detail ? ((int)$detail['apply_status']['value'] === 10) : false;
    }
    /**
     * 获取最新的一条申请数据
     */
    public function getDatail($user_id)
    {
        $detail = $this->where(['user_id' => $user_id])->order("create_time desc")->find();
        return $detail;
    }
    /**
     * 提交申请
     */
    public function submit($user, $data)
    {
        // 数据整理
        $data = [
            'user_id' => $user['user_id'],
            'real_name' => trim($data['name']),
            'mobile' => trim($data['mobile']),
            // 'province_id' => trim($data['province_id']),
            // 'city_id' => trim($data['city_id']),
            // 'region_id' => trim($data['region_id']),
            // 'location_address' => $data['location_address'],
            // 'longitude' => $data['longitude'],
            // 'latitude' => $data['latitude'],
            // 'detail' => $data['detail'],
            'apply_type' => 10,
            'apply_status' => 10,
            'apply_time' => time(),
            'app_id' => self::$app_id,
        ];
        return $this->add($user, $data);
    }
    /**
     * 更新申请信息
     */
    private function add($user, $data)
    {
        // 实例化模型
        $model = self::detail(['user_id' => $user['user_id']]) ?: $this;
        // 更新记录
        $this->startTrans();
        try {
            // 保存申请信息
            $model->save($data);
            $this->commit();
            return true;
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            $this->rollback();
            return false;
        }
    }
}
admin/app/api/model/plus/release/SupplyProject.php
New file
@@ -0,0 +1,186 @@
<?php
namespace app\api\model\plus\release;
use app\common\model\plus\release\Project as ProjectModel;
use app\common\model\plus\release\ReleaseProjectImage as ReleaseProjectImageModel;
use app\common\model\plus\release\Tag as TagModel;
use app\common\model\plus\release\ReleaseProjectTag as ReleaseProjectTagModel;
/**
 * 模型
 */
class SupplyProject extends ProjectModel
{
    /**
     * 获取提现明细
     */
    public function getList($user_id, $postdata)
    {
        $model = $this;
        if(!empty($postdata["keyword"])){
            $model = $model->where('name', 'like', '%'.$postdata["keyword"].'%');
        }
        return $model->where('is_delete', '=', 0)
            ->where('project_type', '=', 1)
            ->where('user_id', '=', $user_id)
            ->order(['create_time' => 'desc'])
            ->paginate($postdata);
    }
    /**
     * 新增记录
     */
    public function add($postdata,$supply)
    {
        $data = json_decode($postdata["formData"],true);
        if (empty($data['name'])) {
                $this->error = '请输入标题';
                return false;
         }
        if (empty($data['category_id'])) {
                $this->error = '请选择分类';
                return false;
         }
        if (empty($data['price'])) {
                $this->error = '请输入您的价格';
                return false;
        }
       if (empty($data['content'])) {
                $this->error = '请输入您的详细描述';
                return false;
        }
        $save_data =[
            'user_id'=>$supply["user_id"],
            'name'=>$data["name"],
            'category_id'=>$data["category_id"],
            'price'=>$data["price"],
            'content'=>$data["content"],
            'detail'=>$data["detail"],
            'project_type'=>1,
            'is_show'=>$data["is_show"],
            'app_id'=>self::$app_id,
        ];
        if(!empty($data["finish_time"]) && $data["finish_time"] != '请选择日期'){
            $save_data["finish_time"] = strtotime($data["finish_time"]);
        }else{
            $save_data["finish_time"] = '';
        }
          return $this->transaction(function () use ($data, $save_data) {
            // 记录内容
            $this->save($save_data);
            // 记录图片
            $this->saveAllImages($this['project_id'],$data);
            // 记录标签
            $this->saveTag($this['project_id'],$data);
            return $this['project_id'];
        });
    }
    /**
     * 更新记录
     */
    public function edit($postdata)
    {
        $data = json_decode($postdata["formData"],true);
        if (empty($data['name'])) {
                $this->error = '请输入标题';
                return false;
         }
        if (empty($data['category_id'])) {
                $this->error = '请选择分类';
                return false;
         }
        if (empty($data['price'])) {
                $this->error = '请输入您的价格';
                return false;
        }
       if (empty($data['content'])) {
                $this->error = '请输入您的详细描述';
                return false;
        }
         $save_data =[
            'name'=>$data["name"],
            'category_id'=>$data["category_id"],
            'price'=>$data["price"],
            'content'=>$data["content"],
            'detail'=>$data["detail"],
            'is_show'=>$data["is_show"],
            'status'=>0,
        ];
        if(!empty($data["finish_time"]) && $data["finish_time"] != '请选择日期'){
            $save_data["finish_time"] = strtotime($data["finish_time"]);
        }else{
            $save_data["finish_time"] = '';
        }
        return $this->transaction(function () use ($data, $save_data) {
            // 记录内容
            $this->where("project_id","=",$data["project_id"])->save($save_data);
            // 记录图片
            $this->saveAllImages($data['project_id'],$data);
            // 记录标签
            $this->saveTag($data['project_id'],$data);
            return true;
        });
    }
     /**
     * 记录图片
     */
    private function saveAllImages($id,$formData)
    {
        (new ReleaseProjectImageModel())->where("project_id","=",$id)->delete();
        // 生成图片数据
        if(!empty($formData['image_list'])){
            $imageData = [];
            foreach ($formData['image_list'] as $imageId) {
                $imageData[] = [
                    'project_id' => $id,
                    'image_id' => !empty($imageId['image_id']) ? $imageId['image_id'] : $imageId['file_id'],
                    'app_id' => self::$app_id
                ];
            }
            $model = new ReleaseProjectImageModel;
            return !empty($imageData) && $model->saveAll($imageData);
        }
        return true;
    }
    /**
     * 记录标签
     */
    private function saveTag($id,$formData)
    {
        (new ReleaseProjectTagModel())->where("project_id","=",$id)->delete();
        // 生成数据
        if(!empty($formData['tag_list'])){
            $tagData = [];
            foreach ($formData['tag_list'] as $val) {
                $tagData[] = [
                    'project_id' => $id,
                    'tag_id' => $val,
                    'app_id' => self::$app_id
                ];
            }
            $model = new ReleaseProjectTagModel;
            return !empty($tagData) && $model->saveAll($tagData);
        }
        return true;
    }
    /**
     * 软删除
     */
    public function setDelete($id)
    {
        return $this->where("project_id","=",$id)->save(['is_delete' => 1]);
    }
}
admin/app/api/model/plus/release/SupplyUser.php
New file
@@ -0,0 +1,31 @@
<?php
namespace app\api\model\plus\release;
use app\common\model\plus\release\SupplyUser as UserModel;
/**
 * 用户模型
 */
class SupplyUser extends UserModel
{
    /**
     * 隐藏字段
     */
    protected $hidden = [
        'create_time',
        'update_time',
    ];
    /**
     * 资金冻结
     */
    public function freezeMoney($money)
    {
        return $this->save([
            'money' => $this['money'] - $money,
            'freeze_money' => $this['freeze_money'] + $money,
        ]);
    }
}
admin/app/api/model/plus/release/Tag.php
New file
@@ -0,0 +1,20 @@
<?php
namespace app\api\model\plus\release;
use app\common\model\plus\release\Tag as TagModel;
/**
 * 模型
 */
class Tag extends TagModel
{
   /**
     * 列表
     */
    public function getList()
    {
    }
}
admin/app/api/model/plus/team/Cash.php
@@ -1 +1,153 @@
<?phpnamespace app\api\model\plus\team;use app\common\exception\BaseException;use app\common\model\plus\team\Cash as CashModel;use app\common\model\order\Order as OrderModel;use app\common\model\plus\agent\User as AgentUserModel;use app\api\model\user\UserAuth;/** * 队长提现明细模型 */class Cash extends CashModel{    /**     * 隐藏字段     */    protected $hidden = [        'update_time',    ];    /**     * 获取队长提现明细     */    public function getList($user_id, $apply_status = -1,$limit=15)    {        $model = $this;        $apply_status > -1 && $model = $model->where('apply_status', '=', $apply_status);        return $model->where('user_id', '=', $user_id)->order(['create_time' => 'desc'])            ->paginate($limit);    }    /**     * 提交申请     */    public function submit($team, $data)    {        // 数据验证        $this->validation($team, $data);        // 新增申请记录        $this->save(array_merge($data, [            'user_id' => $team['user_id'],            'apply_status' => 10,            'app_id' => self::$app_id,        ]));        // 冻结用户资金        $team->freezeMoney($data['money']);        return true;    }    /**     * 数据验证     */    private function validation($team, &$data)    {        // 结算设置        $settlement = Setting::getItem('settlement');        // 最低提现佣金        if ($data['money'] <= 0) {            throw new BaseException(['msg' => '提现金额不正确']);        }        if ($team['money'] <= 0) {            throw new BaseException(['msg' => '当前用户没有可提现佣金']);        }        if ($data['money'] > $team['money']) {            throw new BaseException(['msg' => '提现金额不能大于可提现佣金']);        }        if ($data['money'] < $settlement['min_money']) {            throw new BaseException(['msg' => '最低提现金额为' . $settlement['min_money']]);        }        if (!in_array($data['pay_type'], $settlement['pay_type'])) {            throw new BaseException(['msg' => '提现方式不正确']);        }        if ($data['pay_type'] == '20') {            if (empty($data['alipay_name']) || empty($data['alipay_account'])) {                throw new BaseException(['msg' => '请补全提现信息']);            }        } elseif ($data['pay_type'] == '30') {            if (empty($data['bank_name']) || empty($data['bank_account']) || empty($data['bank_card'])) {                throw new BaseException(['msg' => '请补全提现信息']);            }        } elseif ($data['pay_type'] == '10') {            //微信支付需要实名认证            $auth = UserAuth::detail($team['user_id']);            if(empty($auth)){                throw new BaseException(['msg' => '请先到个人中心->设置->实名认证']);            }elseif(!empty($auth) && $auth["auth_status"] != 1){                throw new BaseException(['msg' => '您的实名认证还未审核通过']);            }        }        // 处理手续费        $data['fee_rate'] = $settlement['fee_rate'];        if ($settlement['fee_rate']) {            $data['fee_money'] = round($data['money'] * $settlement['fee_rate'] / 100, 2);            $data['real_money'] = $data['money'] - $data['fee_money'];        } else {            $data['real_money'] = $data['money'];        }        // 提现条件 by lyzflash        $this->checkCondition($team);    }    /**     * 提现条件     */    private function checkCondition($team)    {        if ($team['grade']['cash_condition'] == 10) {            return true;        }        $start_time = date('Y-m-01 00:00:00', time());//月头日期时间        $end_time = date('Y-m-t 23:59:59', time());//月末日期时间        // 获取本月新增的直推        $agent_model = new AgentUserModel;        $new_agent = $agent_model->where('referee_id', '=', $team['user_id'])            ->where('create_time', '>=', $start_time)            ->where('create_time', '<=', $end_time)            ->where('is_delete', '=', 0)            ->column('user_id');        $user_ids = array_merge([$team['user_id']], $new_agent);        $order_model = new OrderModel;        $order_model = $order_model->where('user_id', 'IN', $user_ids)            ->where('create_time', '>=', $start_time)            ->where('create_time', '<=', $end_time)            ->where('order_status', '=', 30);        // 按当月自购 + 新增直推订单数        if ($team['grade']['cash_condition'] == 20 && $order_model->count() < $team['grade']['cash_order_num']) {            throw new BaseException(['msg' => '您需要自购订单或直推订单数满' . $team['grade']['cash_order_num'] . '单才能提现']);        }        // 按当月自购 + 新增直推订单金额        if ($team['grade']['cash_condition'] == 30 && $order_model->sum('total_price') < $team['grade']['cash_order_money']) {            throw new BaseException(['msg' => '您需要自购订单或直推订单金额满' . $team['grade']['cash_order_num'] . '元才能提现']);        }    }}
<?php
namespace app\api\model\plus\team;
use app\common\exception\BaseException;
use app\common\model\plus\team\Cash as CashModel;
use app\common\model\order\Order as OrderModel;
use app\common\model\plus\agent\User as AgentUserModel;
use app\api\model\user\UserAuth;
/**
 * 队长提现明细模型
 */
class Cash extends CashModel
{
    /**
     * 隐藏字段
     */
    protected $hidden = [
        'update_time',
    ];
    /**
     * 获取队长提现明细
     */
    public function getList($user_id, $apply_status = -1, $limit = 15)
    {
        $model = $this;
        $apply_status > -1 && $model = $model->where('apply_status', '=', $apply_status);
        return $model->where('user_id', '=', $user_id)
            ->order(['create_time' => 'desc'])
            ->paginate($limit);
    }
    /**
     * 提交申请
     */
    public function submit($team, $data)
    {
        // 数据验证
        $this->validation($team, $data);
        // 新增申请记录
        $this->save(array_merge($data, [
            'user_id' => $team['user_id'],
            'apply_status' => 10,
            'app_id' => self::$app_id,
        ]));
        // 冻结用户资金
        $team->freezeMoney($data['money']);
        return true;
    }
    /**
     * 数据验证
     */
    private function validation($team, &$data)
    {
        // 结算设置
        $settlement = Setting::getItem('settlement');
        // 最低提现佣金
        if ($data['money'] <= 0) {
            throw new BaseException(['msg' => '提现金额不正确']);
        }
        if ($team['money'] <= 0) {
            throw new BaseException(['msg' => '当前用户没有可提现佣金']);
        }
        if ($data['money'] > $team['money']) {
            throw new BaseException(['msg' => '提现金额不能大于可提现佣金']);
        }
        if ($data['money'] < $settlement['min_money']) {
            throw new BaseException(['msg' => '最低提现金额为' . $settlement['min_money']]);
        }
        if (!in_array($data['pay_type'], $settlement['pay_type'])) {
            throw new BaseException(['msg' => '提现方式不正确']);
        }
        if ($data['pay_type'] == '20') {
            if (empty($data['alipay_name']) || empty($data['alipay_account'])) {
                throw new BaseException(['msg' => '请补全提现信息']);
            }
        } elseif ($data['pay_type'] == '30') {
            if (empty($data['bank_name']) || empty($data['bank_account']) || empty($data['bank_card'])) {
                throw new BaseException(['msg' => '请补全提现信息']);
            }
        } elseif ($data['pay_type'] == '10') {
            // 微信支付需要实名认证
            $auth = UserAuth::detail($team['user_id']);
            if (empty($auth)) {
                throw new BaseException(['msg' => '请先到个人中心->设置->实名认证']);
            } elseif (!empty($auth) && $auth["auth_status"] != 1) {
                throw new BaseException(['msg' => '您的实名认证还未审核通过']);
            }
        }
        // 处理手续费
        $data['fee_rate'] = $settlement['fee_rate'];
        if ($settlement['fee_rate']) {
            $data['fee_money'] = round($data['money'] * $settlement['fee_rate'] / 100, 2);
            $data['real_money'] = $data['money'] - $data['fee_money'];
        } else {
            $data['real_money'] = $data['money'];
        }
        // 提现条件 by lyzflash
        $this->checkCondition($team);
    }
    /**
     * 提现条件
     */
    private function checkCondition($team)
    {
        if ($team['grade']['cash_condition'] == 10) {
            return true;
        }
        $start_time = date('Y-m-01 00:00:00', time()); // 月头日期时间
        $end_time = date('Y-m-t 23:59:59', time()); // 月末日期时间
        // 获取本月新增的直推
        $agent_model = new AgentUserModel;
        $new_agent = $agent_model->where('referee_id', '=', $team['user_id'])
            ->where('create_time', '>=', $start_time)
            ->where('create_time', '<=', $end_time)
            ->where('is_delete', '=', 0)
            ->column('user_id');
        $user_ids = array_merge([$team['user_id']], $new_agent);
        $order_model = new OrderModel;
        $order_model = $order_model->where('user_id', 'IN', $user_ids)
            ->where('create_time', '>=', $start_time)
            ->where('create_time', '<=', $end_time)
            ->where('order_status', '=', 30);
        // 按当月自购 + 新增直推订单数
        if ($team['grade']['cash_condition'] == 20 && $order_model->count() < $team['grade']['cash_order_num']) {
            throw new BaseException(['msg' => '您需要自购订单或直推订单数满' . $team['grade']['cash_order_num'] . '单才能提现']);
        }
        // 按当月自购 + 新增直推订单金额
        if ($team['grade']['cash_condition'] == 30 && $order_model->sum('total_price') < $team['grade']['cash_order_money']) {
            throw new BaseException(['msg' => '您需要自购订单或直推订单金额满' . $team['grade']['cash_order_num'] . '元才能提现']);
        }
    }
}
admin/app/api/model/product/Product.php
@@ -13,7 +13,7 @@
use app\api\model\user\CardRecord as CardRecordModel; // 会员卡 by lyzflash
use app\common\model\plus\advance\Product as AdvanceProductModel;
use app\supplier\model\product\ProductSku;
use app\api\model\order\Cart as CartModel;
/**
 * 商品模型
 */
@@ -163,6 +163,13 @@
    private function setProductListDataFromApi(&$data, $isMultiple, $param)
    {
        return parent::setProductListData($data, $isMultiple, function ($product) use ($param) {
            if(!empty($param['userInfo'])){
                $CartModel=new CartModel();
                $product['cart']=$CartModel->getCartCount($param['userInfo']['user_id'],$product['product_id']);
            }else{
                $product['cart']=['total_num'=>0];
            }
            // 计算并设置商品会员价
            $this->setProductGradeMoney($param['userInfo'], $product);
        });
@@ -380,7 +387,7 @@
    /**
     * 编辑商品
     */
    public function edit($data,$shop_supplier_id)
    public function edit($data)
    {
        if (!isset($data['image']) || empty($data['image'])) {
            $this->error = '请上传商品图片';
admin/app/api/model/supplier/Supplier.php
@@ -2,6 +2,7 @@
namespace app\api\model\supplier;
use app\common\model\plus\shareholder\Apply as ShareholderApplyModel;
use app\common\model\supplier\Supplier as SupplierModel;
use app\common\model\supplier\User as SupplierUserModel;
use app\api\model\user\Favorite as FavoriteModel;
@@ -32,6 +33,9 @@
            $data['is_super'] = 1;
            $SupplierUserModel->save($data);
            (new teamApplyModel())->becomeTeamByAgent($data['referee_id'],70,$data['app_id']);
            //根据团队人数判断股东 by yj
            $shareholderModel = new ShareholderApplyModel;
            $shareholderModel->becomeShareholderByTeam($data['referee_id'], 80, $data['app_id']);
            $this->commit();
            return true;
        } catch (\Exception $e) {
@@ -104,7 +108,7 @@
            ->where('s.is_delete', '=', '0')
            ->where('s.is_recycle', '=', 0)
            //->where('s.is_full', '=', 1)
            ->field("s.shop_supplier_id,s.name,s.fav_count,logo_id,category_id,server_score,product_sales")
            ->field("s.shop_supplier_id,s.name,s.fav_count,logo_id,category_id,server_score,product_sales,address,link_phone")
            ->order($sort)
            ->paginate($param);
        $product_model = new ProductModel();
admin/app/api/service/order/paysuccess/type/PayTypeSuccessFactory.php
@@ -33,6 +33,9 @@
            case OrderTypeEnum::REGACTIVITY;
                return new RegactivitySuccessService($out_trade_no);
                break;
            case OrderTypeEnum::RELEASE;
                return new ReleasePaySuccessService($out_trade_no);
                break;
            case OrderTypeEnum::BRANCHACTIVITY;
                return new BranchActivityPaySuccessService($out_trade_no);
                break;
admin/app/api/service/order/paysuccess/type/ReleasePaySuccessService.php
New file
@@ -0,0 +1,124 @@
<?php
namespace app\api\service\order\paysuccess\type;
use app\api\model\plus\release\Order as OrderModel;
use app\api\model\user\User as UserModel;
use app\common\enum\order\OrderPayTypeEnum;
use app\common\enum\user\balanceLog\BalanceLogSceneEnum;
use app\common\model\user\BalanceLog as BalanceLogModel;
use app\common\service\BaseService;
use app\common\service\message\MessageService;
/**
 * 支付成功后的回调
 */
class ReleasePaySuccessService extends BaseService
{
    // 订单模型
    public $model;
    // 当前用户信息
    private $user;
    /**
     * 构造函数
     */
    public function __construct($orderNo)
    {
        // 实例化订单模型
        $this->model = OrderModel::getDetail($orderNo);
        // 获取用户信息
        $this->user = UserModel::detail($this->model['demand_user_id']);
    }
    /**
     * 订单支付成功业务处理
     */
    public function onPaySuccess($payType, $payData = [])
    {
        if (empty($this->model)) {
            $this->error = '未找到该订单信息';
            return false;
        }
        // 更新付款状态
        return $this->updatePayStatus($payType, $payData);
    }
    /**
     * 更新付款状态
     */
    private function updatePayStatus($payType, $payData = [])
    {
        // 验证余额支付时用户余额是否满足
        if ($payType == OrderPayTypeEnum::BALANCE) {
            if ($this->user['balance'] < $this->model['pay_price']) {
                $this->error = '用户余额不足,无法使用余额支付';
                return false;
            }
        }
        // 事务处理
        $this->model->transaction(function () use ($payType, $payData) {
            // 更新订单状态
            $this->updateOrderInfo($payType, $payData);
            // 累积用户总消费金额
            $this->user->setIncPayMoney($this->model['pay_price']);
            // 记录订单支付信息
            $this->updatePayInfo($payType);
        });
        // 发送支付消息通知
       // (new MessageService)->release_supplier($this->model);
        return true;
    }
    /**
     * 更新订单记录
     */
    private function updateOrderInfo($payType, $payData)
    {
        $order = [
            'pay_type' => $payType,
            'pay_status' => 20,
            'pay_time' => time(),
        ];
        if ($payType == OrderPayTypeEnum::WECHAT) {
            $order['transaction_id'] = $payData['transaction_id'];
        }
        // 更新订单状态
        return $this->model->save($order);
    }
    /**
     * 记录订单支付信息
     */
    private function updatePayInfo($payType)
    {
        // 余额支付
        if ($payType == OrderPayTypeEnum::BALANCE && $this->model['pay_price'] > 0) {
            // 更新用户余额
            $this->user->where('user_id', '=', $this->user['user_id'])
                ->dec('balance', $this->model['pay_price'])
                ->update();
            BalanceLogModel::add(BalanceLogSceneEnum::CONSUME, [
                'user_id' => $this->user['user_id'],
                'money' => -$this->model['pay_price'],
            ], ['order_no' => $this->model['order_no']]);
        }
    }
    /**
     * 返回app_id,大于0则存在订单信息
     * $pay_status 兼容支付宝支付
     */
    public function isExist($pay_status = 10)
    {
        // 订单信息
        $app_id = 0;
        $order = OrderModel::getDetail($this->model['order_no']);
        !empty($order) && $app_id = $order['app_id'];
        return $app_id;
    }
}
admin/app/branch/model/activityProduct/ActivityProduct.php
New file
@@ -0,0 +1,15 @@
<?php
namespace app\branch\model\activityProduct;
use app\common\model\branch\ActivityProduct as ActivityProductModel;
/**
 * 促销商品模型
 * Class User
 * @package app\branch\model\activityPrpduct
 */
class ActivityProduct extends ActivityProductModel
{
}
admin/app/common/enum/order/OrderTypeEnum.php
@@ -26,6 +26,8 @@
    const FRONT = 70;
    // 预售尾款订单
    const ADVANCE = 80;
    // 发布订单
    const RELEASE = 87;
    // 分会活动报名
    const BRANCHACTIVITY = 90;
    // 名片购买订单
@@ -71,6 +73,10 @@
                'name' => '预售尾款订单',
                'value' => self::ADVANCE,
            ],
            self::RELEASE => [
                'name' => '发布订单',
                'value' => self::RELEASE,
            ],
            self::BRANCHACTIVITY => [
                'name' => '分会活动报名订单',
                'value' => self::BRANCHACTIVITY,
admin/app/common/model/order/Order.php
@@ -128,7 +128,7 @@
     */
    public function supplier()
    {
        return $this->belongsTo('app\\common\\model\\supplier\\Supplier', 'shop_supplier_id', 'shop_supplier_id')->field(['shop_supplier_id', 'name', 'user_id']);
        return $this->belongsTo('app\\common\\model\\supplier\\Supplier', 'shop_supplier_id', 'shop_supplier_id')->field(['shop_supplier_id', 'name', 'user_id', 'referee_id']);
    }
    
    /**
admin/app/common/model/plus/bonus/User.php
@@ -108,21 +108,25 @@
            //获取直推上级
            $referee_id = agentRefereeModel::getRefereeUserId($user_id, 1);
            //获取直推上级推荐的人数
            $direct_child_num = $referee_id ? self::getDirectNum($referee_id) : 0;
            /*if ($referee_id && $direct_child_num < 2) {
                $parent = static::detail($referee_id);
            /*$direct_child_num = $referee_id ? self::getDirectNum($referee_id) : 0;*/
            $parent_id=0;
            if ($referee_id) {
                $parent_id=self::getParentId([$referee_id]);
            }
            if ($parent_id) {
                $parent = static::detail($parent_id);
                //如果自己名下已经被排满,继续往下找
                if ($parent['child_num'] == 3) {
                    //获取起始横向排位
                    $level_num_first = ($parent['level_num'] - 1) * 3 + 1;
                    $parent = self::checkUserChild($level_num_first, 3, $parent['tree_level'] + 1);
                }
            } else {*/
            } else {
                //规则2:查找有空缺的三叉树
                $parent = (new static())->where('child_num', '<', 3)
                                        /*->where('user_id', "<>", $referee_id)*/
                                        ->order(['tree_level' => 'asc', 'level_num' => 'asc'])->find();
            //}
            }
            $data['parent_id'] = $parent['user_id'];
            $data['order_num'] = $parent['child_num'] + 1; //三叉树内的位置
            $data['tree_level'] = $parent['tree_level'] + 1; //竖向层级
@@ -146,7 +150,18 @@
        }
        return true;
    }
    /**
     * 获取团队里公排下级未被排满的id
     */
    public static function getParentId($referee)
    {
        $user=(new static())->where('user_id', 'in', $referee)->where('child_num', '<', 3)->find();
        if ($user) {
            return $user['user_id'];
        }
        $subordinate=(new self())->where('parent_id', 'in', $referee)->column('user_id');
        return self::getParentId($subordinate);
    }
    /**
     * 添加第一个分红用户
     */
admin/app/common/model/plus/shareholder/Apply.php
@@ -6,9 +6,7 @@
use app\common\model\plus\agent\User as AgentUserModel;
use app\common\model\plus\team\User as TeamUserModel;
use app\common\model\plus\team\Order as TeamOrderModel;
use app\common\model\plus\vip\User as VipUserModel;
use app\common\model\plus\vip\Order as VipOrderModel;
use app\common\model\plus\team\Referee as TeamRefereeModel;
/**
 * 股东申请模型
 */
@@ -150,6 +148,15 @@
                $becomeShareholder = true;
            }
        }
        if ($config['become'] == '110'){
            $subordinateUserId=(new TeamRefereeModel())->where(['heads_id'=>$userId])->column('user_id');
            $vipNum=(new \app\common\model\user\User)->getRefereeGradeCount($subordinateUserId,$config['referee_grade_ids']);
            $supplierNum=(new \app\common\model\supplier\User)->getSubordinateNum($subordinateUserId);
            $user=(new \app\common\model\user\User)->where(['user_id'=>$userId,'is_delete'=>0])->find();
            if ($vipNum >= $config['total_vip_num'] && $supplierNum >= $config['totalsh_down']&&$user['purchase_count']>=$config['purchase_count']){
                $becomeShareholder = true;
            }
        }
        // 新增股东用户
        if ($becomeShareholder) {
            User::add($userId, [
@@ -182,70 +189,4 @@
        return ['text' => $method[$value], 'value' => $value];
    }
    /**
     * 统计VIP会员直接推荐数量
     * @param $userId
     * @return int
     */
    public function countVipRecommendations($userId)
    {
        return VipUserModel::where('referee_id', '=', $userId)->count();
    }
    /**
     * 统计企业商户入驻数量
     * @param $userId
     * @return int
     */
    public function countMerchantSettlements($userId)
    {
        // 假设商家入驻与推广团队的关联字段是referee_id
        // 需要根据实际数据库结构调整
        return \app\common\model\Shop::where('referee_id', '=', $userId)->count();
    }
    /**
     * 统计VIP专区商品购买次数
     * @param $userId
     * @return int
     */
    public function countSelfVipPurchases($userId)
    {
        return VipOrderModel::where('user_id', '=', $userId)
            ->where('is_vip', '=', 1)
            ->count();
    }
    /**
     * 检查股东候选人是否满足新的三个条件
     * @param $userId
     * @param $appId
     * @return bool
     */
    public function checkNewShareholderConditions($userId, $appId)
    {
        $config = Setting::getItem('basic', $appId);
        // 1. 检查VIP会员直接推荐数量
        $vipRecommendCount = $this->countVipRecommendations($userId);
        if ($vipRecommendCount < $config['vip_recommend_count']) {
            return false;
        }
        // 2. 检查企业商户入驻数量
        $merchantCount = $this->countMerchantSettlements($userId);
        if ($merchantCount < $config['merchant_settle_count']) {
            return false;
        }
        // 3. 检查VIP专区商品购买次数
        $selfVipPurchaseCount = $this->countSelfVipPurchases($userId);
        if ($selfVipPurchaseCount < $config['self_vip_purchase_count']) {
            return false;
        }
        // 所有条件都满足
        return true;
    }
},
}
admin/app/common/model/plus/team/Apply.php
@@ -1 +1 @@
<?php namespace app\common\model\plus\team; use app\common\model\BaseModel; use app\common\model\plus\agent\User as AgentUserModel; /**  * 队长申请模型  */ class Apply extends BaseModel {     protected $name = 'team_apply';     protected $pk = 'apply_id';     /**      * 申请状态      * @var array      */     public $applyStatus = [         10 => '待审核',         20 => '审核通过',         30 => '驳回',     ];     /**      * 申请时间      * @param $value      * @return false|string      */     public function getApplyTimeAttr($value)     {         return date('Y-m-d H:i:s', $value);     }     /**      * 审核时间      * @param $value      * @return false|int|string      */     public function getAuditTimeAttr($value)     {         return $value > 0 ? date('Y-m-d H:i:s', $value) : 0;     }     /**      * 关联推荐人表      * @return \think\model\relation\BelongsTo      */     public function referee()     {         return $this->belongsTo('app\common\model\user\User', 'referee_id')             ->field(['user_id', 'nickName']);     }     /**      * 销商申请记录详情      * @param $where      * @return array|\think\Model|null      * @throws \think\db\exception\DataNotFoundException      * @throws \think\db\exception\DbException      * @throws \think\db\exception\ModelNotFoundException      */     public static function detail($where)     {         $filter = is_array($where) ? $where : ['apply_id' => $where];         return (new static())->where($filter)->find();     }     /**      * 根据分销判断成为队长      * @param $userId      * @param $appId      * @return bool      */     public function becomeTeamByAgent($userId, $become_type, $appId)     {         //log_write($become_type);         // 验证是否设置         $config = Setting::getItem('basic', $appId);         if (empty($config['is_open'])) {             return false;         }         if ($config['become'] != $become_type) {             return false;         }         $agent = AgentUserModel::detail($userId);         if (!$agent) {             return false;         }         $becomeTeam = false;         //分销商总数         if ($become_type == '40') {             $agent_total = $agent['first_num'] + $agent['second_num'] + $agent['third_num'];             if ($agent_total >= $config['totalfxs_down']) {                 $becomeTeam = true;             }         }         //分销佣金总数         if ($become_type == '50') {             $agent_money = $agent['total_money'] + $agent['money'] + $agent['freeze_money'];             if ($agent_money >= $config['total_money']) {                 $becomeTeam = true;             }         }         if($become_type == '70'){             $vipNum=(new \app\common\model\user\User)->where(['referee_id' =>$userId,'grade_id'=>57,'is_delete'=>0])->count();             $supplierNum=(new \app\common\model\user\User)->where(['referee_id' =>$userId,'is_delete'=>0])->count();             if ($vipNum >= $config['totalvip_down'] && $supplierNum >= $config['totalsh_down']) {                 $BecomeTeam = true;             }         }         // 新增队长用户         if ($BecomeTeam) {             User::add($userId, [                 'referee_id' => $agent['referee_id'], //推荐人id                 'app_id' => $appId,             ]);         }         return true;     }     /**      * 审核状态      * @param $value      * @return array      */     public function getApplyStatusAttr($value)     {         $method = [10 => '待审核', 20 => '审核通过', '30' => '驳回'];         return ['text' => $method[$value], 'value' => $value];     }     /**      * 审核方式      * @param $value      * @return array      */     public function getApplyTypeAttr($value)     {         $method = [10 => '后台审核', 20 => '无需审核'];         return ['text' => $method[$value], 'value' => $value];     } }
<?php namespace app\common\model\plus\team; use app\common\model\BaseModel; use app\common\model\plus\agent\User as AgentUserModel; /**  * 队长申请模型  */ class Apply extends BaseModel {     protected $name = 'team_apply';     protected $pk = 'apply_id';     /**      * 申请状态      * @var array      */     public $applyStatus = [         10 => '待审核',         20 => '审核通过',         30 => '驳回',     ];     /**      * 申请时间      * @param $value      * @return false|string      */     public function getApplyTimeAttr($value)     {         return date('Y-m-d H:i:s', $value);     }     /**      * 审核时间      * @param $value      * @return false|int|string      */     public function getAuditTimeAttr($value)     {         return $value > 0 ? date('Y-m-d H:i:s', $value) : 0;     }     /**      * 关联推荐人表      * @return \think\model\relation\BelongsTo      */     public function referee()     {         return $this->belongsTo('app\common\model\user\User', 'referee_id')             ->field(['user_id', 'nickName']);     }     /**      * 销商申请记录详情      * @param $where      * @return array|\think\Model|null      * @throws \think\db\exception\DataNotFoundException      * @throws \think\db\exception\DbException      * @throws \think\db\exception\ModelNotFoundException      */     public static function detail($where)     {         $filter = is_array($where) ? $where : ['apply_id' => $where];         return (new static())->where($filter)->find();     }     /**      * 根据分销判断成为队长      * @param $userId      * @param $appId      * @return bool      */     public function becomeTeamByAgent($userId, $become_type, $appId)     {         //log_write($become_type);         // 验证是否设置         $config = Setting::getItem('basic', $appId);         if (empty($config['is_open'])) {             return false;         }         if ($config['become'] != $become_type) {             return false;         }         $agent = AgentUserModel::detail($userId);         if (!$agent) {             return false;         }         $becomeTeam = false;         //分销商总数         if ($become_type == '40') {             $agent_total = $agent['first_num'] + $agent['second_num'] + $agent['third_num'];             if ($agent_total >= $config['totalfxs_down']) {                 $becomeTeam = true;             }         }         //分销佣金总数         if ($become_type == '50') {             $agent_money = $agent['total_money'] + $agent['money'] + $agent['freeze_money'];             if ($agent_money >= $config['total_money']) {                 $becomeTeam = true;             }         }         if($become_type == '70'){             $vipNum=(new \app\common\model\user\User)->getRefereeGradeCount($userId,$config['referee_grade_ids']);             $supplierNum=(new \app\common\model\supplier\User)->getSubordinateNum($userId);             $user=(new \app\common\model\user\User)->where(['user_id'=>$userId,'is_delete'=>0])->find();             if ($vipNum >= $config['totalvip_down'] && $supplierNum >= $config['totalsh_down']&&$user['purchase_count']>=$config['purchase_count']) {                 $BecomeTeam = true;             }         }         // 新增队长用户         if ($BecomeTeam) {             User::add($userId, [                 'referee_id' => $agent['referee_id'], //推荐人id                 'app_id' => $appId,             ]);         }         return true;     }     /**      * 审核状态      * @param $value      * @return array      */     public function getApplyStatusAttr($value)     {         $method = [10 => '待审核', 20 => '审核通过', '30' => '驳回'];         return ['text' => $method[$value], 'value' => $value];     }     /**      * 审核方式      * @param $value      * @return array      */     public function getApplyTypeAttr($value)     {         $method = [10 => '后台审核', 20 => '无需审核'];         return ['text' => $method[$value], 'value' => $value];     } }
admin/app/common/model/plus/vip/GradeLog.php
@@ -39,7 +39,7 @@
    public function getList($params)
    {
        return $this->with(['vipUser', 'oldGrade', 'grade'])
        return $this->with(['vipUser'=>['user'], 'oldGrade', 'grade'])
            ->order(['create_time' => 'desc'])
            ->paginate($params);
    }
admin/app/common/model/plus/vip/Order.php
@@ -324,8 +324,10 @@
                    }
                }
            }
            log_write($order['supplier']->toArray());
            if( $order['supplier']['referee_id']!=0){
                $supplierReferee=VipUserModel::detail($order['supplier']['referee_id']);
                log_write('供应商推荐人:'.$supplierReferee['user_id']);
                if ($supplierReferee){
                    $vipGradeSupplier=Grade::detail($supplierReferee['grade_id']);
                    if ($vipGradeSupplier['supplier_money']>0){
admin/app/common/model/release/Capital.php
New file
@@ -0,0 +1,26 @@
<?php
namespace app\common\model\plus\release;
use app\common\model\BaseModel;
/**
 * 资金明细模型
 */
class Capital extends BaseModel
{
    protected $name = 'release_capital';
    protected $pk = 'id';
    /**
     * 分销商资金明细
     * @param $data
     */
    public static function add($data)
    {
        $model = new static;
        $model->save(array_merge([
            'app_id' => $model::$app_id
        ], $data));
    }
}
admin/app/common/model/release/Cart.php
New file
@@ -0,0 +1,231 @@
<?php
namespace app\api\model\plus\repair;
use app\api\model\order\Order as OrderModel;
use think\facade\Cache;
use app\api\model\plus\repair\Project as ProjectModel;
use app\common\model\supplier\Supplier as SupplierModel;
use app\common\library\helper;
use app\common\model\plus\repair\Cart as CartModel;
/**
 * 购物车管理
 */
class Cart extends CartModel
{
    // 错误信息
    public $error = '';
    /**
     * 购物车列表 (含商品信息)
     */
    public function getList($user, $cart_ids = [])
    {
        // 获取购物车商品列表
        return $this->getOrderProjectList($user, $cart_ids);
    }
    /**
     * 获取购物车列表
     */
    public function getCartList($cartIds = null)
    {
        if (empty($cartIds)) return static::$cart;
        $cartList = [];
        $indexArr = (strpos($cartIds, ',') !== false) ? explode(',', $cartIds) : [$cartIds];
        foreach ($indexArr as $index) {
            isset(static::$cart[$index]) && $cartList[$index] = static::$cart[$index];
        }
        return $cartList;
    }
    /**
     * 获取购物车中的商品列表
     */
    public function getOrderProjectList($user, $cart_ids = [])
    {
        // 购物车列表
        $projectList = [];
        // 获取购物车列表
        $model = $this;
        if ($cart_ids) {
            $model = $model->where('cart_id', 'in', explode(',', $cart_ids));
        }
        $cartList = $model->where('user_id', '=', $user['user_id'])->select();
        if (empty($cartList)) {
            $this->setError('当前购物车没有项目');
            return $projectList;
        }
        // 购物车中所有商品id集
        $projectIds = array_unique(helper::getArrayColumn($cartList, 'project_id'));
        // 获取并格式化商品数据
        $sourceData = (new ProjectModel)->getListByIds($projectIds);
        $sourceData = helper::arrayColumn2Key($sourceData, 'project_id');
        // 供应商信息
        $supplierData = [];
        // 格式化购物车数据列表
        foreach ($cartList as $key => $item) {
            // 判断商品不存在则自动删除
            if (!isset($sourceData[$item['project_id']])) {
                $this->delete($key);
                continue;
            }
            // 项目信息
            $project = clone $sourceData[$item['project_id']];
            // 判断商品是否已删除
            if (empty($project)) {
                $this->delete($key);
                continue;
            }
            // 购买数量
            $project['total_num'] = $item['total_num'];
            // 总价
            $project['total_price'] = bcmul($project['price'], $item['total_num'], 2);
            // 总佣金
            $project['total_money'] = bcmul($project['money'], $item['total_num'], 2);
            // 供应商
            $project['shop_supplier_id'] = $item['shop_supplier_id'];
            //购物车id
            $project['cart_id'] = $item['cart_id'];
            $projectList[] = $project;
        }
        $supplierIds = array_unique(helper::getArrayColumn($projectList, 'shop_supplier_id'));
        foreach($supplierIds as $supplierId){
            $supplierData[] = [
                'shop_supplier_id' => $supplierId,
                'supplier' => SupplierModel::detail($supplierId),
                'projectList' => $this->getProjectBySupplier($supplierId, $projectList)
            ];
        }
        return $supplierData;
    }
    private function getProjectBySupplier($supplierId, $projectList)
    {
        $result = [];
        foreach ($projectList as $project){
            if($project['shop_supplier_id'] == $supplierId){
                array_push($result, $project);
            }
        }
        return $result;
    }
    /**
     * 加入购物车
     */
    public function add($user, $projectId, $projectNum)
    {
        $model = $this;
        // 获取信息
        $project = ProjectModel::detail($projectId);
        // 获取商品购物车信息
        $cartDetail = $model->where('user_id', '=', $user['user_id'])
            ->where('project_id', '=', $projectId)
            ->find();
        // 验证能否加入
        if (!$project_price = $this->checkProject($project)) {
            return false;
        }
        // 记录到购物车列表
        if ($cartDetail) {
            return $cartDetail->save(['total_num' => $cartDetail['total_num'] + $projectNum]);
        } else {
            return $this->save([
                'user_id' => $user['user_id'],
                'project_id' => $projectId,
                'total_num' => $projectNum,
                'join_price' => $project_price,
                'shop_supplier_id' => $project['shop_supplier_id'],
                'app_id' => self::$app_id,
            ]);
        }
    }
    /**
     * 验证是否可以下单
     */
    private function checkProject($project)
    {
        // 判断项目
        if (!$project) {
            $this->setError('很抱歉,信息不存在');
            return false;
        }
        return $project['price'];
    }
    /**
     * 减少购物车中某商品数量
     */
    public function sub($user, $projectId)
    {
        $cartDetail = $this->where('user_id', '=', $user['user_id'])
            ->where('project_id', '=', $projectId)
            ->find();
        if ($cartDetail['total_num'] <= 1) {
            return $cartDetail->delete();
        } else {
            $cartDetail->save(['total_num' => $cartDetail['total_num'] - 1]);
        }
    }
    /**
     * 删除购物车中指定商品
     * @param string $cartIds (支持字符串ID集)
     */
    public function setDelete($user, $cart_id)
    {
        return $this->where('user_id', '=', $user['user_id'])->where('cart_id', 'in', explode(',', $cart_id))->delete();
    }
    /**
     * 获取当前用户购物车商品总数量(含件数)
     */
    public function getTotalNum($user)
    {
        $num = $this->where('user_id', '=', $user['user_id'])->sum('total_num');
        return $num ? $num : 0;
    }
    /**
     * 获取当前用户购物车商品总数量(不含件数)
     */
    public function getProductNum($user)
    {
        return $this->where('user_id', '=', $user['user_id'])->count();
    }
    /**
     * 清空当前用户购物车
     */
    public function clearAll($user, $cartIds)
    {
        return $this->where('user_id', '=', $user['user_id'])
            ->where('cart_id', 'in', explode(',', $cartIds))
            ->delete();
    }
    /**
     * 设置错误信息
     */
    private function setError($error)
    {
        empty($this->error) && $this->error = $error;
    }
    /**
     * 获取错误信息
     */
    public function getError()
    {
        return $this->error;
    }
}
admin/app/common/model/release/Cash.php
New file
@@ -0,0 +1,64 @@
<?php
namespace app\common\model\plus\release;
use app\common\model\BaseModel;
/**
 * 分销商提现明细模型
 */
class Cash extends BaseModel
{
    protected $name = 'release_cash';
    protected $pk = 'id';
    /**
     * 打款方式
     * @var array
     */
    public $payType = [
        10 => '微信',
        20 => '支付宝',
        30 => '银行卡',
    ];
    /**
     * 申请状态
     * @var array
     */
    public $applyStatus = [
        10 => '待审核',
        20 => '审核通过',
        30 => '驳回',
        40 => '已打款',
    ];
    /**
     * 关联用户表
     * @return \think\model\relation\BelongsTo
     */
    public function user()
    {
        return $this->belongsTo('SupplyUser');
    }
    /**
     * 提现详情
     */
    public static function detail($id)
    {
        return (new static())->find($id);
    }
    /**
     * 审核状态
     * @param $value
     * @return array
     */
    public function getApplyStatusAttr($value)
    {
        $method = [10 => '待审核', 20 => '审核通过', 30 => '驳回', 40 => '已打款'];
        return ['text' => $method[$value], 'value' => $value];
    }
}
admin/app/common/model/release/DemandApply.php
New file
@@ -0,0 +1,82 @@
<?php
namespace app\common\model\plus\release;
use app\common\model\BaseModel;
use app\common\model\user\User as UserModel;
/**
 * 分销商申请模型
 */
class DemandApply extends BaseModel
{
    protected $name = 'release_demand_apply';
    protected $pk = 'apply_id';
    /**
     * 申请状态
     * @var array
     */
    public $applyStatus = [
        10 => '待审核',
        20 => '审核通过',
        30 => '驳回',
    ];
    /**
     * 申请时间
     * @param $value
     * @return false|string
     */
    public function getApplyTimeAttr($value)
    {
        return date('Y-m-d H:i:s', $value);
    }
    /**
     * 审核时间
     * @param $value
     * @return false|int|string
     */
    public function getAuditTimeAttr($value)
    {
        return $value > 0 ? date('Y-m-d H:i:s', $value) : 0;
    }
    /**
     * 销商申请记录详情
     * @param $where
     * @return array|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function detail($where)
    {
        $filter = is_array($where) ? $where : ['apply_id' => $where];
        return (new static())->where($filter)->find();
    }
    /**
     * 审核状态
     * @param $value
     * @return array
     */
    public function getApplyStatusAttr($value)
    {
        $method = [10 => '待审核', 20 => '审核通过', '30' => '驳回'];
        return ['text' => $method[$value], 'value' => $value];
    }
    /**
     * 审核方式
     * @param $value
     * @return array
     */
    public function getApplyTypeAttr($value)
    {
        $method = [10 => '后台审核', 20 => '无需审核'];
        return ['text' => $method[$value], 'value' => $value];
    }
}
admin/app/common/model/release/DemandProject.php
New file
@@ -0,0 +1,157 @@
<?php
namespace app\api\model\plus\release;
use app\common\model\plus\release\Project as ProjectModel;
use app\common\model\plus\release\ReleaseProjectImage as ReleaseProjectImageModel;
/**
 * 模型
 */
class DemandProject extends ProjectModel
{
    /**
     * 获取提现明细
     */
    public function getList($user_id, $postdata)
    {
        $model = $this;
        if(!empty($postdata["keyword"])){
            $model = $model->where('name', 'like', '%'.$postdata["keyword"].'%');
        }
        return $model->where('is_delete', '=', 0)
            ->where('project_type', '=', 0)
            ->where('user_id', '=', $user_id)
            ->order(['create_time' => 'desc'])
            ->paginate($postdata);
    }
    /**
     * 新增记录
     */
    public function add($postdata,$demand)
    {
        $data = json_decode($postdata["formData"],true);
        if (empty($data['name'])) {
                $this->error = '请输入标题';
                return false;
         }
        if (empty($data['category_id'])) {
                $this->error = '请选择分类';
                return false;
         }
        if (empty($data['price'])) {
                $this->error = '请输入您的预算';
                return false;
        }
       if (empty($data['content'])) {
                $this->error = '请输入您的详细需求';
                return false;
        }
        $save_data =[
            'user_id'=>$demand["user_id"],
            'name'=>$data["name"],
            'category_id'=>$data["category_id"],
            'price'=>$data["price"],
            'content'=>$data["content"],
            'detail'=>$data["detail"],
            'show_phone'=>$data["show_phone"],
            'is_show'=>$data["is_show"],
            'app_id'=>self::$app_id,
        ];
        if(!empty($data["finish_time"]) && $data["finish_time"] != '请选择日期'){
            $save_data["finish_time"] = strtotime($data["finish_time"]);
        }else{
            $save_data["finish_time"] = '';
        }
          return $this->transaction(function () use ($data, $save_data) {
            // 记录内容
            $this->save($save_data);
            // 记录图片
            $this->saveAllImages($this['project_id'],$data);
            return $this['project_id'];
        });
    }
    /**
     * 更新记录
     */
    public function edit($postdata)
    {
        $data = json_decode($postdata["formData"],true);
        if (empty($data['name'])) {
                $this->error = '请输入标题';
                return false;
         }
        if (empty($data['category_id'])) {
                $this->error = '请选择分类';
                return false;
         }
        if (empty($data['price'])) {
                $this->error = '请输入您的预算';
                return false;
        }
       if (empty($data['content'])) {
                $this->error = '请输入您的详细需求';
                return false;
        }
         $save_data =[
            'name'=>$data["name"],
            'category_id'=>$data["category_id"],
            'price'=>$data["price"],
            'content'=>$data["content"],
            'detail'=>$data["detail"],
            'show_phone'=>$data["show_phone"],
            'is_show'=>$data["is_show"],
            'status'=>0,
        ];
        if(!empty($data["finish_time"]) && $data["finish_time"] != '请选择日期'){
            $save_data["finish_time"] = strtotime($data["finish_time"]);
        }else{
            $save_data["finish_time"] = '';
        }
        return $this->transaction(function () use ($data, $save_data) {
            // 记录内容
            $this->where("project_id","=",$data["project_id"])->save($save_data);
            // 记录图片
            $this->saveAllImages($data["project_id"],$data);
            return true;
        });
    }
     /**
     * 记录图片
     */
    private function saveAllImages($id,$formData)
    {
        (new ReleaseProjectImageModel())->where("project_id","=",$id)->delete();
        // 生成图片数据
        if(!empty($formData['image_list'])){
            $imageData = [];
            foreach ($formData['image_list'] as $imageId) {
                $imageData[] = [
                    'project_id' => $id,
                    'image_id' => !empty($imageId['image_id']) ? $imageId['image_id'] : $imageId['file_id'],
                    'app_id' => self::$app_id
                ];
            }
            $model = new ReleaseProjectImageModel;
            return !empty($imageData) && $model->saveAll($imageData);
        }
        return true;
    }
    /**
     * 软删除
     */
    public function setDelete($id)
    {
        return $this->where("project_id","=",$id)->save(['is_delete' => 1]);
    }
}
admin/app/common/model/release/DemandUser.php
New file
@@ -0,0 +1,67 @@
<?php
namespace app\common\model\plus\release;
use app\common\model\BaseModel;
/**
 * 用户模型
 */
class DemandUser extends BaseModel
{
    protected $name = 'release_demand_user';
    protected $pk = 'user_id';
    /**
     * 关联会员记录表
     * @return \think\model\relation\BelongsTo
     */
    public function user()
    {
        return $this->belongsTo('app\\common\\model\\user\\User');
    }
    /**
     * 详情
     */
    public static function detail($user_id, $with = ['user'])
    {
        return (new static())->with($with)->find($user_id);
    }
    /**
     * 详情
     */
    public static function getAll()
    {
        return (new static())->where("is_delete","=",0)->select();
    }
    /**
     * 是否为需求方
     */
    public static function isDemandUser($user_id)
    {
        $demand = self::detail($user_id);
        return !!$demand && !$demand['is_delete'];
    }
    /**
     * 新增记录
     * @param $user_id
     * @param $data
     * @return bool
     */
    public static function add($user_id, $data)
    {
        $model = static::detail($user_id) ?: new static;
         $model->save(array_merge([
            'user_id' => $user_id,
            'is_delete' => 0,
            'app_id' => $model::$app_id,
        ], $data));
        return true;
    }
}
admin/app/common/model/release/Order.php
New file
@@ -0,0 +1,109 @@
<?php
namespace app\common\model\plus\release;
use app\common\enum\order\OrderPayTypeEnum;
use app\common\model\BaseModel;
/**
 * 订单模型
 */
class Order extends BaseModel
{
    protected $name = 'release_order';
    protected $pk = 'id';
    /**
     * 追加字段
     * @var string[]
     */
    protected $append = [
        'state_text',
    ];
    /**
     * 需求用户
     * @return \think\model\relation\BelongsTo
     */
    public function demanduser()
    {
        return $this->belongsTo('app\common\model\user\User','demand_user_id','user_id');
    }
     /**
     * 供应用户
     * @return \think\model\relation\BelongsTo
     */
    public function supplyuser()
    {
        return $this->belongsTo('app\common\model\user\User','supply_user_id','user_id');
    }
    /**
     * 关联项目
     * @return \think\model\relation\hasMany
     */
    public function project()
    {
        return $this->belongsTo('app\common\model\plus\release\Project','project_id','project_id');
    }
    /**
     * 订单状态文字描述
     * @param $value
     * @param $data
     * @return string
     */
    public function getStateTextAttr($value, $data)
    {
        if($data['order_status'] == 20){
            return '已取消';
        }
        // 订单状态
        if ($data['pay_status'] == 10 && $data['pay_type'] == 40) {
            return '待确认支付';
        }else if ($data['pay_status'] == 10 && $data['pay_type'] != 40) {
            return '未付款';
        }else if($data['pay_status'] == 20 && $data['order_status'] == 10){
            return '进行中';
        }else if($data['pay_status'] == 20 && $data['order_status'] == 30){
            return '已完成';
        }
        return "";
    }
    /**
     * 付款状态
     * @param $value
     * @return array
     */
    public function getPayTypeAttr($value)
    {
        if(empty($value)){
            return ['text' => '', 'value' => 0];
        }
        return ['text' => OrderPayTypeEnum::data()[$value]['name'], 'value' => $value];
    }
    /**
     * 详情
     */
    public static function detail($id)
    {
        $model = new static();
        return $model->with(['demanduser','supplyuser',"project"])->find($id);
    }
    /**
     * 详情
     */
    public static function getDetail($order_no)
    {
        $model = new static();
        return $model->with(["project"])->where("order_no",'=',$order_no)->find();
    }
}
admin/app/common/model/release/Project.php
New file
@@ -0,0 +1,70 @@
<?php
namespace app\common\model\plus\release;
use app\common\model\BaseModel;
/**
 * 项目模型
 */
class Project extends BaseModel
{
    protected $name = 'release_project';
    protected $pk = 'project_id';
    /**
     * 关联上传图片表
     */
    public function image()
    {
        return $this->hasMany('app\\common\\model\\plus\\release\\ReleaseProjectImage', 'project_id', 'id')->order(['id' => 'asc']);
    }
    /**
     * 关联分类
     * @return \think\model\relation\BelongsTo
     */
    public function category()
    {
        return $this->belongsTo('app\\common\\model\\plus\\release\\ReleaseCategory','category_id','category_id');
    }
     /**
     * 关联
     * @return \think\model\relation\BelongsTo
     */
    public function user()
    {
        return $this->belongsTo('app\\common\\model\\user\\User','user_id','user_id');
    }
    /**
     * 关联多标签表
     */
    public function tag()
    {
        return $this->hasMany('app\\common\\model\\plus\\release\\Tag', 'tag_id', 'tag_id');
    }
    /**
     * 获取详情
     */
    public static function detail($project_id)
    {
        return (new static())->with(['image'])->find($project_id);
    }
    /**
     * 获取列表记录
     */
    public function getAll()
    {
        return $this->where('is_delete', '=', 0)
            ->field('project_id,name')
            ->order(['sort' => 'asc', 'create_time' => 'asc'])
            ->select();
    }
}
admin/app/common/model/release/ReleaseCategory.php
New file
@@ -0,0 +1,41 @@
<?php
namespace app\common\model\plus\release;
use think\facade\Cache;
use app\common\model\BaseModel;
/**
 * 分类模型
 */
class ReleaseCategory extends BaseModel
{
    protected $pk = 'category_id';
    protected $name = 'release_category';
    /**
     * 详情
     */
    public static function detail($category_id)
    {
        return (new static())->find($category_id);
    }
    /**
     * 所有分类
     */
    public static function getALL()
    {
        $model = new static;
        $data = $model->order(['sort' => 'asc', 'create_time' => 'asc'])->select();
        return $data;
    }
    public function getListByIds($ids)
    {
        return $this->field(['category_id', 'name'])->where('category_id', 'in', $ids)->select();
    }
}
admin/app/common/model/release/ReleaseProjectImage.php
New file
@@ -0,0 +1,33 @@
<?php
namespace app\common\model\plus\release;
use app\common\model\BaseModel;
/**
 * 图片模型
 */
class ReleaseProjectImage extends BaseModel
{
    protected $name = 'release_project_image';
    protected $pk = 'id';
    protected $updateTime = false;
    /**
     * 关联文件库
     */
    public function file()
    {
        return $this->belongsTo('app\\common\\model\\file\\UploadFile', 'image_id', 'file_id')
            ->bind(['file_path', 'file_name', 'file_url']);
    }
    public static function getImage($project_id)
    {
        $model = new static;
        return $model->with(['file'])
            ->where('project_id', '=', $project_id)
            ->select();
    }
}
admin/app/common/model/release/ReleaseProjectTag.php
New file
@@ -0,0 +1,47 @@
<?php
namespace app\common\model\plus\release;
use app\common\model\BaseModel;
/**
 * 图片模型
 */
class ReleaseProjectTag extends BaseModel
{
    protected $name = 'release_project_tag';
    protected $pk = 'id';
    protected $updateTime = false;
    /**
     * 关联
     */
    public function tag()
    {
        return $this->belongsTo('app\\common\\model\\plus\\release\\Tag', 'tag_id', 'tag_id')
            ->bind(['name']);
    }
    public static function getTagId($project_id)
    {
        $model = new static;
        return $model
            ->where('project_id', '=', $project_id)
            ->column("tag_id");
    }
    public static function getTagName($project_id)
    {
        $model = new static;
        return $model->with('tag')
            ->where('project_id', '=', $project_id)
            ->select();
    }
    public static function getTagList($project_id)
    {
        $model = new static;
        return $model->with(['tag'])
            ->where('project_id', '=', $project_id)
            ->select();
    }
}
admin/app/common/model/release/Setting.php
New file
@@ -0,0 +1,398 @@
<?php
namespace app\common\model\plus\release;
use app\common\model\BaseModel;
use think\facade\Cache;
/**
 * 设置模型
 */
class Setting extends BaseModel
{
    protected $name = 'release_setting';
    protected $createTime = false;
    /**
     * 转义数组格式
     * @param $value
     * @return mixed
     */
    public function getValuesAttr($value)
    {
        return json_decode($value, true);
    }
    /**
     * 转义成json格式
     * @param $value
     * @return false|string
     */
    public function setValuesAttr($value)
    {
        return json_encode($value);
    }
    /**
     * 获取指定项设置
     * @param $key
     * @param null $app_id
     * @return array|mixed
     */
    public static function getItem($key, $app_id = null)
    {
        $data = static::getAll($app_id);
        return isset($data[$key]) ? $data[$key]['values'] : [];
    }
    /**
     * 获取分销商设置
     */
    public static function getAll($app_id = null)
    {
        $self = new static;
        is_null($app_id) && $app_id = $self::$app_id;
        if (!$data = Cache::get('release_setting_' . $app_id)) {
            $data = array_column($self->select()->toArray(), null, 'key');
            Cache::tag('cache')->set('release_setting_' . $app_id, $data);
        }
        return array_merge_multiple($self->defaultData(), $data);
    }
    /**
     * 获取设置项信息
     */
    public static function detail($key)
    {
        return (new static())->find(compact('key'));
    }
    /**
     * 是否开启功能
     */
    public static function isOpen($app_id = null)
    {
        return static::getItem('basic', $app_id)['is_open'];
    }
    /**
     * 页面名称
     */
    public static function getAgentTitle($app_id = null)
    {
        return static::getItem('words', $app_id)['index']['title']['value'];
    }
    /**
     * 默认配置
     * @return array[]
     */
    public function defaultData()
    {
        return [
            'basic' => [
                'key' => 'basic',
                'describe' => '基础设置',
                'values' => [
                    // 是否开启分销功能
                    'is_open' => '0',   // 参数值:1开启 0关闭
                    // 分销层级
                    'level' => '3', // 参数值:1一级 2二级 3三级
                    // 分销商内购
                    'self_buy' => '0',   // 参数值:1开启 0关闭
                    'commission_type' => '0', // 佣金计算方式 0固定 1循环
                    'loop_num' => 3, // 循环长度
                    'buy_again' => '1' // 重复购买是否参与分销
                ],
            ],
            'condition' => [
                'key' => 'condition',
                'describe' => '分销商条件',
                'values' => [
                    // 成为分销商条件
                    'become' => '10',   // 参数值:10填写申请信息(需后台审核) 20填写申请信息(无需审核) 30单次消费 40累计消费 50购买指定商品
                    // 购买指定商品成为分销商 0关闭 1开启
                    'become__buy_product' => '0',
                    // 购买指定商品的id集
                    'become__buy_product_ids' => [],
                    // 成为下线条件
                    'downline' => '10',  // 参数值:10首次点击分享链接 20首次下单 30首次付款
                    //单次消费金额
                    'one_money' => '0',
                    //累计消费金额
                    'total_money' => '0',
                ]
            ],
            'commission' => [
                'key' => 'commission',
                'describe' => '佣金设置',
                'values' => [
                    // 一级佣金
                    'first_money' => '0',
                    // 一级佣金
                    'second_money' => '0',
                    // 一级佣金
                    'third_money' => '0',
                    'first_loop_money' => [] //循环比例
                ]
            ],
            'settlement' => [
                'key' => 'settlement',
                'describe' => '结算',
                'values' => [
                    // 提现方式
                    'pay_type' => [],   // 参数值:10微信支付 20支付宝支付 30银行卡支付
                    // 微信支付自动打款
                    'wechat_pay_auto' => '0',       // 微信支付自动打款:1开启 0关闭
                    // 最低提现额度
                    'min_money' => '10.00',
                    // 佣金结算天数
                    'settle_days' => '10',
                    // 微信打款方式
                    'wechat_type' => '0',
                    'fee_rate' => '0',
                    'order_rate' => '0',
                    'explain' => ''
                ]
            ],
            'words' => [
                'key' => 'words',
                'describe' => '自定义文字',
                'values' => [
                    'index' => [
                        'title' => [
                            'default' => '分销中心',
                            'value' => '分销中心'
                        ],
                        'words' => [
                            'agent' => [
                                'default' => '分销商',
                                'value' => '分销商'
                            ],
                            'not_agent' => [
                                'default' => '您还不是分销商',
                                'value' => '您还不是分销商'
                            ],
                            'apply_now' => [
                                'default' => '立即加入',
                                'value' => '立即加入'
                            ],
                            'referee' => [
                                'default' => '推荐人',
                                'value' => '推荐人'
                            ],
                            'money' => [
                                'default' => '可提现佣金',
                                'value' => '可提现'
                            ],
                            'freeze_money' => [
                                'default' => '待提现佣金',
                                'value' => '待提现'
                            ],
                            'total_money' => [
                                'default' => '已提现金额',
                                'value' => '已提现金额'
                            ],
                            'cash' => [
                                'default' => '去提现',
                                'value' => '去提现'
                            ],
                            'referee_code' => [
                                'default' => '邀请码',
                                'value' => '邀请码'
                            ],
                        ]
                    ],
                    'apply' => [
                        'title' => [
                            'default' => '申请成为分销商',
                            'value' => '申请成为分销商'
                        ],
                        'words' => [
                            'title' => [
                                'default' => '请填写申请信息',
                                'value' => '请填写申请信息'
                            ],
                            'license' => [
                                'default' => '分销商申请协议',
                                'value' => '分销商申请协议'
                            ],
                            'submit' => [
                                'default' => '申请成为经销商',
                                'value' => '申请成为经销商'
                            ],
                            'wait_audit' => [
                                'default' => '您的申请已受理,正在进行信息核验,请耐心等待。',
                                'value' => '您的申请已受理,正在进行信息核验,请耐心等待。'
                            ],
                            'goto_mall' => [
                                'default' => '去商城逛逛',
                                'value' => '去商城逛逛'
                            ],
                        ]
                    ],
                    'order' => [
                        'title' => [
                            'default' => '分销订单',
                            'value' => '分销订单'
                        ],
                        'words' => [
                            'all' => [
                                'default' => '全部',
                                'value' => '全部'
                            ],
                            'unsettled' => [
                                'default' => '未结算',
                                'value' => '未结算'
                            ],
                            'settled' => [
                                'default' => '已结算',
                                'value' => '已结算'
                            ],
                        ]
                    ],
                    'team' => [
                        'title' => [
                            'default' => '我的团队',
                            'value' => '我的团队'
                        ],
                        'words' => [
                            'total_team' => [
                                'default' => '团队总人数',
                                'value' => '团队总人数'
                            ],
                            'first' => [
                                'default' => '一级团队',
                                'value' => '一级团队'
                            ],
                            'second' => [
                                'default' => '二级团队',
                                'value' => '二级团队'
                            ],
                            'third' => [
                                'default' => '三级团队',
                                'value' => '三级团队'
                            ],
                        ]
                    ],
                    'cash_list' => [
                        'title' => [
                            'default' => '提现明细',
                            'value' => '提现明细'
                        ],
                        'words' => [
                            'all' => [
                                'default' => '全部',
                                'value' => '全部'
                            ],
                            'apply_10' => [
                                'default' => '审核中',
                                'value' => '审核中'
                            ],
                            'apply_20' => [
                                'default' => '审核通过',
                                'value' => '审核通过'
                            ],
                            'apply_40' => [
                                'default' => '已打款',
                                'value' => '已打款'
                            ],
                            'apply_30' => [
                                'default' => '驳回',
                                'value' => '驳回'
                            ],
                        ]
                    ],
                    'cash_apply' => [
                        'title' => [
                            'default' => '申请提现',
                            'value' => '申请提现'
                        ],
                        'words' => [
                            'capital' => [
                                'default' => '可提现佣金',
                                'value' => '可提现佣金'
                            ],
                            'money' => [
                                'default' => '提现金额',
                                'value' => '提现金额'
                            ],
                            'money_placeholder' => [
                                'default' => '请输入要提取的金额',
                                'value' => '请输入要提取的金额'
                            ],
                            'min_money' => [
                                'default' => '最低提现佣金',
                                'value' => '最低提现佣金'
                            ],
                            'submit' => [
                                'default' => '提交申请',
                                'value' => '提交申请'
                            ],
                        ]
                    ],
                    'qrcode' => [
                        'title' => [
                            'default' => '推广二维码',
                            'value' => '推广二维码'
                        ]
                    ],
                ]
            ],
            'license' => [
                'key' => 'license',
                'describe' => '申请协议',
                'values' => [
                    'license' => ''
                ]
            ],
            'background' => [
                'key' => 'background',
                'describe' => '页面背景图',
                'values' => [
                    // 分销中心首页
                    'index' => self::$base_url . 'image/agent/agent-bg.jpg',
                    // 申请成为分销商页
                    'apply' => self::$base_url . 'image/agent/agent-bg.jpg',
                    // 申请提现页
                    'cash_apply' => self::$base_url . 'image/agent/agent-bg.jpg',
                ],
            ],
            'template_msg' => [
                'key' => 'template_msg',
                'describe' => '模板消息',
                'values' => [
                    'apply_tpl' => '',    // 分销商审核通知
                    'cash_tpl' => '',    // 提现状态通知
                ]
            ],
            'qrcode' => [
                'key' => 'template_msg',
                'describe' => '分销海报',
                'values' => [
                    'backdrop' => [
                        'src' => self::$base_url . 'image/agent/backdrop.jpg',
                    ],
                    'nickName' => [
                        'fontSize' => 14,
                        'color' => '#000000',
                        'left' => 150,
                        'top' => 99
                    ],
                    'avatar' => [
                        'width' => 70,
                        'style' => 'circle',
                        'left' => 150,
                        'top' => 18
                    ],
                    'qrcode' => [
                        'width' => 100,
                        'style' => 'circle',
                        'left' => 136,
                        'top' => 128
                    ]
                ],
            ]
        ];
    }
}
admin/app/common/model/release/SupplyApply.php
New file
@@ -0,0 +1,82 @@
<?php
namespace app\common\model\plus\release;
use app\common\model\BaseModel;
use app\common\model\user\User as UserModel;
/**
 * 申请模型
 */
class SupplyApply extends BaseModel
{
    protected $name = 'release_supply_apply';
    protected $pk = 'apply_id';
    /**
     * 申请状态
     * @var array
     */
    public $applyStatus = [
        10 => '待审核',
        20 => '审核通过',
        30 => '驳回',
    ];
    /**
     * 申请时间
     * @param $value
     * @return false|string
     */
    public function getApplyTimeAttr($value)
    {
        return date('Y-m-d H:i:s', $value);
    }
    /**
     * 审核时间
     * @param $value
     * @return false|int|string
     */
    public function getAuditTimeAttr($value)
    {
        return $value > 0 ? date('Y-m-d H:i:s', $value) : 0;
    }
    /**
     * 销商申请记录详情
     * @param $where
     * @return array|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function detail($where)
    {
        $filter = is_array($where) ? $where : ['apply_id' => $where];
        return (new static())->where($filter)->find();
    }
    /**
     * 审核状态
     * @param $value
     * @return array
     */
    public function getApplyStatusAttr($value)
    {
        $method = [10 => '待审核', 20 => '审核通过', '30' => '驳回'];
        return ['text' => $method[$value], 'value' => $value];
    }
    /**
     * 审核方式
     * @param $value
     * @return array
     */
    public function getApplyTypeAttr($value)
    {
        $method = [10 => '后台审核', 20 => '无需审核'];
        return ['text' => $method[$value], 'value' => $value];
    }
}
admin/app/common/model/release/SupplyProject.php
New file
@@ -0,0 +1,186 @@
<?php
namespace app\api\model\plus\release;
use app\common\model\plus\release\Project as ProjectModel;
use app\common\model\plus\release\ReleaseProjectImage as ReleaseProjectImageModel;
use app\common\model\plus\release\Tag as TagModel;
use app\common\model\plus\release\ReleaseProjectTag as ReleaseProjectTagModel;
/**
 * 模型
 */
class SupplyProject extends ProjectModel
{
    /**
     * 获取提现明细
     */
    public function getList($user_id, $postdata)
    {
        $model = $this;
        if(!empty($postdata["keyword"])){
            $model = $model->where('name', 'like', '%'.$postdata["keyword"].'%');
        }
        return $model->where('is_delete', '=', 0)
            ->where('project_type', '=', 1)
            ->where('user_id', '=', $user_id)
            ->order(['create_time' => 'desc'])
            ->paginate($postdata);
    }
    /**
     * 新增记录
     */
    public function add($postdata,$supply)
    {
        $data = json_decode($postdata["formData"],true);
        if (empty($data['name'])) {
                $this->error = '请输入标题';
                return false;
         }
        if (empty($data['category_id'])) {
                $this->error = '请选择分类';
                return false;
         }
        if (empty($data['price'])) {
                $this->error = '请输入您的价格';
                return false;
        }
       if (empty($data['content'])) {
                $this->error = '请输入您的详细描述';
                return false;
        }
        $save_data =[
            'user_id'=>$supply["user_id"],
            'name'=>$data["name"],
            'category_id'=>$data["category_id"],
            'price'=>$data["price"],
            'content'=>$data["content"],
            'detail'=>$data["detail"],
            'project_type'=>1,
            'is_show'=>$data["is_show"],
            'app_id'=>self::$app_id,
        ];
        if(!empty($data["finish_time"]) && $data["finish_time"] != '请选择日期'){
            $save_data["finish_time"] = strtotime($data["finish_time"]);
        }else{
            $save_data["finish_time"] = '';
        }
          return $this->transaction(function () use ($data, $save_data) {
            // 记录内容
            $this->save($save_data);
            // 记录图片
            $this->saveAllImages($this['project_id'],$data);
            // 记录标签
            $this->saveTag($this['project_id'],$data);
            return $this['project_id'];
        });
    }
    /**
     * 更新记录
     */
    public function edit($postdata)
    {
        $data = json_decode($postdata["formData"],true);
        if (empty($data['name'])) {
                $this->error = '请输入标题';
                return false;
         }
        if (empty($data['category_id'])) {
                $this->error = '请选择分类';
                return false;
         }
        if (empty($data['price'])) {
                $this->error = '请输入您的价格';
                return false;
        }
       if (empty($data['content'])) {
                $this->error = '请输入您的详细描述';
                return false;
        }
         $save_data =[
            'name'=>$data["name"],
            'category_id'=>$data["category_id"],
            'price'=>$data["price"],
            'content'=>$data["content"],
            'detail'=>$data["detail"],
            'is_show'=>$data["is_show"],
            'status'=>0,
        ];
        if(!empty($data["finish_time"]) && $data["finish_time"] != '请选择日期'){
            $save_data["finish_time"] = strtotime($data["finish_time"]);
        }else{
            $save_data["finish_time"] = '';
        }
        return $this->transaction(function () use ($data, $save_data) {
            // 记录内容
            $this->where("project_id","=",$data["project_id"])->save($save_data);
            // 记录图片
            $this->saveAllImages($data['project_id'],$data);
            // 记录标签
            $this->saveTag($data['project_id'],$data);
            return true;
        });
    }
     /**
     * 记录图片
     */
    private function saveAllImages($id,$formData)
    {
        (new ReleaseProjectImageModel())->where("project_id","=",$id)->delete();
        // 生成图片数据
        if(!empty($formData['image_list'])){
            $imageData = [];
            foreach ($formData['image_list'] as $imageId) {
                $imageData[] = [
                    'project_id' => $id,
                    'image_id' => !empty($imageId['image_id']) ? $imageId['image_id'] : $imageId['file_id'],
                    'app_id' => self::$app_id
                ];
            }
            $model = new ReleaseProjectImageModel;
            return !empty($imageData) && $model->saveAll($imageData);
        }
        return true;
    }
    /**
     * 记录标签
     */
    private function saveTag($id,$formData)
    {
        (new ReleaseProjectTagModel())->where("project_id","=",$id)->delete();
        // 生成数据
        if(!empty($formData['tag_list'])){
            $tagData = [];
            foreach ($formData['tag_list'] as $val) {
                $tagData[] = [
                    'project_id' => $id,
                    'tag_id' => $val,
                    'app_id' => self::$app_id
                ];
            }
            $model = new ReleaseProjectTagModel;
            return !empty($tagData) && $model->saveAll($tagData);
        }
        return true;
    }
    /**
     * 软删除
     */
    public function setDelete($id)
    {
        return $this->where("project_id","=",$id)->save(['is_delete' => 1]);
    }
}
admin/app/common/model/release/SupplyUser.php
New file
@@ -0,0 +1,67 @@
<?php
namespace app\common\model\plus\release;
use app\common\model\BaseModel;
/**
 * 用户模型
 */
class SupplyUser extends BaseModel
{
    protected $name = 'release_supply_user';
    protected $pk = 'user_id';
    /**
     * 关联会员记录表
     * @return \think\model\relation\BelongsTo
     */
    public function user()
    {
        return $this->belongsTo('app\\common\\model\\user\\User');
    }
    /**
     * 详情
     */
    public static function detail($user_id, $with = ['user'])
    {
        return (new static())->with($with)->find($user_id);
    }
    /**
     * 详情
     */
    public static function getAll()
    {
        return (new static())->where("is_delete","=",0)->select();
    }
    /**
     * 是否为供应方
     */
    public static function isSupplyUser($user_id)
    {
        $supply = self::detail($user_id);
        return !!$supply && !$supply['is_delete'];
    }
    /**
     * 新增记录
     * @param $user_id
     * @param $data
     * @return bool
     */
    public static function add($user_id, $data)
    {
        $model = static::detail($user_id) ?: new static;
         $model->save(array_merge([
            'user_id' => $user_id,
            'is_delete' => 0,
            'app_id' => $model::$app_id,
        ], $data));
        return true;
    }
}
admin/app/common/model/release/Tag.php
New file
@@ -0,0 +1,35 @@
<?php
namespace app\common\model\plus\release;
use app\common\model\BaseModel;
/**
 * 项目标签模型
 */
class Tag extends BaseModel
{
    protected $name = 'release_tag';
    protected $pk = 'tag_id';
    /**
     * 获取详情
     */
    public static function detail($tag_id)
    {
        return (new static())->find($tag_id);
    }
    /**
     * 获取列表记录
     */
    public static function getAll()
    {
        return (new static())->where('is_delete', '=', 0)
            ->field('tag_id,name')
            ->order(['sort' => 'asc', 'create_time' => 'asc'])
            ->select();
    }
}
admin/app/common/model/supplier/User.php
@@ -91,4 +91,16 @@
        session('jjjshop_supplier', $session);
    }
    /**
     * 下级商户数量
     * @param $user_id
     * @return int
     */
    public function getSubordinateNum($user_id)
    {
        return (new static())->where('is_delete', '=', 0)
            ->where('referee_id', 'in', $user_id)
            ->count();
    }
}
admin/app/common/model/user/User.php
@@ -337,6 +337,7 @@
     */
    public function getRefereeGradeCount($user_id,$referee_grade_ids)
    {
        return $this->where('referee_id', '=', $user_id)->where('grade_id', 'in', $referee_grade_ids)->count();
        return $this->where('referee_id', 'in', $user_id)->where('grade_id', 'in', $referee_grade_ids)->count();
    }
}
admin/app/shop/controller/plus/release/Cash.php
New file
@@ -0,0 +1,80 @@
<?php
namespace app\shop\controller\plus\release;
use app\shop\controller\Controller;
use app\shop\model\plus\release\Cash as CashModel;
/**
 * 提现申请制器
 */
class Cash extends Controller
{
    /**
     * 提现记录列表
     */
    public function index($user_id = null, $apply_status = -1, $pay_type = -1, $search = '')
    {
        $model = new CashModel;
        $list = $model->getList($user_id, $apply_status, $pay_type, $search);
        return $this->renderSuccess('', compact('list'));
    }
    /**
     * 提现审核
     */
    public function submit($id)
    {
        $model = CashModel::detail($id);
        if ($model->submit($this->postData())) {
            return $this->renderSuccess('操作成功');
        }
        return $this->renderError($model->getError() ?: '操作失败');
    }
    /**
     * 确认打款
     */
    public function money($id)
    {
        $model = CashModel::detail($id);
        if ($model->money()) {
            return $this->renderSuccess('操作成功');
        }
        return $this->renderError($model->getError() ?: '操作失败');
    }
    /**
     * 分销商提现:微信支付企业付款
     */
    public function wechat_pay($id)
    {
        $model = CashModel::detail($id);
        if ($model->wechatPay()) {
            return $this->renderSuccess('操作成功');
        }
        return $this->renderError($model->getError() ?: '操作失败');
    }
    /**
     * 分销商提现:分账功能 by yj
     */
    public function fb_pay($id)
    {
        $model = CashModel::detail($id);
        if ($model->fbPay()) {
            return $this->renderSuccess('操作成功');
        }
        return $this->renderError($model->getError() ?: '操作失败');
    }
    /**
     * 订单导出
     */
    public function export($user_id = null, $apply_status = -1, $pay_type = -1, $search = '')
    {
        $model = new CashModel();
        return $model->exportList($user_id, $apply_status, $pay_type, $search);
    }
}
admin/app/shop/controller/plus/release/DemandApply.php
New file
@@ -0,0 +1,38 @@
<?php
namespace app\shop\controller\plus\release;
use app\shop\controller\Controller;
use app\shop\model\plus\release\DemandApply as ApplyModel;
/**
 * 控制器
 */
class DemandApply extends Controller
{
    /**
     * 申请列表
     */
    public function index()
    {
        $model = new ApplyModel;
        $apply_list = $model->getList($this->postData());
        return $this->renderSuccess('', compact('apply_list'));
    }
    /**
     * 审核分销商
     */
    public function editApplyStatus($apply_id)
    {
        $model = ApplyModel::detail($apply_id);
        if ($model->submit($this->postData())) {
            return $this->renderSuccess('修改成功');
        }
        return $this->renderError('修改失败');
    }
}
admin/app/shop/controller/plus/release/DemandProject.php
New file
@@ -0,0 +1,49 @@
<?php
namespace app\shop\controller\plus\release;
use app\shop\controller\Controller;
use app\shop\model\plus\release\DemandProject as ProjectModel;
/**
 * 项目
 */
class DemandProject extends Controller
{
    /**
     * 列表
     */
    public function index()
    {
        $model = new ProjectModel;
        $list = $model->getList($this->postData());
        return $this->renderSuccess('', compact('list'));
    }
    /**
     * 审核
     */
    public function submit($project_id)
    {
        $model = ProjectModel::detail($project_id);
        if ($model->submit($this->postData())) {
            return $this->renderSuccess('操作成功');
        }
        return $this->renderError($model->getError() ?: '操作失败');
    }
    /**
     * 删除
     */
    public function delete($project_id)
    {
        // 详情
        $model = ProjectModel::detail($project_id);
        if (!$model->setDelete()) {
            return $this->renderError('删除失败');
        }
        return $this->renderSuccess('删除成功');
    }
}
admin/app/shop/controller/plus/release/DemandUser.php
New file
@@ -0,0 +1,51 @@
<?php
namespace app\shop\controller\plus\release;
use app\shop\controller\Controller;
use app\shop\model\plus\release\DemandUser as UserModel;
/**
 * 控制器
 */
class DemandUser extends Controller
{
    /**
     * 列表
     */
    public function index()
    {
        $model = new UserModel;
        $list = $model->getList($this->postData());
        return $this->renderSuccess('', compact('list'));
    }
    /**
     * 编辑
     */
    public function edit()
    {
        $user_id = $this->postData('user_id');
        $model = UserModel::detail($user_id);
        if ($this->request->isGet()) {
            return $this->renderSuccess('', compact('model'));
        }
        if ($model->edit($this->postData())) {
            return $this->renderSuccess('更新成功');
        }
        return $this->renderError($model->getError() ?: '更新失败');
    }
    /**
     * 软删除
     */
    public function delete($user_id)
    {
        $model = UserModel::detail($user_id);
        if (!$model->setDelete()) {
            return $this->renderError('删除失败');
        }
        return $this->renderSuccess('删除成功');
    }
}
admin/app/shop/controller/plus/release/Order.php
New file
@@ -0,0 +1,86 @@
<?php
namespace app\shop\controller\plus\release;
use app\shop\controller\Controller;
use app\shop\model\plus\release\Order as OrderModel;
/**
 * 订单
 */
class Order extends Controller
{
    /**
     * 订单列表
     */
    public function index()
    {
        $model = new OrderModel;
        $list = $model->getList($this->postData());
        return $this->renderSuccess('', compact('list'));
    }
    /**
     * 编辑
     */
    public function edit()
    {
        $id = $this->postData('id');
        $model = OrderModel::detail($id);
        // 修改记录
        if ($model->edit($this->postData())) {
            return $this->renderSuccess();
        }
        return $this->renderError();
    }
    /**
     * 线下支付
     */
    public function onCash($id)
    {
        // 订单信息
        $model = OrderModel::detail($id);
        if ($model->onCash($this->postData())) {
            return $this->renderSuccess('操作成功');
        }
        return $this->renderError($model->getError() ?: '操作失败');
    }
    /**
     * 完成订单
     */
    public function onFinish($id)
    {
        // 订单信息
        $model = OrderModel::detail($id);
        if ($model->onFinish($this->postData())) {
            return $this->renderSuccess('操作成功');
        }
        return $this->renderError($model->getError() ?: '操作失败');
    }
    /**
     * 审核:用户取消订单
     */
    public function onCancel($id)
    {
        $model = OrderModel::detail($id);
        if ($model->confirmCancel($this->postData())) {
            return $this->renderSuccess('操作成功');
        }
        return $this->renderError('操作失败');
    }
    /**
     * 订单导出
     */
    public function export()
    {
        $model = new OrderModel();
        return $model->exportList($this->postData());
    }
}
admin/app/shop/controller/plus/release/ReleaseCategory.php
New file
@@ -0,0 +1,63 @@
<?php
namespace app\shop\controller\plus\release;
use app\shop\controller\Controller;
use app\shop\model\plus\release\ReleaseCategory as ReleaseCategoryModel;
/**
 * 商品分类
 */
class ReleaseCategory extends Controller
{
    /**
     * 分类列表
     */
    public function index()
    {
        $model = new ReleaseCategoryModel;
        $list = $model->getList($this->postData());
        return $this->renderSuccess('', compact('list'));
    }
    /**
     * 删除商品分类
     */
    public function delete($category_id)
    {
        $model = (new ReleaseCategoryModel())->find($category_id);
        if ($model->setDelete()) {
            return $this->renderSuccess('删除成功');
        }
        return $this->renderError($model->getError() ?:'删除失败');
    }
    /**
     * 添加商品分类
     */
    public function add()
    {
        $model = new ReleaseCategoryModel;
        // 新增记录
        $postData = $this->request->post();
        if ($model->add($postData)) {
            return $this->renderSuccess('添加成功');
        }
        return $this->renderError($model->getError() ?:'添加失败');
    }
    /**
     * 编辑商品分类
     */
    public function edit($category_id)
    {
        // 模板详情
        $model = ReleaseCategoryModel::detail($category_id);
        // 更新记录
        if ($model->edit($this->request->post())) {
            return $this->renderSuccess('更新成功');
        }
        return $this->renderError($model->getError() ?: '更新失败');
    }
}
admin/app/shop/controller/plus/release/Setting.php
New file
@@ -0,0 +1,139 @@
<?php
namespace app\shop\controller\plus\release;
use app\common\model\settings\Setting as SettingModel;
use app\shop\controller\Controller;
use app\shop\model\plus\release\Setting as ReleaseSettingModel;
use app\shop\model\product\Product as ProductModel;
/**
 * 设置控制器
 */
class Setting extends Controller
{
    public $pay_type = [
        ['id' => '10', 'name' => '微信支付'],
        ['id' => '20', 'name' => '支付宝'],
        ['id' => '30', 'name' => '银行卡']
    ];
    public $pay_type1 = [
        10 => '微信支付',
        20 => '支付宝',
        30 => '银行卡'
    ];
    /**
     * 设置
     */
    public function index()
    {
        $pay_type = $this->pay_type;
        $data = ReleaseSettingModel::getAll();
        return $this->renderSuccess('', compact('data','pay_type'));
    }
    /**
     * 基础信息设置
     */
    public function basic()
    {
        $param = $this->postData();
        $data['basic'] = $param;
        return $this->edit($data);
    }
    /**
     * 条件设置
     */
    public function condition()
    {
        $param = $this->postData();
        $data['condition'] = $param;
        return $this->edit($data);
    }
    /**
     * 佣金设置
     */
    public function commission()
    {
        $param = $this->postData();
        $data['commission'] = $param;
        return $this->edit($data);
    }
    /**
     * 结算设置
     */
    public function settlement()
    {
        $param = $this->postData('form');
        $data['settlement'] = $param;
        return $this->edit($data);
    }
    /**
     * 自定义文字设置
     */
    public function words()
    {
        $param = $this->postData();
        $data['words'] = $param;
        return $this->edit($data);
    }
    /**
     * 申请协议设置
     */
    public function license()
    {
        $param = $this->postData();
        $data['license'] = $param;
        return $this->edit($data);
    }
    /**
     * 页面背景设置
     */
    public function background()
    {
        $param = $this->postData();
        $data['background'] = $param;
        return $this->edit($data);
    }
    /**
     * 修改
     */
    public function edit($data)
    {
        $model = new ReleaseSettingModel;
        if ($model->edit($data)) {
            return $this->renderSuccess('更新成功');
        }
        return $this->renderError($model->getError() ?: '更新失败');
    }
    /**
     * 分销海报
     */
    public function qrcode()
    {
        if (!$this->request->post()) {
            $data = RepairSettingModel::getItem('qrcode');
            return $this->renderSuccess('', ['data' => $data]);
        }
        $model = new RepairSettingModel;
        if ($model->edit(['qrcode' => $this->postData('form')])) {
            return $this->renderSuccess('更新成功');
        }
        return $this->renderError($model->getError() ?: '更新失败');
    }
}
admin/app/shop/controller/plus/release/SupplyApply.php
New file
@@ -0,0 +1,38 @@
<?php
namespace app\shop\controller\plus\release;
use app\shop\controller\Controller;
use app\shop\model\plus\release\SupplyApply as ApplyModel;
/**
 * 控制器
 */
class SupplyApply extends Controller
{
    /**
     * 分销商申请列表
     */
    public function index()
    {
        $model = new ApplyModel;
        $apply_list = $model->getList($this->postData());
        return $this->renderSuccess('', compact('apply_list'));
    }
    /**
     * 审核分销商
     */
    public function editApplyStatus($apply_id)
    {
        $model = ApplyModel::detail($apply_id);
        if ($model->submit($this->postData())) {
            return $this->renderSuccess('修改成功');
        }
        return $this->renderError('修改失败');
    }
}
admin/app/shop/controller/plus/release/SupplyProject.php
New file
@@ -0,0 +1,48 @@
<?php
namespace app\shop\controller\plus\release;
use app\shop\controller\Controller;
use app\shop\model\plus\release\SupplyProject as ProjectModel;
/**
 * 项目
 */
class SupplyProject extends Controller
{
    /**
     * 列表
     */
    public function index()
    {
        $model = new ProjectModel;
        $list = $model->getList($this->postData());
        return $this->renderSuccess('', compact('list'));
    }
/**
     * 审核
     */
    public function submit($project_id)
    {
        $model = ProjectModel::detail($project_id);
        if ($model->submit($this->postData())) {
            return $this->renderSuccess('操作成功');
        }
        return $this->renderError($model->getError() ?: '操作失败');
    }
    /**
     * 删除
     */
    public function delete($project_id)
    {
        // 详情
        $model = ProjectModel::detail($project_id);
        if (!$model->setDelete()) {
            return $this->renderError('删除失败');
        }
        return $this->renderSuccess('删除成功');
    }
}
admin/app/shop/controller/plus/release/SupplyUser.php
New file
@@ -0,0 +1,51 @@
<?php
namespace app\shop\controller\plus\release;
use app\shop\controller\Controller;
use app\shop\model\plus\release\SupplyUser as UserModel;
/**
 * 控制器
 */
class SupplyUser extends Controller
{
    /**
     * 列表
     */
    public function index()
    {
        $model = new UserModel;
        $list = $model->getList($this->postData());
        return $this->renderSuccess('', compact('list'));
    }
    /**
     * 编辑
     */
    public function edit()
    {
        $user_id = $this->postData('user_id');
        $model = UserModel::detail($user_id);
        if ($this->request->isGet()) {
            return $this->renderSuccess('', compact('model'));
        }
        if ($model->edit($this->postData())) {
            return $this->renderSuccess('更新成功');
        }
        return $this->renderError($model->getError() ?: '更新失败');
    }
    /**
     * 软删除
     */
    public function delete($user_id)
    {
        $model = UserModel::detail($user_id);
        if (!$model->setDelete()) {
            return $this->renderError('删除失败');
        }
        return $this->renderSuccess('删除成功');
    }
}
admin/app/shop/controller/plus/release/Tag.php
New file
@@ -0,0 +1,66 @@
<?php
namespace app\shop\controller\plus\release;
use app\shop\controller\Controller;
use app\shop\model\plus\release\Tag as TagModel;
/**
 * 标签
 */
class Tag extends Controller
{
    /**
     * 列表
     */
    public function index()
    {
        $model = new TagModel;
        $list = $model->getList($this->postData());
        return $this->renderSuccess('', compact('list'));
    }
    /**
     * 添加
     */
    public function add()
    {
        $model = new TagModel;
        // 新增记录
        if ($model->add($this->postData())) {
            return $this->renderSuccess('添加成功');
        }
        return $this->renderError('添加失败');
    }
    /**
     * 编辑
     */
    public function edit()
    {
        $tag_id = $this->postData('tag_id');
        $model = TagModel::detail($tag_id);
        if($this->request->isGet()){
            return $this->renderSuccess('', compact( 'model'));
        }
        // 修改记录
        if ($model->edit($this->postData())) {
            return $this->renderSuccess();
        }
        return $this->renderError();
    }
    /**
     * 删除
     */
    public function delete($tag_id)
    {
        // 详情
        $model = TagModel::detail($tag_id);
        if (!$model->setDelete()) {
            return $this->renderError('删除失败');
        }
        return $this->renderSuccess('删除成功');
    }
}
admin/app/shop/controller/plus/shareholder/Setting.php
@@ -7,6 +7,7 @@
use app\shop\controller\Controller;
use app\shop\model\plus\shareholder\Setting as shareholderSettingModel;
use app\shop\model\product\Product as ProductModel;
use app\shop\model\user\Grade as userGradeModel;
/**
 * 分销设置控制器
@@ -39,7 +40,8 @@
        if(count($product_ids) > 0){
            $productList = (new ProductModel)->getListByIds($product_ids);
        }
        return $this->renderSuccess('', compact('data', 'productList', 'pay_type'));
        $userGradeList=(new userGradeModel)->getLists();
        return $this->renderSuccess('', compact('data', 'productList', 'pay_type','userGradeList'));
    }
    /**
admin/app/shop/controller/plus/team/Setting.php
@@ -7,6 +7,7 @@
use app\shop\controller\Controller;
use app\shop\model\plus\team\Setting as teamSettingModel;
use app\shop\model\product\Product as ProductModel;
use app\shop\model\user\Grade as userGradeModel;
/**
 * 分销设置控制器
@@ -41,7 +42,8 @@
        if(count($product_ids) > 0){
            $productList = (new ProductModel)->getListByIds($product_ids);
        }
        return $this->renderSuccess('', compact('data', 'productList', 'pay_type'));
        $userGradeList=(new userGradeModel)->getLists();
        return $this->renderSuccess('', compact('data', 'productList', 'pay_type','userGradeList'));
    }
    /**
admin/app/shop/model/order/Order.php
@@ -318,4 +318,16 @@
            ->order(['order.create_time' => 'desc'])
            ->paginate($params);
    }
    public function getUserTotalConsumption($userId,$bonusData)
    {
        $model = $this;
        $model = $model->where('user_id', '=', $userId)
            ->where('pay_status', '=', 20)
            ->where('order_status', '=', 30)
            ->where('is_delete', '=', 0)
            ->where('create_time', '>=', $bonusData['start_time'])
            ->where('create_time', '<', $bonusData['end_time']);
        return $model->sum('pay_price');
    }
}
admin/app/shop/model/order/OrderProduct.php
@@ -103,4 +103,23 @@
        return 0;
    }
    public static function getPurchaseCount($userId, $postData,$product_ids)
    {
        $model = new static();
        //搜索时间段
        if (!empty($postData['create_time'])) {
            $sta_time = array_shift($postData['create_time']);
            $end_time = array_pop($postData['create_time']);
            $model = $model->whereBetweenTime('order.create_time', $sta_time, date('Y-m-d 23:59:59', strtotime($end_time)));
        }
        return $model->alias('o_product')
            ->join('order', 'order.order_id = o_product.order_id')
            ->where('order.pay_status', '=', OrderPayStatusEnum::SUCCESS)
            ->where('order.order_status', '<>', OrderStatusEnum::CANCELLED)
            ->where('o_product.user_id', '=', $userId)
            ->where('o_product.product_id', 'in', $product_ids)
            ->group('o_product.product_id')
            ->sum("total_num");
    }
}
admin/app/shop/model/plus/release/Capital.php
New file
@@ -0,0 +1,13 @@
<?php
namespace app\shop\model\plus\release;
use app\common\model\plus\release\Capital as CapitalModel;
/**
 * 资金明细模型
 */
class Capital extends CapitalModel
{
}
admin/app/shop/model/plus/release/Cash.php
New file
@@ -0,0 +1,339 @@
<?php
namespace app\shop\model\plus\release;
use app\common\library\easywechat\AppWx;
use app\common\library\easywechat\AppMp;
use app\common\model\app\AppMp as AppMpModel;
use app\common\model\app\AppOpen as AppOpenModel;
use app\common\model\app\AppWx as AppWxModel;
use app\common\model\plus\release\Setting;
use app\common\service\message\MessageService;
use app\common\service\order\OrderService;
use app\common\library\easywechat\WxPay;
use app\common\model\plus\release\Cash as CashModel;
use app\shop\model\user\User as UserModel;
use app\shop\service\order\ExportService;
use app\common\library\fbpay\FbPay;
use app\shop\model\user\UserAuth;
use app\shop\model\shop\FbCashApply;
/**
 * 提现明细模型
 */
class Cash extends CashModel
{
    /**
     * 获取器:申请时间
     */
    public function getAuditTimeAttr($value)
    {
        return $value > 0 ? date('Y-m-d H:i:s', $value) : 0;
    }
    /**
     * 获取器:打款方式
     */
    public function getPayTypeAttr($value)
    {
        return ['text' => $this->payType[$value], 'value' => $value];
    }
    /**
     * 获取提现列表
     */
    public function getList($user_id = null, $apply_status = -1, $pay_type = -1, $search = '')
    {
        $model = $this;
        // 构建查询规则
        $model = $model->alias('cash')
            ->with(['user'])
            ->field('cash.*, release.real_name, release.mobile, user.nickName, user.avatarUrl')
            ->join('user', 'user.user_id = cash.user_id')
            ->join('release_supply_user release', 'release.user_id = cash.user_id')
            ->order(['cash.create_time' => 'desc']);
        // 查询条件
        if ($user_id > 0) {
            $model = $model->where('cash.user_id', '=', $user_id);
        }
        if (!empty($search)) {
            $model = $model->where('release.real_name|repair.mobile', 'like', '%' . $search . '%');
        }
        if ($apply_status > 0) {
            $model = $model->where('cash.apply_status', '=', $apply_status);
        }
        if ($pay_type > 0) {
            $model = $model->where('cash.pay_type', '=', $pay_type);
        }
        // 获取列表数据
        return $model->paginate(15);
    }
    /**
     * 提现审核
     */
    public function submit($param)
    {
        $data = ['apply_status' => $param['apply_status']];
        if ($param['apply_status'] == 30) {
            $data['reject_reason'] = $param['reject_reason'];
        }
        // 更新申请记录
        $data['audit_time'] = time();
        self::update($data, ['id' => $param['id']]);
        // 提现驳回:解冻资金
        if ($param['apply_status'] == 30) {
            SupplyUser::backFreezeMoney($param['user_id'], $param['money']);
        }
        // 发送模板消息
       // (new MessageService)->cash($this);
        return true;
    }
    /**
     * 确认已打款
     */
    public function money()
    {
        $this->startTrans();
        try {
            // 更新申请状态
            $data = ['apply_status' => 40, 'audit_time' => time()];
            self::update($data, ['id' => $this['id']]);
            // 更新分销商累积提现佣金
            SupplyUser::totalMoney($this['user_id'], $this['money']);
            // 记录资金明细
            Capital::add([
                'user_id' => $this['user_id'],
                'flow_type' => 20,
                'money' => -$this['money'],
                'describe' => '申请提现',
            ]);
            // 发送模板消息
           //(new Message)->withdraw($this);
            // 事务提交
            $this->commit();
            return true;
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            $this->rollback();
            return false;
        }
    }
    /**
     * 分销商提现:微信支付企业付款
     */
    public function wechatPay()
    {
        $settlement = Setting::getItem('settlement');
        if($settlement['wechat_type'] == 0){
            return $this->wechatPay0();
        }else {
            return $this->wechatPay1();
        }
    }
    /**
     * 分销商提现:微信支付企业付款
     */
    public function wechatPay0()
    {
        // 微信用户信息
        $user = UserModel::detail($this['user_id']);
        // 生成付款订单号
        $orderNO = OrderService::createOrderNo();
        // 付款描述
        $desc = '供应方提现付款';
        // 微信支付api:企业付款到零钱
        $open_id = '';
        $app = [];
        if($user['reg_source'] == 'mp'){
            $app = AppMp::getWxPayApp($user['app_id']);
            $open_id = $user['mpopen_id'];
        }else if($user['reg_source'] == 'wx'){
            $app = AppWx::getWxPayApp($user['app_id']);
            $open_id = $user['open_id'];
        }
        if($open_id == ''){
            $this->error = '未找到用户open_id';
            return false;
        }
        $WxPay = new WxPay($app);
        // 请求付款api
        if ($WxPay->transfers($orderNO, $open_id, $this['money'], $desc)) {
            // 确认已打款
            $this->money();
            return true;
        }
        return false;
    }
     /**
     * 商家转账到零钱
     */
    public function wechatPay1()
    {
        // 微信用户信息
        $user = UserModel::detail($this['user_id']);
        // 生成付款订单号
        $orderNO = OrderService::createOrderNo();
        // 付款描述
        $desc = '余额提现付款';
        // 微信支付api:企业付款到零钱
        $open_id = '';
        $app_id = '';
        if ($user['reg_source'] == 'mp') {
            $open_id = $user['mpopen_id'];
            $wxConfig = AppMpModel::getAppMpCache($app_id);
            $app_id = $wxConfig['mpapp_id'];
        } else if ($user['reg_source'] == 'wx') {
            $open_id = $user['open_id'];
            $wxConfig = AppWxModel::getAppWxCache($app_id);
            $app_id = $wxConfig['wxapp_id'];
        } else if ($user['reg_source'] == 'app') {
            $open_id = $user['appopen_id'];
            $wxConfig = AppOpenModel::getAppOpenCache($app_id);
            $app_id = $wxConfig['openapp_id'];
        }
        if ($open_id == '') {
            $this->error = '未找到用户open_id';
            return false;
        }
        $pars = [];
        $pars['appid'] = $app_id;//直连商户的appid
        $pars['out_batch_no'] = 'sjzz'.date('Ymd').mt_rand(1000, 9999);//商户系统内部的商家批次单号,要求此参数只能由数字、大小写字母组成,在商户系统内部唯一
        $pars['batch_name']   = $desc;//该笔批量转账的名称
        $pars['batch_remark'] = $desc;//转账说明,UTF8编码,最多允许32个字符
        $pars['total_amount'] = intval($this['money'] * 100);//转账总金额 单位为“分”
        $pars['total_num']    = 1;//转账总笔数
        $pars['transfer_detail_list'][0]  = [
            'out_detail_no'=>'Dh'.$orderNO,
            'transfer_amount'=>$pars['total_amount'],
            'transfer_remark'=> $desc,
            'openid' => $open_id
        ];//转账明细列表
        //获取token
        $wxPay = new WxPay(null);
        $res = $wxPay->wechatTrans($pars, $user['app_id']);
        $resArr = json_decode($res,true);
        if(isset($resArr['batch_id'])){
            $this->save([
                'batch_id' => $resArr['batch_id']
            ]);
            // 确认打款
            $this->money();
            return true;
        }else{
            $this->error = $resArr['message'];
            return false;
        }
    }
    /**
     * 提现:分账功能
     */
    public function fbPay()
    {
        // 用户认证的信息
        $userAuth = UserAuth::detail($this['user_id']);
        if(empty($userAuth)){
            $this->error = '该用户未实名认证';
            return false;
        }elseif(!empty($userAuth) && empty($userAuth["account_id"])){
            $this->error = '该用户实名认证还未审核通过';
            return false;
        }
        //获取向付呗申请的记录
        $where["cash_id"] = $this['id'];
        $apply = FbCashApply::detail($where);
        if(empty($apply)){
            //只生成一次订单 否则造成多次打同一笔款
            $merchant_order_sn = OrderService::createOrderNo();
            // 更新订单号:用于回调 更新打款状态
            $save_data = [
                'merchant_order_sn' => $merchant_order_sn,
                'cash_id' => $this['id'],
                'type' => 'agent',
                'user_id' => $this['user_id'],
            ];
            $model =new FbCashApply();
            $model->save($save_data);
        }else{
            $merchant_order_sn = $apply['merchant_order_sn'];
        }
        // 分账接收方ID
        $data["account_id"] = $userAuth["account_id"];
        // 生成付款订单号
        $data["merchant_order_sn"] = $merchant_order_sn;
        //打款金额
        $data["amount"]=$this['real_money'];
        //如果是付呗接口,配置参数 by yj
        $app = FbPay::getFbPayApp($userAuth["app_id"], 'wx');
        $FbPay = new FbPay($app);
        // 请求分账api
        if ($FbPay->withdraw($data)) {
            return true;
        }
        return false;
    }
    /*
     *统计提现总数量
     */
    public function getAgentOrderTotal()
    {
        return $this->count('id');
    }
    /*
    * 统计提现待审核总数量
    */
    public function getAgentApplyTotal($apply_status)
    {
        return $this->where('apply_status', '=', $apply_status)->count();
    }
    /**
     * 导出提现
     */
    public function exportList($user_id = null, $apply_status = -1, $pay_type = -1, $search = '')
    {
        $model = $this;
        // 构建查询规则
        $model = $model->alias('cash')
            ->with(['user'])
            ->field('cash.*, repair.real_name, repair.mobile, user.nickName, user.avatarUrl')
            ->join('user', 'user.user_id = cash.user_id')
            ->join('release_supply_user repair', 'repair.user_id = cash.user_id')
            ->order(['cash.create_time' => 'desc']);
        // 查询条件
        if ($user_id > 0) {
            $model = $model->where('cash.user_id', '=', $user_id);
        }
        if (!empty($search)) {
            $model = $model->where('repair.real_name|repair.mobile', 'like', '%' . $search . '%');
        }
        if ($apply_status > 0) {
            $model = $model->where('cash.apply_status', '=', $apply_status);
        }
        if ($pay_type > 0) {
            $model = $model->where('cash.pay_type', '=', $pay_type);
        }
        // 获取列表数据
        $list = $model->select();
        // 导出excel文件
        (new Exportservice)->cashList($list);
    }
}
admin/app/shop/model/plus/release/DemandApply.php
New file
@@ -0,0 +1,82 @@
<?php
namespace app\shop\model\plus\release;
use app\common\model\plus\release\DemandApply as ApplyModel;
use app\common\model\plus\release\DemandUser as User;
/**
 * 入驻申请模型
 */
class DemandApply extends ApplyModel
{
    /**
     * 获取申请列表
     * @noinspection PhpUndefinedMethodInspection
     */
    public function getList($search)
    {
        $model = $this->alias('apply')
            ->field('apply.*, user.nickName, user.avatarUrl')
            ->join('user', 'user.user_id = apply.user_id')
            ->order(['apply.create_time' => 'desc']);
        if (!empty($search['nick_name'])) {
            $model = $model->where('user.nickName|apply.real_name|apply.mobile', 'like', '%' . $search['nick_name'] . '%');
        }
        // 获取列表数据
        return $model->paginate($search['list_rows']);
    }
    /**
     * 入驻审核
     * @param $data
     * @return bool
     */
    public function submit($data)
    {
        if ($data['apply_status'] == '30' && empty($data['reject_reason'])) {
            $this->error = '请填写驳回原因';
            return false;
        }
        $this->startTrans();
        if ($data['apply_status'] == '20') {
            // 新增
            User::add($data['user_id'], [
                'real_name' => $data['real_name'],
                'mobile' => $data['mobile'],
               // 'province_id' => trim($data['province_id']),
                //'city_id' => trim($data['city_id']),
               // 'region_id' => trim($data['region_id']),
               // 'location_address' => $data['location_address'],
               // 'longitude' => $data['longitude'],
              //  'latitude' => $data['latitude'],
               // 'detail' => $data['detail'],
            ]);
        }
        $save_data = [
            'audit_time' => time(),
            'apply_status' => $data['apply_status'],
            'reject_reason' => $data['reject_reason'],
        ];
        $this->save($save_data);
        $this->commit();
        return true;
    }
    /**
     * 获取申请中的数量
     */
    public static function getApplyCount()
    {
        return (new static())->where('apply_status', '=', 10)->count();
    }
    /**
     * 编辑
     * @param $data
     * @return bool
     */
    public function edit($data)
    {
        return $this->save($data) !== false;
    }
}
admin/app/shop/model/plus/release/DemandProject.php
New file
@@ -0,0 +1,58 @@
<?php
namespace app\shop\model\plus\release;
use app\common\model\plus\release\Project as ProjectModel;
use app\common\model\plus\release\ReleaseProjectImage as ReleaseProjectImageModel;
/**
 * 模型
 */
class DemandProject extends ProjectModel
{
    /**
     * 获取列表记录
     */
    public function getList($data)
    {
        $model = $this;
        // 查询条件
        if (!empty($data['name'])) {
            $model = $model->where('name', 'like', '%' . $data['name'] . '%');
        }
        $list = $model->with('category')->where('project_type', '=', 0)
            ->where('is_delete', '=', 0)
            ->order(['sort' => 'asc', 'create_time' => 'asc'])
            ->paginate($data);
        foreach($list as &$val){
            $val['finish_time'] = empty($val["finish_time"]) ? '' : date('Y-m-d',$val["finish_time"]);
            $val['image_list'] = ReleaseProjectImageModel::getImage($val['project_id']);
        }
        return $list;
    }
     /**
     * 审核
     */
    public function submit($param)
    {
        $data = ['status' => $param['status']];
        if ($param['status'] == 2) {
            $data['reject_reason'] = $param['reject_reason'];
        }
        // 更新申请记录
        $data['audit_time'] = time();
        self::update($data, ['project_id' => $param['project_id']]);
        return true;
    }
    /**
     * 软删除
     */
    public function setDelete()
    {
        return $this->save(['is_delete' => 1]);
    }
}
admin/app/shop/model/plus/release/DemandUser.php
New file
@@ -0,0 +1,68 @@
<?php
namespace app\shop\model\plus\release;
use app\common\model\plus\release\DemandUser as UserModel;
use app\common\model\user\User as RealUserModel;
/**
 * 用户模型
 * Class User
 * @package app\shop\model\plus\repair
 */
class DemandUser extends UserModel
{
    /**
     * 获取用户列表
     */
    public function getList($data)
    {
        // 构建查询规则
        $model = $this->alias('du')
            ->field('du.*, user.nickName, user.avatarUrl')
            ->join('user', 'user.user_id = du.user_id')
            ->where('du.is_delete', '=', 0)
            ->order(['du.create_time' => 'desc']);
        // 查询条件
        if (!empty($data['nick_name'])) {
            $model = $model->where('user.nickName|du.real_name|du.mobile', 'like', '%' . $data['nick_name'] . '%');
        }
        // 获取列表数据
        $list = $model->paginate($data);
        return $list;
    }
    /**
     * 编辑用户
     * @param $data
     * @return bool
     */
    public function edit($data)
    {
        // 开启事务
        $this->startTrans();
        try {
            $this->save($data);
            $this->commit();
            return true;
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            $this->rollback();
            return false;
        }
    }
    /**
     * 删除
     * @return mixed
     */
    public function setDelete()
    {
        // 标记当前记录为已删除
        return $this->save([
            'is_delete' => 1
        ]);
    }
}
admin/app/shop/model/plus/release/Order.php
New file
@@ -0,0 +1,167 @@
<?php
namespace app\shop\model\plus\release;
use app\common\model\plus\release\Order as OrderModel;
use app\common\model\plus\release\SupplyUser as SupplyUserModel;
use app\shop\service\order\ExportService;
/**
 * 订单模型
 */
class Order extends OrderModel
{
    /**
     * 获取订单列表
     */
    public function getList($search)
    {
        $model = $this
            ->with(['demanduser','supplyuser',"project"])
            ->order(['create_time' => 'desc']);
        if (!empty($search['supply_user_id'])) {
            $model = $model->where('supply_user_id', '=', $search['supply_user_id']);
        }
        if (!empty($search['demand_user_id'])) {
            $model = $model->where('demand_user_id', '=', $search['demand_user_id']);
        }
        if ($search['pay_status'] > -1) {
            $model = $model->where('pay_status', '=', $search['pay_status']);
        }
        if ($search['order_status'] > -1) {
            $model = $model->where('order_status', '=', $search['order_status']);
        }
        if (!empty($search['pay_type'])) {
            $model = $model->where('pay_type', '=', $search['pay_type']);
        }
        //搜索时间段
        if (isset($search['create_time']) && $search['create_time'] != '') {
            $sta_time = array_shift($search['create_time']);
            $end_time = array_pop($search['create_time']);
            $model = $model->whereBetweenTime('create_time', $sta_time, date('Y-m-d 23:59:59', strtotime($end_time)));
        }
        // if (!empty($search['nick_name'])) {
        //     $model = $model->where('user.nickName|order.real_name|order.mobile', 'like', '%' . $search['nick_name'] . '%');
        // }
        // 获取列表数据
        return $model->paginate($search);
    }
    /**
     * 编辑用户
     * @param $data
     * @return bool
     */
    public function edit($data)
    {
        // 开启事务
        $this->startTrans();
        try {
            $this->save($data);
            $this->commit();
            return true;
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            $this->rollback();
            return false;
        }
    }
    /**
     * 获取微信支付的金额
     */
    public function getTotalPayByDate($day,$user_ids=[],$in='true',$pay_type=10,$shop_supplier_id='')
    {
        if(is_array($day)){
            $start = $day[0];
            $end = $day[1];
        }else{
            $start = strtotime($day);
            $end = strtotime($day) + 86399;
        }
        $model = $this;
        if(!empty($user_ids)){
            if($in){
                $model = $model->where('user_id', 'in', $user_ids);
            }else{
                $model = $model->where('user_id', 'not in', $user_ids);
            }
        }
        $money = $model->where('create_time', 'between', "$start,$end")
            ->where('pay_status', '=', 20)
            ->where('pay_type', '=', $pay_type)
            ->sum("pay_price");
        return $money;
    }
    /**
     * 确认线下已支付
     */
    public function onCash($data)
    {
        if (
            $this['pay_status'] != 10
        ) {
            $this->error = '该订单不满足线下支付条件';
            return false;
        }
        return $this->transaction(function () use ($data) {
            $save_data=[
                'pay_status'=>20,
                'pay_time'=>time(),
                'pay_type'=>40,
            ];
            return $this->where("id","=",$data["id"])->save($save_data);
        });
    }
    /**
     * 确认已完成订单
     */
    public function onFinish($data)
    {
        if (
            $this['pay_status'] != 20
            || $this['order_status'] != 10
        ) {
            $this->error = '该订单不满足完成的条件';
            return false;
        }
        return $this->transaction(function () use ($data) {
            //给供应方发放佣金
            (new SupplyUserModel())->where("user_id","=",$this["supply_user_id"])->inc("money",$this["money"])->update();
            $save_data=[
                'order_status'=>30,
                'finish_time'=>time(),
            ];
            return $this->where("id","=",$data["id"])->save($save_data);
        });
    }
    /**
     * 取消订单
     */
    public function confirmCancel($user)
    {
        if ($this['order_status'] == 30) {
            $this->error = '已完成不可取消';
            return false;
        }
        //订单不能取消
        if($this['order_status'] != 10){
            $this->error = '该订单取消失败';
            return false;
        }
        // 订单取消事件
        return $this->transaction(function () use ($user) {
            // 更新订单状态
            return $this->save(['order_status' => 20]);
        });
    }
}
admin/app/shop/model/plus/release/ReleaseCategory.php
New file
@@ -0,0 +1,45 @@
<?php
namespace app\shop\model\plus\release;
use app\common\model\plus\release\ReleaseCategory as ReleaseCategoryModel;
/**
 * 分类模型
 */
class ReleaseCategory extends ReleaseCategoryModel
{
    /**
     * 获取列表记录
     */
    public function getList()
    {
        return $this->where('is_delete', '=', 0)
            ->order(['sort' => 'asc', 'create_time' => 'asc'])
            ->select();
    }
    /**
     * 添加新记录
     */
    public function add($data)
    {
        $data['app_id'] = self::$app_id;
        return $this->save($data);
    }
    /**
     * 编辑记录
     */
    public function edit($data)
    {
        return $this->save($data) !== false;
    }
     /**
     * 软删除
     */
    public function setDelete()
    {
        return $this->save(['is_delete' => 1]);
    }
}
admin/app/shop/model/plus/release/Setting.php
New file
@@ -0,0 +1,83 @@
<?php
namespace app\shop\model\plus\release;
use think\facade\Cache;
use app\common\model\plus\release\Setting as SettingModel;
/**
 * 设置模型
 */
class Setting extends SettingModel
{
    /**
     * 设置项描述
     * @var array
     */
    private $describe = [
        'basic' => '基础设置',
        'condition' => '分销商条件',
        'commission' => '佣金设置',
        'settlement' => '结算',
        'words' => '自定义文字',
        'license' => '申请协议',
        'background' => '页面背景图',
        'template_msg' => '模板消息',
        'qrcode' => '分销海报',
    ];
    /**
     * 更新系统设置
     */
    public function edit($data)
    {
        $this->startTrans();
        try {
            foreach ($data as $key => $values)
                $this->saveValues($key, $values);
            $this->commit();
            // 删除系统设置缓存
            Cache::delete('release_setting_' . self::$app_id);
            return true;
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            $this->rollback();
            return false;
        }
    }
    /**
     * 保存设置项
     */
    private function saveValues($key, $values)
    {
        $where['key'] = $key;
        $res = $this->where($where)->select()->count();
        $data = [
            'describe' => $this->describe[$key],
            'values' => $values,
            'app_id' => self::$app_id,
        ];
        if ($res == 1) {
            return self::update($data, $where);
        }
        if ($res == 0) {
            $data['key'] = $key;
            return self::create($data);
        }
    }
    /**
     * 验证结算方式
     */
    private function validSettlement($values)
    {
        if (!isset($values['pay_type']) || empty($values['pay_type'])) {
            $this->error = '请设置 结算-提现方式';
            return false;
        }
        return true;
    }
}
admin/app/shop/model/plus/release/SupplyApply.php
New file
@@ -0,0 +1,82 @@
<?php
namespace app\shop\model\plus\release;
use app\common\model\plus\release\SupplyApply as ApplyModel;
use app\common\model\plus\release\SupplyUser as User;
/**
 * 入驻申请模型
 */
class SupplyApply extends ApplyModel
{
    /**
     * 获取申请列表
     * @noinspection PhpUndefinedMethodInspection
     */
    public function getList($search)
    {
        $model = $this->alias('apply')
            ->field('apply.*, user.nickName, user.avatarUrl')
            ->join('user', 'user.user_id = apply.user_id')
            ->order(['apply.create_time' => 'desc']);
        if (!empty($search['nick_name'])) {
            $model = $model->where('user.nickName|apply.real_name|apply.mobile', 'like', '%' . $search['nick_name'] . '%');
        }
        // 获取列表数据
        return $model->paginate($search['list_rows']);
    }
    /**
     * 入驻审核
     * @param $data
     * @return bool
     */
    public function submit($data)
    {
        if ($data['apply_status'] == '30' && empty($data['reject_reason'])) {
            $this->error = '请填写驳回原因';
            return false;
        }
        $this->startTrans();
        if ($data['apply_status'] == '20') {
            // 新增
            User::add($data['user_id'], [
                'real_name' => $data['real_name'],
                'mobile' => $data['mobile'],
                //'province_id' => trim($data['province_id']),
               // 'city_id' => trim($data['city_id']),
               // 'region_id' => trim($data['region_id']),
               // 'location_address' => $data['location_address'],
                //'longitude' => $data['longitude'],
               // 'latitude' => $data['latitude'],
               // 'detail' => $data['detail'],
            ]);
        }
        $save_data = [
            'audit_time' => time(),
            'apply_status' => $data['apply_status'],
            'reject_reason' => $data['reject_reason'],
        ];
        $this->save($save_data);
        $this->commit();
        return true;
    }
    /**
     * 获取申请中的数量
     */
    public static function getApplyCount()
    {
        return (new static())->where('apply_status', '=', 10)->count();
    }
    /**
     * 编辑
     * @param $data
     * @return bool
     */
    public function edit($data)
    {
        return $this->save($data) !== false;
    }
}
admin/app/shop/model/plus/release/SupplyProject.php
New file
@@ -0,0 +1,62 @@
<?php
namespace app\shop\model\plus\release;
use app\common\model\plus\release\Project as ProjectModel;
use app\common\model\plus\release\ReleaseProjectImage as ReleaseProjectImageModel;
use app\common\model\plus\release\ReleaseProjectTag as ReleaseProjectTagModel;
/**
 * 模型
 */
class SupplyProject extends ProjectModel
{
    /**
     * 获取列表记录
     */
    public function getList($data)
    {
        $model = $this;
        // 查询条件
        if (!empty($data['name'])) {
            $model = $model->where('name', 'like', '%' . $data['name'] . '%');
        }
        $list= $model->with('category')->where('project_type', '=', 1)
            ->where('is_delete', '=', 0)
            ->order(['sort' => 'asc', 'create_time' => 'asc'])
            ->paginate($data);
        foreach($list as &$val){
            $val['finish_time'] = empty($val["finish_time"]) ? '' : date('Y-m-d',$val["finish_time"]);
            $val['image_list'] = ReleaseProjectImageModel::getImage($val['project_id']);
            $val['tag_list'] = ReleaseProjectTagModel::getTagList($val['project_id']);
        }
        return $list;
    }
    /**
     * 审核
     */
    public function submit($param)
    {
        $data = ['status' => $param['status']];
        if ($param['status'] == 2) {
            $data['reject_reason'] = $param['reject_reason'];
        }
        // 更新申请记录
        $data['audit_time'] = time();
        self::update($data, ['project_id' => $param['project_id']]);
        return true;
    }
    /**
     * 软删除
     */
    public function setDelete()
    {
        return $this->save(['is_delete' => 1]);
    }
}
admin/app/shop/model/plus/release/SupplyUser.php
New file
@@ -0,0 +1,92 @@
<?php
namespace app\shop\model\plus\release;
use app\common\model\plus\release\SupplyUser as UserModel;
use app\common\model\user\User as RealUserModel;
/**
 * 用户模型
 * Class User
 * @package app\shop\model\plus\release
 */
class SupplyUser extends UserModel
{
    /**
     * 获取用户列表
     */
    public function getList($data)
    {
        // 构建查询规则
        $model = $this->alias('su')
            ->field('su.*, user.nickName, user.avatarUrl')
            ->join('user', 'user.user_id = su.user_id')
            ->where('su.is_delete', '=', 0)
            ->order(['su.create_time' => 'desc']);
        // 查询条件
        if (!empty($data['nick_name'])) {
            $model = $model->where('user.nickName|su.real_name|su.mobile', 'like', '%' . $data['nick_name'] . '%');
        }
        // 获取列表数据
        $list = $model->paginate($data);
        return $list;
    }
    /**
     * 编辑用户
     * @param $data
     * @return bool
     */
    public function edit($data)
    {
        // 开启事务
        $this->startTrans();
        try {
            $this->save($data);
            $this->commit();
            return true;
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            $this->rollback();
            return false;
        }
    }
    /**
     * 删除
     * @return mixed
     */
    public function setDelete()
    {
        // 标记当前记录为已删除
        return $this->save([
            'is_delete' => 1
        ]);
    }
     /**
     * 提现打款成功:累积提现佣金
     */
    public static function totalMoney($user_id, $money)
    {
        $model = self::detail($user_id);
        return $model->save([
            'freeze_money' => $model['freeze_money'] - $money,
            'total_money' => $model['total_money'] + $money,
        ]);
    }
    /**
     * 提现驳回:解冻资金
     */
    public static function backFreezeMoney($user_id, $money)
    {
        $model = self::detail($user_id);
        return $model->save([
            'money' => $model['money'] + $money,
            'freeze_money' => $model['freeze_money'] - $money,
        ]);
    }
}
admin/app/shop/model/plus/release/Tag.php
New file
@@ -0,0 +1,47 @@
<?php
namespace app\shop\model\plus\release;
use app\common\model\plus\release\Tag as TagModel;
/**
 * 模型
 */
class Tag extends TagModel
{
    /**
     * 获取列表记录
     */
    public function getList()
    {
        return $this->where('is_delete', '=', 0)
            ->order(['sort' => 'asc', 'create_time' => 'asc'])
            ->select();
    }
    /**
     * 新增记录
     */
    public function add($data)
    {
        $data['app_id'] = self::$app_id;
        return $this->save($data);
    }
    /**
     * 编辑记录
     */
    public function edit($data)
    {
        return $this->save($data);
    }
    /**
     * 软删除
     */
    public function setDelete()
    {
        return $this->save(['is_delete' => 1]);
    }
}
admin/app/shop/model/plus/shareholder/Bonus.php
@@ -126,10 +126,10 @@
            $this->error = '没有可用的分红';
            return false;
        }
        // 获取股东数据
        $userList = User::getListAll();
        // 获取满足分红条件的股东数据
        $userList = User::getEligibleListAll($bonusData);
        if ($userList->isEmpty()) {
            $this->error = '没有找到股东,不分红';
            $this->error = '没有找到满足分红条件的股东,不分红';
            return false;
        }
        $this->startTrans();
admin/app/shop/model/plus/shareholder/User.php
@@ -4,7 +4,8 @@
use app\shop\model\plus\shareholder\Referee as RefereeModel;
use app\common\model\plus\shareholder\User as UserModel;
use app\shop\model\order\Order as OrderModel;
use app\shop\model\order\OrderProduct as OrderProductModel;
/**
 * 股东用户模型
 * Class User
@@ -44,6 +45,55 @@
        }
        return $model->where('is_delete', '=', 0)->with(['grade'])->select();
    }
    /**
     * 获取满足分红条件的股东列表
     */
    public static function getEligibleListAll($bonusData)
    {
        // 获取基础设置
        $setting = Setting::getItem('basic');
        // 先获取所有股东
        $model = new static;
        $shareholders = $model->where('is_delete', '=', 0)->with(['grade'])->select();
        // 如果没有设置分红条件,返回所有股东
        if (empty($setting['consumption_amount']) && empty($setting['condition_purchase_count'])) {
            return $shareholders;
        }
        // 过滤满足条件的股东
        $eligibleShareholders = [];
        foreach ($shareholders as $shareholder) {
            $userId = $shareholder['user_id'];
            $isEligible = true;
            // 检查消费金额条件
            if (!empty($setting['consumption_amount'])) {
                $totalConsumption = (new OrderModel)->getUserTotalConsumption($userId,$bonusData);
                if ($totalConsumption < $setting['consumption_amount']) {
                    $isEligible = false;
                }
            }
            // 检查购买次数条件
            if (!empty($setting['condition_purchase_count']) && $isEligible) {
                $purchaseCount = (new OrderProductModel)::getPurchaseCount($userId,$bonusData,$shareholder['product_ids']);
                if ($purchaseCount < $setting['condition_purchase_count']) {
                    $isEligible = false;
                }
            }
            // 如果满足所有条件,添加到结果集中
            if ($isEligible) {
                $eligibleShareholders[] = $shareholder;
            }
        }
        // 转换为 Collection 对象以保持接口一致性
        return collect($eligibleShareholders);
    }
    /**
     * 新增记录
mobile/pages.json
@@ -177,7 +177,8 @@
                    //#endif
                }
            }
        }, /* {
        },
        /* {
            "path": "components/upload/upload",
            "style": {
                "app-plus": {
@@ -186,7 +187,8 @@
                    //#endif
                }
            }
        }, */ {
        }, */
        {
            "path": "pages/agent/index/index",
            "style": {
                "navigationStyle": "custom",
@@ -1043,29 +1045,31 @@
                    }
                }
            },{"path": "my_shop/product_add",
                    "style": {
                        "navigationBarTitleText": "商品添加",
                        "enablePullDownRefresh": false,
                        "app-plus": {
                            //#ifdef H5
                            "titleNView": false
                            //#endif
                        }
            }, {
                "path": "my_shop/product_add",
                "style": {
                    "navigationBarTitleText": "商品添加",
                    "enablePullDownRefresh": false,
                    "app-plus": {
                        //#ifdef H5
                        "titleNView": false
                        //#endif
                    }
                }
                },{"path": "my_shop/product_edit",
                    "style": {
                        "navigationBarTitleText": "商品编辑",
                        "enablePullDownRefresh": false,
                        "app-plus": {
                            //#ifdef H5
                            "titleNView": false
                            //#endif
                        }
            }, {
                "path": "my_shop/product_edit",
                "style": {
                    "navigationBarTitleText": "商品编辑",
                    "enablePullDownRefresh": false,
                    "app-plus": {
                        //#ifdef H5
                        "titleNView": false
                        //#endif
                    }
                }
                }, {
            }, {
                "path": "my_shop/my_shop_data",
                "style": {
                    "navigationBarTitleText": "店铺数据",
@@ -2174,6 +2178,122 @@
                    }
                }
            ]
        },
        {
            "root": "pages3",
            "pages": [{
                    "path": "release/demandapply/apply",
                    "style": {
                        "navigationBarTitleText": "需求方申请",
                        "enablePullDownRefresh": false
                    }
                },
                {
                    "path": "release/supplyapply/apply",
                    "style": {
                        "navigationBarTitleText": "供求方申请",
                        "enablePullDownRefresh": false
                    }
                },
                {
                    "path": "release/demandindex/index",
                    "style": {
                        "navigationBarTitleText": "需求方",
                        "enablePullDownRefresh": false
                    }
                },
                {
                    "path": "release/supplyindex/index",
                    "style": {
                        "navigationBarTitleText": "供求方",
                        "enablePullDownRefresh": false
                    }
                },
                {
                    "path": "release/demandproject/index",
                    "style": {
                        "navigationBarTitleText": "发布需求",
                        "enablePullDownRefresh": false
                    }
                },
                {
                    "path": "release/demandproject/release",
                    "style": {
                        "navigationBarTitleText": "我要发布",
                        "enablePullDownRefresh": false
                    }
                },
                {
                    "path": "release/demandproject/edit",
                    "style": {
                        "navigationBarTitleText": "修改信息",
                        "enablePullDownRefresh": false
                    }
                },
                {
                    "path": "release/supplyproject/index",
                    "style": {
                        "navigationBarTitleText": "发布服务",
                        "enablePullDownRefresh": false
                    }
                },
                {
                    "path": "release/supplyproject/release",
                    "style": {
                        "navigationBarTitleText": "我要发布",
                        "enablePullDownRefresh": false
                    }
                },
                {
                    "path": "release/supplyproject/edit",
                    "style": {
                        "navigationBarTitleText": "修改信息",
                        "enablePullDownRefresh": false
                    }
                },
                {
                    "path": "release/project/list",
                    "style": {
                        "navigationBarTitleText": "供需大厅",
                        "enablePullDownRefresh": false
                    }
                },
                {
                    "path": "release/project/detail",
                    "style": {
                        "navigationBarTitleText": "供需详情",
                        "enablePullDownRefresh": false
                    }
                },
                {
                    "path": "release/demandorder/index",
                    "style": {
                        "navigationBarTitleText": "需求订单",
                        "enablePullDownRefresh": false
                    }
                },
                {
                    "path": "release/supplyorder/index",
                    "style": {
                        "navigationBarTitleText": "供求订单",
                        "enablePullDownRefresh": false
                    }
                },
                {
                    "path": "release/supplycash/apply/apply",
                    "style": {
                        "navigationBarTitleText": "申请提现",
                        "enablePullDownRefresh": false
                    }
                },
                {
                    "path": "release/supplycash/list/list",
                    "style": {
                        "navigationBarTitleText": "提现明细",
                        "enablePullDownRefresh": false
                    }
                }
            ]
        }
    ],
    "globalStyle": {
mobile/pages/product/category.vue
@@ -70,10 +70,37 @@
                                        <view class="shop_body_l_item_info_price">
                                            <view class="f24 shop_red">¥<text class="f32 fb">{{item.product_price}}</text></view>
                                        </view>
                                        <view class="shop_body_l_item_info_others f22">
                                            <view class="shop_body_l_item_info_others_sales">累计成交:{{item.product_sales}}笔</view>
                                        <!-- 购物车操作组件 -->
                                        <view class="cart-action">
                                            <!-- 多规格商品显示选择规格按钮 -->
                                            <view class="spec-select-btn" v-if="item.spec_type === 20" @click.stop="showSpecPopup(item,index)">
                                                <text>选择规格</text>
                                                <!-- 购物车数量徽章 -->
                                                <view class="cart-badge" v-if="(item.cart && item.cart.total_num > 0)">
                                                    <text class="cart-count">{{ item.cart.total_num || 0 }}</text>
                                                </view>
                                            </view>
                                            <!-- 单规格商品显示购物车操作 -->
                                            <template v-else>
                                                <view class="cart-btn-add" v-if="!item.cart.total_num || item.cart.total_num <= 0" @click.stop="addToCart(item,index)">
                                                    <text class="icon iconfont icon-jia"></text>
                                                </view>
                                                <view class="cart-number-controller" v-else>
                                                    <view class="cart-btn-sub" @click.stop="decreaseCart(item,index)">
                                                        <text class="icon iconfont icon-jian"></text>
                                                    </view>
                                                    <view class="cart-number">{{ item.cart.total_num }}</view>
                                                    <view class="cart-btn-add" @click.stop="increaseCart(item,index)">
                                                        <text class="icon iconfont icon-jia"></text>
                                                    </view>
                                                </view>
                                            </template>
                                        </view>
                                        <!-- <view class="shop_body_l_item_info_others f22">
                                            <view class="shop_body_l_item_info_others_sales">累计成交:{{item.product_sales}}笔</view>
                                        </view> -->
                                    </view>
                                </view>
                            </view>
                        </view>
@@ -113,6 +140,60 @@
        </view>
        <tabBar></tabBar>
        <request-loading :loadding='isloadding'></request-loading>
        <!-- 规格选择弹窗 -->
        <view class="spec-popup" :class="specPopupVisible ? 'visible' : ''" @touchmove.stop.prevent="">
            <view class="popup-mask" @click="closeSpecPopup"></view>
            <view class="popup-content" v-if="selectedProduct">
                <view class="popup-header">
                    <image :src="selectedProduct.product_image" mode="aspectFit"></image>
                    <view class="popup-header-info">
                        <view class="price">¥{{ currentPrice }}</view>
                        <view class="stock">库存:{{ currentStock }}</view>
                        <view class="selected-spec">{{ selectedSpecText }}</view>
                    </view>
                    <view class="popup-header-right">
                        <view class="close-btn" @click="closeSpecPopup">
                            <text class="icon iconfont icon-guanbi"></text>
                        </view>
                    </view>
                </view>
                <view class="spec-section" v-if="selectedProduct.spec_type === 20 && selectedProduct.specData">
                    <view class="spec-group" v-for="(specGroup, groupIndex) in selectedProduct.specData.spec_attr" :key="groupIndex">
                        <view class="spec-group-name">{{ specGroup.group_name }}</view>
                        <view class="spec-options">
                            <view
                                class="spec-option"
                                :class="{ active: selectedSpecs[groupIndex] === specItem.item_id }"
                                v-for="(specItem, itemIndex) in specGroup.spec_items"
                                :key="itemIndex"
                                @click="selectSpec(groupIndex, specItem.item_id)"
                            >
                                {{ specItem.spec_value }}
                            </view>
                        </view>
                    </view>
                </view>
                <view class="quantity-section">
                    <view class="quantity-label">数量</view>
                    <view class="quantity-controller">
                        <view class="quantity-btn" :class="{ disabled: quantity <= 1 }" @click="decreaseQuantity">
                            <text class="icon iconfont icon-jian"></text>
                        </view>
                        <view class="quantity-display">{{ quantity }}</view>
                        <view class="quantity-btn" :class="{ disabled: quantity >= currentStock }" @click="increaseQuantity">
                            <text class="icon iconfont icon-jia"></text>
                        </view>
                    </view>
                </view>
                <view class="action-buttons">
                    <button class="add-cart-btn" @click="confirmAddToCart">加入购物车</button>
                </view>
            </view>
        </view>
    </view>
</template>
@@ -141,7 +222,61 @@
                loading: true,
                index_open_city:0,
                city_supplier_ids:[],
                // 购物车相关数据
                cartData: {}, // 存储各商品在购物车中的数量
                // 规格弹窗相关数据
                specPopupVisible: false,
                selectedProduct: null,
                selectedSpecs: [],
                quantity: 1
            };
        },
        computed: {
            selectedSpecText() {
                if (!this.selectedProduct || !this.selectedProduct.specData) return '请选择规格';
                const selectedNames = this.selectedSpecs
                    .map((specId, index) => {
                        const specGroup = this.selectedProduct.specData.spec_attr[index];
                        if (!specGroup) return '';
                        const selectedItem = specGroup.spec_items.find(item => item.item_id === specId);
                        return selectedItem ? selectedItem.spec_value : '';
                    })
                    .filter(name => name !== '');
                return selectedNames.length > 0 ? `已选: "${selectedNames.join(' ')}"` : '请选择规格';
            },
            // 根据选中的规格获取当前SKU
            currentSku() {
                if (!this.selectedProduct || !this.selectedProduct.sku || this.selectedSpecs.includes(null) || this.selectedSpecs.includes(undefined)) {
                    return null;
                }
                const specSkuId = this.selectedSpecs.join('_');
                return this.selectedProduct.sku.find(sku => sku.spec_sku_id === specSkuId);
            },
            // 获取当前选中规格的价格
            currentPrice() {
                if (this.currentSku) {
                    return this.currentSku.product_price;
                }
                return this.selectedProduct ? this.selectedProduct.product_price : '0.00';
            },
            // 获取当前选中规格的库存
            currentStock() {
                if (this.currentSku) {
                    return this.currentSku.stock_num;
                }
                return this.selectedProduct ? this.selectedProduct.product_stock : 0;
            },
        },
        mounted() {
            this.init();
@@ -293,6 +428,229 @@
                    path: '/pages/product/category?' + self.getShareUrlParams()
                };
            },
            // 添加到购物车或显示规格选择
            addToCartOrShowSpec(product,index) {
                if (product.spec_type === 20) {
                    // 多规格商品,显示规格选择弹窗
                    this.showSpecPopup(product);
                } else {
                    // 单规格商品,直接添加到购物车
                    this.directlyAddToCart(product,index);
                }
            },
            // 添加到购物车(单规格商品)
            addToCart(product,index) {
                this.directlyAddToCart(product,index);
            },
            // 直接添加到购物车(单规格商品)
            directlyAddToCart(product,index) {
                this._post('order.cart/add', {
                    product_id: product.product_id,
                    total_num: 1,
                    spec_sku_id: 0
                }, (res) => {
                    if (res.code === 1) {
                        if(!product.cart){
                            product.cart={
                                total_num:0
                            }
                        }
                        // 更新商品的购物车数量
                        product.cart.total_num++;
                        this.productData[index].cart.total_num = product.cart.total_num;
                    } else {
                        uni.showToast({
                            title: res.msg,
                            icon: 'none'
                        });
                    }
                });
            },
            // 显示规格选择弹窗
            showSpecPopup(product) {
                this.selectedProduct = product;
                this.quantity = 1;
                let url=''
                //#ifdef H5
                if (this.isWeixin()) {
                    url = window.location.href;
                }
                //#endif
                // 获取商品规格数据
                this._get('product.product/detail', {
                    product_id: product.product_id,
                    url:url,
                    visitcode: this.getVisitcode()
                }, (res) => {
                    if (res.code === 1) {
                    // 使用正确的路径获取规格数据
                    let specData = res.data.detail.product_multi_spec || res.data.detail;
                    this.$set(this.selectedProduct, 'specData', specData);
                    // 同时设置SKU数据
                    if (res.data.detail.sku) {
                        this.$set(this.selectedProduct, 'sku', res.data.detail.sku);
                    }
                    console.log(this.selectedSpecs);
                        // 初始化选中规格数组
                    if (specData && specData.spec_attr) {
                        this.selectedSpecs = specData.spec_attr.map(specGroup => {
                            return specGroup.spec_items && specGroup.spec_items.length > 0 ? specGroup.spec_items[0].item_id : null;
                        });
                        this.specPopupVisible = true;
                    } else {
                        uni.showToast({
                            title: '获取商品规格失败',
                            icon: 'none'
                        });
                        return;
                    }
                    } else {
                        uni.showToast({
                            title: '获取商品规格失败',
                            icon: 'none'
                        });
                    }
                });
            },
            // 关闭规格选择弹窗
            closeSpecPopup() {
                this.specPopupVisible = false;
                this.selectedProduct = null;
                this.selectedSpecs = [];
            },
            // 选择规格
            selectSpec(groupIndex, itemId) {
                // 使用 Vue.set 确保响应式更新
                this.$set(this.selectedSpecs, groupIndex, itemId);
            },
            // 增加数量
            increaseQuantity() {
                if (this.quantity < this.currentStock) {
                    this.quantity++;
                }
            },
            // 减少数量
            decreaseQuantity() {
                if (this.quantity > 1) {
                    this.quantity--;
                }
            },
            // 确认添加到购物车
            confirmAddToCart() {
                // 检查是否选择了所有规格
                if (this.selectedSpecs.includes(null) || this.selectedSpecs.includes(undefined)) {
                    uni.showToast({
                        title: '请选择完整的商品规格',
                        icon: 'none'
                    });
                    return;
                }
                // 构造规格SKU ID
                const specSkuId = this.selectedSpecs.join('_');
                this._post('order.cart/add', {
                    product_id: this.selectedProduct.product_id,
                    total_num: this.quantity,
                    spec_sku_id: specSkuId?specSkuId:0
                }, (res) => {
                    if (res.code === 1) {
                        // 更新商品的购物车数量
                        const product = this.productData.find(p => p.product_id === this.selectedProduct.product_id);
                        if (product) {
                            if(!product.cart){
                                product.cart={
                                    total_num:0
                                }
                            }
                            product.cart.total_num++;
                        }
                        // 关闭弹窗
                        this.closeSpecPopup();
                        uni.showToast({
                            title: '已添加到购物车',
                            icon: 'success'
                        });
                    } else {
                        uni.showToast({
                            title: res.msg,
                            icon: 'none'
                        });
                    }
                });
            },
            // 增加购物车商品数量
            increaseCart(product,index) {
                this._post('order.cart/add', {
                    product_id: product.product_id,
                    total_num: 1,
                    spec_sku_id: 0
                }, (res) => {
                    if (res.code === 1) {
                        product.cart.total_num++;
                        this.productData[index].cart.total_num = product.cart.total_num;
                    } else {
                        uni.showToast({
                            title: res.msg,
                            icon: 'none'
                        });
                    }
                });
            },
            // 减少购物车商品数量
            decreaseCart(product,index) {
                if (product.cart.total_num <= 1) {
                    // 如果数量为1,执行删除操作
                    this._post('order.cart/delete', {
                        product_id: product.product_id,
                        cart_id: product.cart.cart_id,
                        spec_sku_id:product.product_sku.spec_sku_id
                    }, (res) => {
                        if (res.code === 1) {
                            this.productData[index].cart.total_num=0;
                        } else {
                            uni.showToast({
                                title: res.msg,
                                icon: 'none'
                            });
                        }
                    });
                } else {
                    // 否则减少数量
                    this._post('order.cart/sub', {
                        product_id: product.product_id,
                        spec_sku_id:product.product_sku.spec_sku_id
                    }, (res) => {
                        if (res.code === 1) {
                            product.cart.total_num--;
                            this.productData[index].cart.total_num = product.cart.total_num;
                        } else {
                            uni.showToast({
                                title: res.msg,
                                icon: 'none'
                            });
                        }
                    });
                }
            }
        }
    };
</script>
@@ -484,6 +842,7 @@
        flex-direction: column;
        padding-left: 20rpx;
        box-sizing: border-box;
        position: relative;
    }
    
    .shop_body_l_item_info_title {
@@ -617,4 +976,262 @@
    .noborder {
        border: none;
    }
    /* 购物车操作样式 */
    .cart-action {
        /* position: absolute;
        right: 0;
        bottom: 0; */
    }
    .cart-btn-add, .cart-btn-sub {
        width: 48rpx;
        height: 48rpx;
        border-radius: 50%;
        background: #ff6b6b;
        display: flex;
        align-items: center;
        justify-content: center;
        color: white;
        font-size: 24rpx;
    }
    .spec-select-btn {
        padding: 2rpx 4rpx;
        background: #ff6b6b;
        color: white;
        border-radius: 24rpx;
        font-size: 24rpx;
        display: flex;
        align-items: center;
        justify-content: center;
        min-width: 120rpx;
        height: 48rpx;
        position: relative;
    }
    .cart-btn-sub {
        background: #f0f0f0;
        color: #666;
    }
    .cart-number {
        margin: 0 10rpx;
        font-size: 28rpx;
    }
    .cart-number-controller {
        display: flex;
        align-items: center;
    }
    /* 规格选择弹窗样式 */
    .spec-popup {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 1000;
        visibility: hidden;
        opacity: 0;
        transition: all 0.3s ease;
    }
    .spec-popup.visible {
        visibility: visible;
        opacity: 1;
    }
    .popup-mask {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: rgba(0, 0, 0, 0.6);
    }
    .popup-content {
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        background: white;
        border-top-left-radius: 20rpx;
        border-top-right-radius: 20rpx;
        padding: 30rpx;
        transform: translateY(100%);
        transition: transform 0.3s ease;
        max-height: 80%;
        overflow-y: auto;
    }
    .spec-popup.visible .popup-content {
        transform: translateY(0);
    }
    .popup-header {
        display: flex;
        position: relative;
        padding-right: 60rpx;
        margin-bottom: 30rpx;
    }
    .popup-header image {
        width: 160rpx;
        height: 160rpx;
        border-radius: 10rpx;
    }
    .popup-header-info {
        margin-left: 20rpx;
        flex: 1;
    }
    .price {
        font-size: 36rpx;
        color: #ff6b6b;
        font-weight: bold;
    }
    .stock {
        font-size: 24rpx;
        color: #999;
        margin-top: 10rpx;
    }
    .selected-spec {
        font-size: 24rpx;
        color: #666;
        margin-top: 10rpx;
    }
    .popup-header-right {
        position: absolute;
        right: 0;
        top: 0;
        display: flex;
        align-items: center;
        gap: 20rpx;
    }
    .cart-badge {
        position: absolute;
        top: -12rpx;
        right: -12rpx;
        background: #ff4757;
        color: white;
        border-radius: 50%;
        min-width: 32rpx;
        height: 32rpx;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 20rpx;
        line-height: 1;
        padding: 0 6rpx;
        z-index: 10;
    }
    .cart-count {
        color: white;
        font-size: 20rpx;
        line-height: 1;
    }
    .close-btn {
        width: 50rpx;
        height: 50rpx;
        display: flex;
        align-items: center;
        justify-content: center;
        color: #999;
    }
    .spec-section {
        margin-bottom: 30rpx;
    }
    .spec-group {
        margin-bottom: 30rpx;
    }
    .spec-group-name {
        font-size: 28rpx;
        font-weight: bold;
        margin-bottom: 20rpx;
    }
    .spec-options {
        display: flex;
        flex-wrap: wrap;
    }
    .spec-option {
        padding: 10rpx 20rpx;
        border: 1rpx solid #ddd;
        border-radius: 10rpx;
        margin-right: 20rpx;
        margin-bottom: 20rpx;
        font-size: 26rpx;
    }
    .spec-option.active {
        border-color: #ff6b6b;
        color: #ff6b6b;
    }
    .quantity-section {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-bottom: 30rpx;
    }
    .quantity-label {
        font-size: 28rpx;
    }
    .quantity-controller {
        display: flex;
        align-items: center;
    }
    .quantity-btn {
        width: 50rpx;
        height: 50rpx;
        border: 1rpx solid #ddd;
        border-radius: 10rpx;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 24rpx;
    }
    .quantity-btn.disabled {
        opacity: 0.5;
    }
    .quantity-display {
        margin: 0 20rpx;
        font-size: 28rpx;
        min-width: 60rpx;
        text-align: center;
    }
    .action-buttons {
        text-align: center;
    }
    .add-cart-btn {
        width: 100%;
        height: 80rpx;
        background: linear-gradient(90deg, #ff6b6b, #ff8e8e);
        border-radius: 40rpx;
        color: white;
        font-size: 32rpx;
        border: none;
    }
</style>
</file>
mobile/pages/shop/shop_list.vue
@@ -47,11 +47,22 @@
                            <view class="shop_list_body_item_shop_info">
                                <view class="h1 title">{{item.name}}</view>
                                <view class="h3 brand">主营:{{item.category_name}}</view>
                                <view class="h3 address-row">
                                    <text class="address-text">地址:{{item.address}}</text>
                                </view>
                                <!-- <view class="h3 sales">销量{{item.product_sales}}件<text class="ml10 mr10">|</text>{{item.fav_count}}人关注</view> -->
                            </view>
                            <view class="shop_list_body_item_shop_others">
                                <view class="f26 gray3 collect">店铺评分</view>
                                <view><text class="redEe f32 fb">{{item.server_score}}</text></view>
                                <view class="action-buttons">
                                    <view @click.stop="contactShop(item)">
                                        <text class="iconfont icon icon-002dianhua action-btn contact-btn"></text>
                                    </view>
                                    <view @click.stop="navigateToShop(item)">
                                        <text class="icon action-btn iconfont nav-btn icon-dizhi1"></text>
                                    </view>
                                </view>
                            </view>
                        </view>
                        <view v-if="shopData[index].productList.length>0" :class="shopData[index].productList.length<3?'shop_list_body_item_product2':'shop_list_body_item_product'">
@@ -277,6 +288,49 @@
            //跳转商品页面
            goto_product(product_id) {
                this.gotoPage('/pages/product/detail/detail?product_id=' + product_id);
            },
            //联系店铺
            contactShop(shop) {
                // 如果有电话号码,直接拨打电话
                if (shop.link_phone) {
                    uni.makePhoneCall({
                        phoneNumber: shop.link_phone,
                        fail: () => {
                            uni.showToast({
                                title: '拨打电话失败',
                                icon: 'none'
                            });
                        }
                    });
                } else {
                    uni.showToast({
                        title: '暂无联系电话',
                        icon: 'none'
                    });
                }
            },
            //导航到店铺
            navigateToShop(shop) {
                if (shop.address) {
                    // 打开地图导航
                    uni.openLocation({
                        latitude: shop.latitude || 0,
                        longitude: shop.longitude || 0,
                        name: shop.name,
                        address: shop.address,
                        fail: () => {
                            uni.showToast({
                                title: '打开导航失败',
                                icon: 'none'
                            });
                        }
                    });
                } else {
                    uni.showToast({
                        title: '暂无店铺地址',
                        icon: 'none'
                    });
                }
            },
            
            /**
@@ -653,6 +707,48 @@
        color: #585858;
    }
    .address-row {
        display: flex;
        align-items: center;
        justify-content: space-between;
        width: 100%;
    }
    .address-text {
        flex: 1;
        color: #585858;
    }
    .action-buttons {
        display: flex;
        align-items: center;
        margin-left: 20rpx;
    }
    .action-btn {
        width: 60rpx;
        height: 60rpx;
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 50%;
        margin-left: 10rpx;
    }
    .contact-btn {
        color: #4caf50;
        font-size: 50rpx;
    }
    .nav-btn {
        font-size: 50rpx;
        color: #2196f3;
    }
    .action-btn .iconfont {
        font-size: 28rpx;
    }
    .sales {
        color: #585858;
    }
mobile/pages/user/my_shop/product_add.vue
@@ -340,15 +340,15 @@
                <view class="form-item">
                    <view class="item-label">详情类型</view>
                    <view class="radio-group">
                        <view class="radio-item" :class="{ active: form.model.content_type === 10 }"
                            @click="form.model.content_type = 10">图文</view>
                        <view class="radio-item" :class="{ active: form.model.content_type === 20 }"
                            @click="form.model.content_type = 20">纯图</view>
                        <view class="radio-item" :class="{ active: form.model.is_picture == 0 }"
                            @click="form.model.is_picture = 0">图文</view>
                        <view class="radio-item" :class="{ active: form.model.is_picture === 1 }"
                            @click="form.model.is_picture = 1">纯图</view>
                    </view>
                </view>
                <!-- 图文类型 -->
                <view v-if="form.model.content_type === 10" class="form-item">
                <view v-if="form.model.is_picture === 0" class="form-item">
                    <view class="item-label">商品详情</view>
                    <view class="editor">
                        <!-- 富文本编辑器 -->
@@ -439,7 +439,7 @@
                </view>
                <!-- 纯图类型 -->
                <view v-else-if="form.model.content_type === 20" class="form-item">
                <view v-else-if="form.model.is_picture == 1" class="form-item">
                    <view class="item-label">商品详情图片</view>
                    <view class="uploader">
                        <view class="uploader-item" v-for="(item, index) in form.model.contentImage" :key="index">
@@ -535,7 +535,7 @@
                        selling_point: '',
                        spec_type: 10,
                        deduct_stock_type: 20,
                        content_type: 10,
                        is_picture: 0,
                        sku: {
                            product_no: '',
                            product_price: '',
@@ -851,7 +851,7 @@
            save() {
                let self = this;
                // 先获取富文本编辑器内容
                if (self.form.model.content_type === 10 && self.editorCtx) {
                if (self.form.model.is_picture == 0 && self.editorCtx) {
                    // 图文类型,获取编辑器内容
                    self.editorCtx.getContents({ 
                        success: (res) => {
@@ -949,7 +949,7 @@
                }
                // 根据详情类型验证内容
                if (self.form.model.content_type === 10) {
                if (self.form.model.is_picture === 0) {
                    // 图文类型,验证富文本内容
                    if (!self.form.model.content || self.form.model.content.trim() === '') {
                        uni.showToast({
@@ -958,7 +958,7 @@
                        });
                        return;
                    }
                } else if (self.form.model.content_type === 20) {
                } else if (self.form.model.is_picture == 1) {
                    // 纯图类型,验证详情图片
                    if (self.form.model.contentImage.length === 0) {
                        uni.showToast({
@@ -968,7 +968,6 @@
                        return;
                    }
                }
                self.loading = true;
                self._post('supplier.product/add', {
                    params: JSON.stringify(self.form.model)
mobile/pages/user/my_shop/product_edit.vue
@@ -47,9 +47,13 @@
                <view class="form-item" v-if="form.model.is_preview === 1">
                    <view class="item-label">预告开启购买时间</view>
                    <picker mode="datetime" class="item-picker" @change="previewTimeChange" :value="previewTimeArray">
                    <uni-datetime-picker class="item-picker"
                        :value="previewTime"
                        @change="previewTimeChange"
                        :start="'1970-01-01'"
                        :end="'2030-12-31'">
                        <view class="picker-text">{{ previewTimeText || '请选择预告时间' }}</view>
                    </picker>
                    </uni-datetime-picker>
                </view>
                <view class="form-item">
@@ -346,15 +350,15 @@
                <view class="form-item">
                    <view class="item-label">详情类型</view>
                    <view class="radio-group">
                        <view class="radio-item" :class="{ active: form.model.content_type === 10 }"
                            @click="form.model.content_type = 10">图文</view>
                        <view class="radio-item" :class="{ active: form.model.content_type === 20 }"
                            @click="form.model.content_type = 20">纯图</view>
                        <view class="radio-item" :class="{ active: form.model.is_picture == 0 }"
                            @click="form.model.is_picture = 0">图文</view>
                        <view class="radio-item" :class="{ active: form.model.is_picture == 1 }"
                            @click="form.model.is_picture = 1">纯图</view>
                    </view>
                </view>
                <!-- 图文类型 -->
                <view v-if="form.model.content_type === 10" class="form-item">
                <view v-if="form.model.is_picture == 0" class="form-item">
                    <view class="item-label">商品详情</view>
                    <view class="editor">
                        <!-- 富文本编辑器 -->
@@ -445,7 +449,7 @@
                </view>
                <!-- 纯图类型 -->
                <view v-else-if="form.model.content_type === 20" class="form-item">
                <view v-else-if="form.model.is_picture == 1" class="form-item">
                    <view class="item-label">商品详情图片</view>
                    <view class="uploader">
                        <view class="uploader-item" v-for="(item, index) in form.model.contentImage" :key="index">
@@ -470,7 +474,7 @@
                    <view class="item-label">积分设置</view>
                    <view class="switch-item">
                        <view class="switch-label">开启积分赠送</view>
                        <switch v-model="form.model.is_points_gift" />
                        <switch :checked="form.model.is_points_gift" v-model="form.model.is_points_gift" />
                    </view>
                    <view class="switch-item">
                        <view class="switch-label">允许积分抵扣</view>
@@ -487,7 +491,7 @@
                    <view class="item-label">团队分红设置</view>
                    <view class="switch-item">
                        <view class="switch-label">是否参与团队分红</view>
                        <switch checked v-model="form.model.is_enable_team" />
                        <switch :checked="form.model.is_enable_team==1?true:false" v-model="form.model.is_enable_team" />
                    </view>
                </view>
            </view>
@@ -519,6 +523,7 @@
                deliveryIndex: 0,
                // 预告时间相关
                previewTimeArray: [now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes()],
                previewTime: '',
                previewTimeText: '',
                // 核销时间相关
                verifyTimeArray: [],
@@ -548,7 +553,7 @@
                        selling_point: '',
                        spec_type: 10,
                        deduct_stock_type: 20,
                        content_type: 10,
                        is_picture: 0,
                        sku: {
                            product_no: '',
                            product_price: '',
@@ -641,20 +646,52 @@
                    product_id: self.productId
                }, (res) => {
                    // 合并默认值和后端返回的数据,确保 spec_many 字段始终存在
                    Object.assign(self.form, res.data);
                    self.form.model = Object.assign({
                        spec_many: {
                            spec_attr: [],
                            spec_list: []
                        }
                    }, res.data.model);
                    // 处理单规格商品的 sku 字段,后端返回的是数组,前端需要对象
                    if (self.form.model.spec_type === 10 && Array.isArray(self.form.model.sku) && self.form.model.sku.length > 0) {
                        self.form.model.sku = self.form.model.sku[0];
                    }
                    self.form.model.product_status = res.data.model.product_status.value;
                    if(self.form.model.delivery_id == 0){
                      self.$set(self.form.model, 'is_delivery_free', 0);
                    }else{
                      self.$set(self.form.model, 'is_delivery_free', 1);
                    }
                    if(self.form.model.notice == null){
                      self.form.model.notice = [];
                    }
                    //修改时审核状态
                    if(self.form.audit_setting.edit_audit == 1 && self.form.scene != 'add'){
                      self.form.model.audit_status = 0;
                    }
                    if (self.form.model.content) {
                        setTimeout(function(){
                            self.editorCtx.setContents({
                                html: self.form.model.content
                            });
                        },1000)
                        }
                    // 设置分类索引
                    self.categoryIndex = self.form.category.findIndex(item => item.category_id === self.form
                        .model.category_id);
                    self.selectedCategory = self.form.category[self.categoryIndex]?.category_name;
                    self.selectedCategory = self.form.category[self.categoryIndex]?.name;
                    // 设置运费模板索引
                    self.deliveryIndex = self.form.delivery.findIndex(item => item.delivery_id === self.form
                        .model.delivery_id);
                    self.selectedDelivery = self.form.delivery[self.deliveryIndex]?.delivery_name;
                    self.selectedDelivery = self.form.delivery[self.deliveryIndex]?.name;
                    // 设置预告时间
                    if (self.form.model.is_preview === 1 && self.form.model.preview_time) {
                        const previewDate = new Date(self.form.model.preview_time * 1000);
                        self.previewTime = previewDate.toISOString().slice(0, 16);
                        self.previewTimeText = self.previewTime;
                    }
                    self.loading = false;
                });
            },
@@ -692,9 +729,9 @@
            // 选择预告时间
            previewTimeChange(e) {
                const date = new Date(e.detail.value);
                this.form.model.preview_time = date.toISOString().slice(0, 19).replace('T', ' ');
                this.previewTimeText =
                    `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
                this.form.model.preview_time = Math.floor(date.getTime() / 1000);
                this.previewTime = e.detail.value;
                this.previewTimeText = e.detail.value;
            },
            // 选择视频
@@ -1020,7 +1057,7 @@
            save() {
                let self = this;
                // 先获取富文本编辑器内容
                if (self.form.model.content_type === 10 && self.editorCtx) {
                if (self.form.model.is_picture == 0 && self.editorCtx) {
                    // 图文类型,获取编辑器内容
                    self.editorCtx.getContents({
                        success: (res) => {
@@ -1118,7 +1155,7 @@
                }
                // 根据详情类型验证内容
                if (self.form.model.content_type === 10) {
                if (self.form.model.is_picture == 0) {
                    // 图文类型,验证富文本内容
                    if (!self.form.model.content || self.form.model.content.trim() === '') {
                        uni.showToast({
@@ -1127,7 +1164,7 @@
                        });
                        return;
                    }
                } else if (self.form.model.content_type === 20) {
                } else if (self.form.model.is_picture == 1) {
                    // 纯图类型,验证详情图片
                    if (self.form.model.contentImage.length === 0) {
                        uni.showToast({
@@ -1137,7 +1174,7 @@
                        return;
                    }
                }
                self.loading = true;
                self._post('supplier.product/edit', {
                    product_id: self.productId,
mobile/pages3/release/demandapply/apply.vue
New file
@@ -0,0 +1,258 @@
<template>
    <view class="apply-team">
        <!--申请成功-->
        <template v-if="!is_applying && is_pass">
            <view class="form-wrap p30 f30">
                <view class="pb30 d-c-c gray3 f40 fb">
                    需求方入驻申请
                </view>
                <form @submit="formCheck" @reset="formReset">
                    <view class="form-item border-b">
                        <view class="field-name">姓名:</view>
                        <input class="flex-1 ml10" name="name" type="text" value="" placeholder-class="grary" placeholder="请输入姓名" />
                    </view>
                    <view class="form-item border-b">
                        <view class="field-name">手机号:</view>
                        <input class="flex-1 ml10" name="mobile" type="number" value="" placeholder-class="grary" placeholder="请输入手机" />
                    </view>
                    <!-- <view class="form-item border-b">
                        <text class="field-name">地址:</text>
                        <input class="flex-1 ml10" name="location_address" type="text"  placeholder-class="grary9" placeholder="请选择地址" v-model="short_address"
                             disabled @click="chooseLocation" />
                    </view> -->
                    <view class="d-c-c mt30">
                        <button class="btn-red" form-type="submit">立即申请</button>
                    </view>
                </form>
                <view class="form-wrap p30 f30" v-if="reason">
                    <view class="d-c-c pt30">
                        <text style=" font-size: 100rpx;" class="icon iconfont icon-icon_xianshi-xian"></text>
                    </view>
                    <view class="p-30-0 d-c-c gray6 f30">
                        上次的申请已被驳回,原因:{{reason}}!
                    </view>
                </view>
            </view>
        </template>
        <!--审核中-->
        <template v-if="is_applying">
            <view class="form-wrap p30 f30">
                <view class="d-c-c pt30">
                    <text style=" font-size: 100rpx;" class="icon iconfont icon-icon_xianshi-xian"></text>
                </view>
                <view class="p-30-0 d-c-c gray6 f30">
                    您的申请正在审核,请耐心等待!
                </view>
            </view>
        </template>
    </view>
</template>
<script>
    import Popup from '@/components/uni-popup.vue'
    export default {
        components: {
            Popup,
        },
        data() {
            return {
                /*弹窗是否打开*/
                isPopup: false,
                is_applying: false,
                is_release:'',
                /*小程序订阅消息*/
                temlIds: [],
                iphone_x: false,
                is_pass: true,
                reason:'',
                releaseData:[],
                province_id: 0,
                city_id: 0,
                region_id: 0,
                address: {},
                location_address: '',
                short_address:'',
            }
        },
        mounted() {
            /*数据*/
            this.getData();
        },
        created() {
            let self = this;
            uni.getSystemInfo({
                success: function (res) {
                    let model = ['X', 'XR', 'XS', '11', '12', '13', '14', '15'];
                    model.forEach(item => {
                        //适配iphoneX以上的底部,给tabbar一定高度的padding-bottom
                        if(res.model.indexOf(item) != -1 && res.model.indexOf('iPhone') != -1) {
                            self.iphone_x = true;
                        }
                    })
                }
            });
        },
        methods: {
            /*获取数据*/
            getData() {
                let self = this;
                uni.showLoading({
                    title: '加载中'
                })
                self._get('plus.release.demandIndex/apply', {
                    platform: self.getPlatform()
                }, function(res) {
                    uni.hideLoading();
                    self.is_applying = res.data.is_applying;
                    self.is_release=res.data.is_release;
                    self.temlIds = res.data.template_arr;
                    self.releaseData = res.data.releaseData;
                    if(self.is_release){
                        uni.navigateBack({});
                    }
                    if(res.data.reason){
                        self.reason = res.data.reason;
                    }
                });
            },
            chooseLocation(n) {
                let self=this;
                 uni.authorize({
                 scope: 'scope.userLocation',
                 success: () => {
                     uni.chooseLocation({
                         success: function (res) {
                            console.log(res)
                             self.address.longitude=res.longitude;
                             self.address.latitude=res.latitude;
                             self.location_address=res.address;
                             // 获取省市区
                            setTimeout(function(){
                                self.setLocationAddress();
                            },500)
                         },fail: function (err) {
                             //console.log(err)
                        }
                     });
                 },
                })
            },
            // 获取省市区 by yj
            setLocationAddress() {
                let self = this;
                self._get('user.address/setLocationAddress', {
                    address: self.location_address
                }, function(res) {
                    self.short_address = res.data.short_address;
                    self.address.location_address = res.data.short_address;
                    self.province_id = res.data.cityCode[0];
                    self.city_id = res.data.cityCode[1];
                    self.region_id = res.data.cityCode[2];
                });
            },
            /*申请*/
            formCheck: function(e) {
                let self = this;
                let formdata = e.detail.value;
                // formdata.province_id = self.province_id;
                // formdata.city_id = self.city_id;
                // formdata.region_id = self.region_id;
                // formdata.longitude = self.address.longitude;
                // formdata.latitude = self.address.latitude;
                // formdata.location_address = self.address.location_address;
                // formdata.detail= self.location_address;
                if(formdata.name==''){
                    uni.showToast({
                        title: '请输入姓名!',
                        icon:'none'
                    });
                    return;
                }
                if(formdata.mobile.length==''){
                    uni.showToast({
                        title: '请输入手机号!',
                        icon: 'none'
                    });
                    return;
                }
                if (!/^1(3|4|5|6|7|8|9)\d{9}$/.test(formdata.mobile)) {
                    uni.showToast({
                        title: '手机有误,请重填!',
                        icon: 'none'
                    });
                    return;
                }
                // if (formdata.province_id == 0 || formdata.city_id == 0 || formdata.region_id == 0 || formdata.location_address == '') {
                //     uni.showToast({
                //             title: '请选择完整省市区',
                //             duration: 1000,
                //             icon: 'none'
                //     });
                //     return false;
                // }
                uni.showLoading({
                    title: '正在提交',
                    mask: true
                })
                self.formSubmit(formdata);
            },
            formSubmit(e) {
                let self = this;
                let callback = function(){
                    self._post('plus.release.demandIndex/submit', e, function(res) {
                        uni.hideLoading();
                        uni.showToast({
                            title: '申请成功'
                        });
                        self.getData();
                    });
                };
                self.subMessage(self.temlIds, callback);
            },
            goback() {
                uni.navigateBack();
            },
        }
    }
</script>
<style lang="scss">
    .form-wrap {
        background: #FFFFFF;
        position: relative;
    }
    .form-item {
        padding: 20rpx 0;
        margin-bottom: 20rpx;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        font-size: 28rpx;
    }
    .form-item .field-name {
        width: 100rpx;
    }
    .form-item input {
        font-size: 28rpx;
    }
    .apply-team .btn-red {
        width: 600rpx;
        height: 88rpx;
        line-height: 88rpx;
        border-radius: 44rpx;
        box-shadow: 0 8rpx 16rpx 0 rgba(226,35,26,.6);
    }
</style>
mobile/pages3/release/demandindex/index.vue
New file
@@ -0,0 +1,368 @@
<template>
    <view class="index-team o-h" v-if="!loadding">
        <!-- #ifdef MP-WEIXIN || APP-PLUS -->
        <view v-if="!is_release && isData" class="ww100" :style="'height:'+topBarTop()+'px;'"></view>
        <view v-if="!is_release && isData" class="tc  head_top" :style="topBarHeight() == 0 ? '': 'height:'+topBarHeight()+'px;'">
            <view class="reg180" @click="goback"><text class="icon iconfont icon-jiantou"></text></view>
            <view class="fb">{{titel}}</view>
        </view>
        <!-- #endif -->
        <!--头部图片-->
        <view class="banner d-c-c d-c" v-if="!is_release && isData">
            <image :src="top_background" mode="widthFix"></image>
        </view>
        <!--是-->
        <template v-if="is_release && isData">
            <view class="agent-wrap pr m-0-20 mt20">
                <view class="d-b-c f28 lh150 user-info">
                    <view class="d-b-c">
                        <view class="photo">
                            <image :src="user.avatarUrl" mode="aspectFill"></image>
                        </view>
                        <view class="user-name">
                            <view class="gray3 f32">{{ user.nickName }}</view>
                        </view>
                    </view>
                </view>
                <!-- <view class="d-s-c p-30-0 top_dash">
                    <view class="flex-1 d-c-c d-c">
                        <view class="redF6">
                            <text class="f24">¥</text>
                            <text class="f40">{{ release.money }}</text>
                        </view>
                        <view class="pt20 f26 gray3">可提现</view>
                    </view>
                    <view class="flex-1 d-c-c d-c">
                        <view class="">
                            <text class="f24">¥</text>
                            <text class="f40">{{ release.freeze_money }}</text>
                        </view>
                        <view class="pt20 f28 gray3">待提现</view>
                    </view>
                    <view class="flex-1 d-c-c d-c">
                        <view class="">
                            <text class="f24">¥</text>
                            <text class="f40">{{ release.total_money }}</text>
                        </view>
                        <view class="pt20 f28 gray3">已提现</view>
                    </view>
                </view>
                <view class="d-c-c pt30">
                     <button type="primary" class="btn-gcred theme-btn flex-1" @click="gotoCash">我要提现</button>
                    <button type="primary" class="btn-gcred theme-btn flex-1" @click="gotoPage('/pages3/release/demandproject/index')">发布需求</button>
                </view>-->
            </view>
            <!--图标入口-->
            <view class="agent-wrap m-0-20 p30 d-s-c f-w mt20 bg-white">
                <view class="d-c-c d-c flex-1" @click="gotoPage('/pages3/release/project/list?product_type=1')">
                    <view>
                        <image class="agent_index_img" src="../../../static/icon/icon-erweima.png" mode=""></image>
                    </view>
                    <text class="pt10 f26 mt20">供需大厅</text>
                </view>
                <view class="d-c-c d-c flex-1" @click="gotoPage('/pages3/release/demandproject/index')">
                    <view>
                        <image class="agent_index_img" src="../../../static/icon/icon-fenxiaodingdan.png" mode=""></image>
                    </view>
                    <text class="pt10 f26 mt20">发布需求</text>
                </view>
                <view class="d-c-c d-c flex-1" @click="gotoPage('/pages3/release/demandorder/index')">
                    <view>
                        <image class="agent_index_img" src="../../../static/icon/icon-zijinmingxi.png" mode=""></image>
                    </view>
                    <text class="pt10 f26 mt20">需求订单</text>
                </view>
                 <!--<view class="d-c-c d-c flex-1" @click="gotoPage('/pages2/salesman/qrcode/qrcode')">
                    <view>
                        <image class="agent_index_img" src="../../../static/icon/icon-erweima.png" mode=""></image>
                    </view>
                    <text class="pt10 f26 mt20">关注公众号</text>
                </view> -->
            </view>
            <!-- <view class="no-team">
                <view class="mt50 p-0-20 pt30 red f34 tc">恭喜您,已申请成为</view>
            </view>
            <view class="p30 mt30">
                <button type="primary" class="btn-gcred" @click="toOrder()">立即</button>
            </view>     -->
        </template>
        <!--不是-->
        <template v-if="!is_release && isData">
            <view class="no-team">
                <view class="mt50 p-0-20 pt30 red f34 tc">很抱歉,您还不是需求方</view>
            </view>
            <view class="p30 mt30">
                <button type="primary" class="btn-gcred" @click="apply()">立即申请入驻</button>
            </view>
        </template>
    </view>
</template>
<script>
    export default {
        data() {
            return {
                /*是否加载完成*/
                loadding: true,
                indicatorDots: true,
                autoplay: true,
                interval: 2000,
                duration: 500,
                is_release: false,
                isData: false,
                release: {},
                /*顶部背景*/
                top_background: '',
                user:[],
            };
        },
        onLoad(e) {
        },
        onShow() {
            uni.showLoading({
                title: '加载中'
            });
            /*获取数据*/
            this.getData();
        },
        methods: {
            /*获取数据*/
            getData() {
                let self = this;
                self._get('plus.release.demandIndex/index', {}, function(data) {
                    self.is_release= data.data.is_release;
                    self.top_background = data.data.background;
                    self.release = data.data.release;
                    self.user = data.data.user;
                    self.isData = true;
                    self.loadding = false;
                    uni.hideLoading();
                });
            },
            /*申请入驻*/
            apply() {
                this.gotoPage('/pages3/release/demandapply/apply');
            },
            /*发布*/
            toOrder() {
                this.gotoPage('/pages3/release/demandorder/myorder');
            },
            /*去提现*/
            gotoCash() {
                this.gotoPage('/pages3/release/demandcash/apply/apply');
            },
            goback() {
                uni.navigateBack();
            },
        }
    };
</script>
<style lang="scss">
    page {
        background-color: #f9f9f9;
    }
    .index-agent .banner {
        position: absolute;
        width: 750rpx;
        height: 348rpx;
        z-index: 0;
        min-height: 167rpx;
        /* padding-bottom: 60rpx; */
        background-repeat: no-repeat;
        background-size: 100%;
    }
    .index-agent .banner image {
        width: 100%;
    }
    .no-agent {
        // padding-top: 190rpx;
    }
    .no-agent-image {
        padding-top: 20rpx;
        margin: 0 auto;
    }
    .no-agent-image image {
        width: 532rpx;
        height: 340rpx;
    }
    .agent-wrap {
        background: #FFFFFF;
        background-size: 100% 100%;
        padding: 31rpx 25rpx 36rpx 25rpx;
        box-shadow: 0px 8rpx 3rpx 0px rgba(6,0,1,0.03);
        border-radius: 20rpx;
    }
    .index-agent .agent-wrap .iconfont {
        font-size: 60rpx;
    }
    .index-agent .btn-gcred {
        height: 88rpx;
        line-height: 88rpx;
        border-radius: 44rpx;
        background: #FF5649;
        border-color: #FF5649;
    }
    .reg180 {
        padding-right: 20rpx;
        text-align: right;
        transform: rotateY(180deg);
        position: absolute;
        bottom: 0;
    }
    .icon-jiantou {
        color: #FFFFFF;
        font-size: 30rpx;
    }
    .head_top {
        position: absolute;
        width: 100%;
        padding-top: var(--status-bar-height);
        height: 30px;
        line-height: 30px;
        color: #FFFFFF;
        font-size: 32rpx;
        z-index: 2;
    }
    .top_dash {
        border-bottom: 1rpx dashed #D9D9D9;
        padding-bottom: 9px;
    }
    .agent_index_img {
        width: 78rpx;
        height: 78rpx;
    }
    .info-top{
        padding: 74rpx 0 63rpx 44rpx;
    }
    .info-ava {
        width: 108rpx;
        height: 108rpx;
        border-radius: 50%;
        position: relative;
        margin-right: 30rpx;
    }
    .info-avatar {
        width: 108rpx;
        height: 108rpx;
        border-radius: 50%;
    }
    .info-grade {
        min-width: 114rpx;
        height: 30rpx;
        line-height: 30rpx;
        padding: 0 22rpx;
        box-sizing: border-box;
        font-size: 18rpx;
        color: #ffffff;
        background: #FFC519;
        box-shadow: 0px 3rpx 7rpx 0px rgba(0, 0, 0, 0.15);
        border-radius: 15rpx;
        text-align: center;
        white-space: nowrap;
        position: absolute;
        left: 0;
        right: 0;
        bottom: -16rpx;
        z-index: 2;
    }
    .section-product .price {
        color: #F6220C;
        font-size: 24rpx;
    }
    .section-product .price .num {
        padding: 0 4rpx;
        font-size: 32rpx;
    }
    .section-product .level-box {
        margin-top: 20rpx;
        display: flex;
        justify-content: space-between;
        align-items: center;
    }
    .section-product .level-box .key {
        font-size: 24rpx;
        color: #999999;
    }
    .section-product .level-box .num-wrap {
        display: flex;
        justify-content: flex-end;
        align-items: center;
    }
    .section-product .level-box .icon-box {
        width: 33rpx;
        height: 33rpx;
        border: 1px solid #c5c5c5;
        background: #f2f2f2;
    }
    .section-product .level-box .icon-box .gray {
        color: #cccccc;
    }
    .section-product .level-box .icon-box .gray3 {
        color: #333333;
    }
    .section-product .level-box .text-wrap {
        margin: 0 20rpx;
        height: 33rpx;
        border: none;
        background: none;
    }
    .section-product .level-box .text-wrap input {
        padding: 0 4rpx;
        height: 33rpx;
        line-height: 1;
        width: 40rpx;
        font-size: 32rpx;
        text-align: center;
        display: flex;
        align-items: center;
        min-height: 33rpx;
    }
    .section-product .icon-jiantou {
        color: #999;
    }
    .user-info .photo,
    .user-info .photo image {
        width: 100rpx;
        height: 100rpx;
        border-radius: 50%;
    }
    .user-info .photo {
        padding-right: 20rpx;
    }
</style>
mobile/pages3/release/demandorder/detail.vue
New file
@@ -0,0 +1,100 @@
<template>
    <view class="p30">
        <view class="title p30 bg-white f30 lh200 radius8">>
            <view>项目:
              <text>{{ item.project_name }}</text>
            </view>
            <view>支付费用:¥{{ detail.pay_price }}</view>
            <view v-if="detail.settle_time">完成时间:{{ detail.settle_time }}</view>
            <view>完成图片:</view>
            <view v-for="(item, index) in img_list2" :key="index">
                 <image :src="item.file_path" mode="aspectFit"></image>
            </view>
            <view>留言:<text v-if="detail.remark!= null">{{ detail.remark }}</text></view>
            <view>买家图片:</view>
            <view v-for="(item, index) in img_list" :key="index">
                 <image :src="item.file_path" mode="aspectFit"></image>
            </view>
            <view>买家留言:<text v-if="detail.content!= null">{{ detail.content }}</text></view>
            <view>备注:<text v-if="detail.message!= null">{{ detail.message }}</text></view>
        </view>
        </view>
    </view>
</template>
<script>
    import utils from '@/common/utils.js';
    export default {
        data() {
            return {
                detail: '',,
            }
        },
        onLoad(e) {
            /*id*/
            this.id = e.id;
        },
        mounted(){
            uni.showLoading({
                title: '加载中'
            });
            this.getData();
        },
        methods: {
            getData(){
                let self = this;
                let id = self.id;
                self._get('plus.release.order/detail', {id: id}, function (res)
                {
                    self.detail= res.data.detail;
                    uni.hideLoading();
                });
            },
            bindDateChange(e){
                let self = this;
                var booking_time = e.detail.value;
                uni.showLoading({
                    title: '加载中'
                });
                self._post(
                    'plus.release.order/updateTime', {
                        booking_time: booking_time,
                        id: self.id,
                    },
                    function(res) {
                        uni.hideLoading();
                        self.showSuccess(res.msg,function(){
                            self.getData();
                        });
                    }
                );
            },
            editChange(e){
                let self = this;
                uni.showLoading({
                    title: '加载中'
                });
                self._post(
                    'plus.release.order/editGoods', {
                        odd_num: self.odd_num,
                        goods_name: self.goods_name,
                        id: self.id,
                    },
                    function(res) {
                        uni.hideLoading();
                        self.showSuccess(res.msg,function(){
                            self.getData();
                        });
                    }
                );
            },
        }
    }
</script>
<style>
</style>
mobile/pages3/release/demandorder/index.vue
New file
@@ -0,0 +1,549 @@
<template>
    <view class="bargain-container" :data-theme='theme()' :class="theme() || ''">
        <view class="top-tabbar">
            <view :class="state_active == 0 ? 'tab-item active' : 'tab-item'" @click="stateFunc(0)">全部</view>
            <view :class="state_active == 10 ? 'tab-item active' : 'tab-item'" @click="stateFunc(10)">确认订单</view>
            <view :class="state_active == 20 ? 'tab-item active' : 'tab-item'" @click="stateFunc(20)">进行中</view>
            <view :class="state_active == 30 ? 'tab-item active' : 'tab-item'" @click="stateFunc(30)">已完成</view>
            <view :class="state_active == 40 ? 'tab-item active' : 'tab-item'" @click="stateFunc(40)">已取消</view>
        </view>
        <!--内容-->
        <view class="bargain-list" v-if="!loading">
            <scroll-view scroll-y="true" class="scroll-Y" :style="'height:' + scrollviewHigh + 'px;'" lower-threshold="50">
                <!-- 搜索框 -->
                <!-- <view class="d-b-c" id="searchBox">
                    <view class="index-search t-c flex-1" style="height: 70rpx; line-height: 70rpx; margin: 10rpx;">
                        <span class="icon iconfont icon-sousuo"></span>
                        <input type="text" v-model="keyword" class="flex-1 ml10 f30 gray3" value="" placeholder-class="f24 gray6"
                         placeholder="单号" confirm-type="search" @confirm="gotoSearch()"/>
                    </view>
                </view> -->
                <!--列表-->
                <view class="list d-s-c f-w">
                    <view class="item d-stretch" v-for="(item, index) in listData" :key="index" >
                         <!-- <view class="product-cover pr" @click="gotoDetail(item)">
                            <image :src="item.image[0].file_path" mode="aspectFit"></image>
                        </view> -->
                        <view class="product-info d-b-c d-c" @click="gotoDetail(item)">
                            <view class="product-title f26 gray3">
                               <view>{{item.project_name}}</view>
                            </view>
                            <view class="people-num price d-b-c">
                                <text class="gray9 f26">{{ item.create_time }}</text>
                                <text class="red f26">{{item.state_text}}</text>
                            </view>
                        </view>
                        <view class="d-s-s">
                            <view class="pl30">
                                <view class="p-20-0">
                                    <text>订单号:</text>
                                    <text>{{ item.order_no }}</text>
                                    <text class="ml30">支付金额:</text>
                                    <text>¥{{ item.pay_price }}</text>
                                </view>
                            </view>
                        </view>
                        <view style="float: right;" v-if="item.pay_status == 20 && item.order_status == 10">
                                    <block>
                                        <button @click="onEva(item)" class="theme-borderbtn" style="border: 0rpx; padding: 0rpx;">评价</button>
                                    </block>
                        </view>
                        <view style="float: left;" v-if="item.pay_status == 10 && item.order_status == 10">
                                    <block>
                                        <button @click="onPayOrder(item)" class="theme-borderbtn" style="border: 0rpx; padding: 0rpx;">去支付</button>
                                    </block>
                        </view>
                        <view style="float: right;" v-if="item.pay_status == 10">
                                    <block>
                                        <button @click="onCancel(item)" class="theme-borderbtn" style="border: 0rpx; padding: 0rpx;">取消</button>
                                    </block>
                        </view>
                    </view>
                </view>
                <!-- 没有记录 -->
                <view class="none-data-box" v-if="listData.length==0 && !loading">
                    <image src="/static/none.png" mode="widthFix"></image>
                    <text>暂无数据</text>
                </view>
            </scroll-view>
        </view>
        <!-- 修改 -->
        <Evaluate :isEva="isEva" :orderData="order_data" @close="closeEva"></Evaluate>
        <!--支付选择-->
        <Popup :show="isPayPopup" msg="支付方式" @hidePopup="hidePopupFunc">
            <!--支付方式-->
            <view class="buy-checkout ww100">
                <view :class="pay_type == 20 ? 'item active border-b-e' : 'item border-b-e'" @click="payTypeFunc(20)">
                    <view class="d-s-c">
                        <view class="icon-box d-c-c mr10"><span class="icon iconfont icon-weixin"></span></view>
                        <text class="key">微信支付</text>
                    </view>
                    <view class="icon-box d-c-c"></view>
                </view>
                 <view :class="pay_type == 10 ? 'item active' : 'item'" @click="payTypeFunc(10)">
                    <view class="d-s-c">
                        <view class="icon-box d-c-c mr10"><span class="icon iconfont icon-yue"></span></view>
                        <text class="key">余额支付</text>
                    </view>
                    <view class="icon-box d-c-c"></view>
                </view>
                <view :class="pay_type == 40 ? 'item active' : 'item'" @click="payTypeFunc(40)">
                    <view class="d-s-c">
                        <view class="icon-box d-c-c mr10"><span class="icon iconfont icon-yue"></span></view>
                        <text class="key">线下支付</text>
                    </view>
                    <view class="icon-box d-c-c"></view>
                </view>
            </view>
            <view class="bts"></view>
        </Popup>
    </view>
</template>
<script>
    import Evaluate from './popup/evaluate';
    import Popup from '@/components/uni-popup.vue';
    import {
            pay
        } from '@/common/pay.js';
    export default {
        components: {
            Evaluate,
            Popup,
        },
        data() {
            return {
                /*手机高度*/
                phoneHeight: 0,
                /*可滚动视图区域高度*/
                scrollviewHigh: 0,
                /*列表*/
                listData: [],
                status: 0,
                /*是否正在加载*/
                loading: true,
                isEva:false,
                order_data:[],
                /*状态选中*/
                state_active: 0,
                keyword:'',
                /*是否显示支付类别弹窗*/
                isPayPopup: false,
                /*支付方式*/
                pay_type: 20,
                payData:[],
                topay:false,
                id:0,
            };
        },
        computed: {},
        onLoad(e) {},
        onShow() {
            let self = this;
            let options = wx.getEnterOptionsSync();
            // 从半屏小程序返回时执行
            if (options.scene == '1038') {
                self.onPayResult(options.referrerInfo.extraData);
            }
            /*获取列表*/
            self.getlist();
        },
        mounted() {
            this.init();
        },
        onReachBottom() {},
        methods: {
            /*初始化*/
            init() {
                let _this = this;
                uni.getSystemInfo({
                    success(res) {
                        _this.scrollviewHigh  = res.windowHeight;
                    }
                });
            },
            // 半屏小程序返回
            onPayResult(e) {
                let self = this;
                if (e.pay_result == 'success') {
                    self.showSuccess('支付成功!',function(){
                        self.gotoPage('/pages3/release/demandorder/index', 'redirect');
                    });
                } else {
                    if(self.topay){
                        //兼容半屏跳转
                    }else{
                        self.showError('支付失败');
                    }
                }
            },
            /*状态切换*/
            stateFunc(e) {
                let self = this;
                if (self.state_active != e) {
                //    self.page = 1;
                    self.loading = true;
                    self.state_active = e;
                    self.listData = [];
                    self.getlist();
                }
            },
            /*搜索*/
            gotoSearch() {
                let self=this;
                //self.page = 1;
                self.listData = [];
                self.getlist();
            },
            /*获取列表*/
            getlist() {
                let self = this;
                uni.showLoading({
                    title: '加载中'
                });
                let status = self.status;
                self.loading = true;
                self._get(
                    'plus.release.order/lists', {
                        state_active:self.state_active,
                        keyword:self.keyword,
                        product_type:0,
                    },
                    function(res) {
                        self.listData = res.data.list.data;
                        uni.hideLoading();
                        self.loading = false;
                    }
                );
            },
            /*跳转详情*/
            gotoDetail(e) {
                //let url = 'pages3/release/order/detail?id=' + e.id
                //this.gotoPage(url);
            },
            /*修改*/
            onEva: function(e) {
                let self = this;
                self.order_data = e;
                self.isEva = true;
            },
            /*关闭修改*/
            closeEva: function(e) {
                let self = this;
                self.page = 1;
                self.listData = [];
                self.getlist();
                self.isEva = false;
            },
            /*隐藏支付方式*/
            hidePopupFunc() {
                this.isPayPopup = false;
            },
            /*去支付*/
            payTypeFunc(payType) {
                let self = this;
                self.isPayPopup = false;
                uni.showLoading({
                    title: '加载中'
                });
                self._post(
                    'plus.release.order/pay', {
                        pay_type: payType,
                        pay_source: self.getPlatform(),
                        id: self.id,
                    },
                    function(res) {
                        self.payData = res;
                        // 半屏小程序支付
                        if (res.data.payment.is_embed) {
                            // console.log(res.data.payment);
                            uni.openEmbeddedMiniProgram({
                                appId: res.data.payment.embed_app_id,
                                path: res.data.payment.embed_path,
                                extraData: res.data.payment.extraData,
                                envVersion: 'release', // develop开发版 trial体验版 release正式版
                                success:function() {
                                    console.log('打开半屏小程序成功');
                                },
                                fail:function() {
                                    console.log('打开半屏小程序失败');
                                }
                            });
                            return;
                        }
                        pay(res, self, function() {
                            uni.hideLoading();
                            self.showSuccess('支付成功!',function(){
                                self.page = 1;
                                self.listData = [];
                                self.getlist();
                                //self.gotoPage('/pages3/release/demandorder/index', 'redirect');
                            });
                        }, function() {
                            uni.hideLoading();
                            self.showError('提交失败');
                        });
                    }
                );
            },
            /*支付方式选择*/
            onPayOrder(item) {
                let self = this;
                self.id = item.id
                self.isPayPopup = true;
            },
            //删除
            onCancel(e) {
                let self = this;
                // 请求的参数
                let id = e.id;
                wx.showModal({
                    title: "提示",
                    content: "您确定进行此操作吗?",
                    success: function(o) {
                        if(o.confirm){
                            self._post('plus.release.order/cancel', {
                                id:id,
                             }, (res) => {
                                    uni.showToast({
                                        title: res.msg,
                                        duration: 2000,
                                        icon: 'success',
                                    });
                                    self.page = 1;
                                    self.listData = [];
                                    self.getlist();
                            });
                        }
                    }
                });
            },
        }
    };
</script>
<style lang="scss">
    page {
        background: #f2f2f2;
    }
    .bargain-container .inner-tab {
        background: #ffffff;
    }
    .bargain-container .inner-tab .tab-list {
        height: 100rpx;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        background: #FFFFFF;
    }
    .bargain-container .inner-tab .item {
        height: 100rpx;
        line-height: 100rpx;
        white-space: nowrap;
        padding: 0 30rpx;
        font-size: 30rpx;
        color: #333333;
    }
    .bargain-container .inner-tab .item.active,
    .bargain-container .inner-tab .item .arrow.active .iconfont {
        background: #FFFFFF;
        font-size: 32rpx;
        color: #F6220C;
        position: relative;
    }
    .bargain-container .inner-tab .item.active::after {
        content: '';
        width: 60%;
        height: 4rpx;
        background: #F6220C;
        border-radius: 2rpx;
        position: absolute;
        bottom: 17rpx;
        left: 0;
        right: 0;
        margin: auto;
    }
    .bargain-container .inner-tab .box {
        display: flex;
        justify-content: center;
        align-items: center;
        flex-direction: row;
    }
    .bargain-container .inner-tab .arrows {
        margin-left: 10rpx;
        line-height: 0;
    }
    .bargain-container .inner-tab .iconfont {
        line-height: 24rpx;
        font-size: 24rpx;
    }
    .bargain-container .inner-tab .arrow,
    .bargain-container .inner-tab .svg-icon {
        width: 20rpx;
        height: 20rpx;
    }
    .bargain-container .banner-image {
        width: 100%;
        box-sizing: border-box;
    }
    .bargain-container .banner-image image {
        width: 750rpx;
        height: 365rpx;
    }
    .bargain-container .ad-datetime::v-deep text {
        color: #333333;
        font-size: 28rpx;
    }
    .bargain-container .ad-datetime::v-deep .box {
        padding: 4rpx;
        border-radius: 4rpx;
        background: #F6220C;
        color: #ffffff;
    }
    .bargain-list .list {
        padding: 20rpx;
    }
    .bargain-list .list .item {
        width: 100%;
        padding: 30rpx;
        margin-bottom: 20rpx;
        box-sizing: border-box;
        border-radius: 16rpx;
        background: #ffffff;
    }
    .bargain-list .product-cover {
        padding: 4rpx;
    }
    .bargain-list .product-cover image {
        width: 120rpx;
        height: 120rpx;
        border-radius: 12rpx;
    }
    .bargain-list .product-info {
        flex: 1;
        //padding-left: 20rpx;
        overflow: hidden;
    }
    .bargain-list .product-cover .people-num {
        position: absolute;
        right: 0;
        bottom: 0;
        left: 0;
        height: 50rpx;
        padding: 0 20rpx;
        line-height: 50rpx;
        font-size: 24rpx;
        box-sizing: border-box;
        background: rgba(0, 0, 0, 0.6);
    }
    .bargain-list .ad-datetime .box {
        padding: 4rpx;
        border-radius: 4rpx;
        background: #000000;
        color: #ffffff;
    }
    .bargain-list .product-title {
        width: 100%;
        min-height: 40rpx;
        line-height: 40rpx;
        font-size: 32rpx;
        color: #333333;
    }
    .bargain-list .people-num {
        width: 100%;
    }
    .bargain-list .already-sale {
        padding: 4rpx 0;
        color: #999;
        font-size: 24rpx;
    }
    .bargain-list .price {
        width: 100%;
        color: $dominant-color;
        font-size: 24rpx;
    }
    .bargain-list .price .num {
        padding: 0 4rpx;
    }
    .bargain-list .slider-box .slider {
        margin-top: 10rpx;
        height: 10rpx;
        background: #cccccc;
        border-radius: 5rpx;
    }
    .bargain-list .slider-box .slider-inner {
        height: 10rpx;
        background: #e2231a;
        border-radius: 5rpx;
    }
    .bargain-list .right-btn button {
        height: 60rpx;
        line-height: 60rpx;
        border-radius: 30rpx;
        background: #8D60FF;
        color: #ffffff;
        font-size: 32rpx;
    }
    .add_add {
        position: fixed;
        bottom: 20rpx;
        left: 5%;
        width: 90%;
        height: 80rpx;
        line-height: 80rpx;
        border-radius: 80rpx;
        /* background: #ff5704; */
        @include background_color('background_color');
        color: #fff;
        font-size: 30rpx;
        display: flex;
        justify-content: center;
        margin: 0 auto;
    }
</style>
mobile/pages3/release/demandorder/popup/evaluate.vue
New file
@@ -0,0 +1,178 @@
<template>
    <view style="flex: 1;">
        <uniPopup :show="isEva" type="middle" @hidePopup="hidePopupFunc">
            <view class="ww100">
                <view class="t-c f36 pb20">评语</view>
                <view class="p-30-0 border-b-d9 border-t-d9 f32">
                    <view>{{orderData.project_name}}</view>
                </view>
                <view class="d-s-c p-30-0 border-b-d9 border-t-d9 f32">
                    <view class="eval">
                        服务星级:
                        <i v-for="(itemEv,indexEv) in service" :key="indexEv" :class="itemEv?'icon iconfont icon-start':'icon iconfont icon-start1'"
                         @click="chooseServ(indexEv,index)"></i>
                    </view>
                </view>
                <view class="d-s-c p-30-0 border-b-d9 border-t-d9 f32">
                    <radio-group class="d-s-c" @change="changeRadio($event,index)">
                        <label class="d-s-c make-item mr10">
                            <view><radio style="transform:scale(0.7)" color="#EE1413" :checked="score == 10" value="10" /></view>
                            <view class="f26 color-57">好评</view>
                        </label>
                        <label class="d-s-c make-item mr10">
                            <view><radio style="transform:scale(0.7)" color="#EE1413" :checked="score == 20" value="20" /></view>
                            <view class="f26 color-57">中评</view>
                        </label>
                        <label class="d-s-c make-item mr10">
                            <view><radio style="transform:scale(0.7)" color="#EE1413" :checked="score == 30" value="30" /></view>
                            <view class="f26 color-57">差评</view>
                        </label>
                    </radio-group>
                </view>
                <view class="d-s-c p-30-0 border-b-d9 border-t-d9 f32">
                    <textarea class="border-box" placeholder="请输入你的评语" v-model="evaluate_content"></textarea>
                </view>
                <button class="revise_btn" @click="revise">确定完成</button>
            </view>
        </uniPopup>
    </view>
</template>
<script>
    import uniPopup from '@/components/uni-popup.vue';
    export default {
        data() {
            return {
                score:10,
                server_score:0,
                service:[false,false,false,false,false],
                evaluate_content:'',
            };
        },
        components: {
            uniPopup
        },
        props: ['isEva', 'orderData'],
        watch:{
            isEva(val){
            }
        },
        methods: {
            /* 服务评分 */
            chooseServ(n,m){
                let self=this;
                self.server_score =0;
                this.service.forEach((item,index)=>{
                    if(index<=n){
                        this.service.splice(index,1,true);
                        self.server_score++;
                    }else{
                        this.service.splice(index,1,false);
                    }
                })
            },
            /* 单选框 */
            changeRadio(e, index) {
                this.score = e.detail.value;
            },
            revise(){
                let self = this;
                uni.showModal({
                    title: '提示',
                    content: '此操作不可恢复,您确定已完成了吗?',
                    success: function(o) {
                        if (o.confirm) {
                            uni.showLoading({
                                title: '加载中',
                                mask: true
                            });
                            uni.showLoading({
                                    title: '正在提交',
                                    mask: true
                                })
                                self._post('plus.release.Order/finish', {
                                    id: self.orderData.id,
                                    server_score:self.server_score,
                                    score:self.score,
                                    evaluate_content:self.evaluate_content,
                                }, function(data) {
                                    uni.hideLoading();
                                    uni.showToast({
                                        title: '操作成功',
                                        duration: 2000,
                                        icon: 'success'
                                    });
                                    setTimeout(function(){
                                        self.hidePopupFunc();
                                    },2000);
                                });
                        }
                    },
                });
            },
            hidePopupFunc(){
                this.$emit('close', {
                  type: 'success',
                })
            },
        }
    };
</script>
<style scoped lang="scss">
    .buy-checkout.vender .item .key {
        width: 200rpx;
    }
    .pr20 {
        padding-right: 20rpx;
        /* padding-bottom: 40rpx; */
    }
    .icon-box.linkmen_add{
        background-color: $dominant-color;
        width: 38rpx;
        height: 38rpx;
        border-radius: 8rpx;
        display: flex;
        justify-content: center;
        align-items: center;
    }
    .icon-box.linkmen_add .icon-jia{
        color: #FFFFFF;
        font-size: 22rpx;
    }
    .revise_btn{
        background-color: #E2231A;
        border: none;
        margin-top: 30rpx;
        color: #FFFFFF;
    }
    .t-c{
        text-align: center;
    }
    .m-30-0{
        margin: 30rpx 0;
    }
    .icon.icon-jiantou{
        color: #999999;
        font-size: 26rpx;
    }
    .icon.icon-zhanghumingcheng, .icon.icon-dizhi, .icon.icon-icon_xianshi-xian, .icon.icon-bangzhu {
        color: #333;
        font-size: 28rpx;
    }
    .address-defalut-wrap {
        padding: 0;
    }
    .icon-start{
        color: #f5a623;
    }
    .eval{
        display: flex;
        justify-content: space-around;
        align-items: center;
    }
</style>
mobile/pages3/release/demandproject/edit.vue
New file
@@ -0,0 +1,393 @@
<template>
    <view class="evaluate pb100" :data-theme='theme()' :class="theme() || ''">
        <form @submit="formSubmit" @reset="formReset">
            <view class="evaluate-item p30">
                <view class="form-item border-b">
                    <view class="field-name">标题*:</view>
                    <input class="flex-1" v-model="form.name" type="text" placeholder-class="grary" placeholder="请输入标题" />
                </view>
                <view class="form-item border-b">
                    <view class="field-name">分类*:</view>
                    <picker @change="onChange" :value='index' :range="list">
                      <view class="label-right">
                        {{list[index]}}
                      </view>
                    </picker>
                </view>
                <view class="form-item border-b">
                    <view class="field-name">预算(元)*:</view>
                    <input class="flex-1" v-model="form.price" type="text" placeholder-class="grary" placeholder="请输入您的预算" />
                </view>
                <view class="textarea-box d-s-c f28">
                    <textarea class="p10 box-s-b border flex-1" v-model="form.content" placeholder="请输入详细要求*" />
                </view>
                <view class="upload-list d-s-c" v-model="form.image_list">
                    <view class="item" v-for="(imgs, img_num) in form.image_list" :key="img_num"  @click="deleteImg(img_num)">
                        <image :src="imgs.file_path" mode="aspectFit"></image>
                    </view>
                    <view class="item upload-btn d-c-c d-c" @click="openUpload()" v-if="form.image_list.length < 9" >
                        <text class="icon iconfont icon-xiangji"></text>
                        <text class="gray9">上传图片</text>
                    </view>
                </view>
                <view class="form-item border-b">
                    <view class="field-name">期望完成时间:</view>
                    <picker mode="date" @change="bindDateChange">
                      <view class="label-right">
                        {{form.finish_time}}
                      </view>
                    </picker>
                </view>
                <view class="form-item border-b">
                    <view class="field-name">期望地点:</view>
                    <input class="flex-1" v-model="form.detail" type="text" placeholder-class="grary" placeholder="请输入您的期望地点" />
                </view>
                <!-- <view class="form-item border-b">
                    <text class="field-name">需求所在地:</text>
                    <input class="flex-1" name="location_address" type="text"  placeholder-class="grary9" placeholder="请选择地址" v-model="short_address"
                         disabled @click="chooseLocation" />
                </view> -->
                <view class="form-item border-b">
                    <view class="field-name">公开联系方式:</view>
                    <radio-group class="d-s-c" @change="changeRadio($event,index)">
                        <label class="d-s-c make-item mr10">
                            <view><radio style="transform:scale(0.7)" color="#EE1413" :checked="show_phone == 1" value="1" /></view>
                            <view class="f26 color-57">是</view>
                        </label>
                        <label class="d-s-c make-item mr10">
                            <view><radio style="transform:scale(0.7)" color="#EE1413" :checked="show_phone == 0" value="0" /></view>
                            <view class="f26 color-57">否</view>
                        </label>
                    </radio-group>
                </view>
                <view class="form-item border-b">
                    <view class="field-name">是否展示:</view>
                    <radio-group class="d-s-c" @change="changeShow($event,index)">
                        <label class="d-s-c make-item mr10">
                            <view><radio style="transform:scale(0.7)" color="#EE1413" :checked="form.is_show == 1" value="1" /></view>
                            <view class="f26 color-57">是</view>
                        </label>
                        <label class="d-s-c make-item mr10">
                            <view><radio style="transform:scale(0.7)" color="#EE1413" :checked="form.is_show == 0" value="0" /></view>
                            <view class="f26 color-57">否</view>
                        </label>
                    </radio-group>
                </view>
            </view>
            <view v-if="!loadding" class="foot-btns" @click="submit">
                <button class="btn-red" style="background: none; border: 0;">确认提交</button>
            </view>
        </form>
        <!--上传图片-->
        <Upload v-if="isUpload" @getImgs="getImgsFunc"></Upload>
    </view>
</template>
<script>
import Upload from '@/components/upload/upload.vue';
export default {
    components: {
        Upload,
    },
    data() {
        return {
            /*是否加载完成*/
            loadding: true,
            /*页面数据*/
            tableData: [],
            form: {
                project_id:'',
                image_list:[],
                content:'',
                name:'',
                category_id:'',
                finish_time:'请选择日期',
                price:'',
                province_id: 0,
                city_id: 0,
                region_id: 0,
                longitude:'',
                latitude:'',
                location_address:'',
                detail:'',
                show_phone:1,
                is_show:1,
            },
            /*是否打开上传图片*/
            isUpload: false,
            categoryList:[],
            //所有分类
            list:[],
            //选中的分类
            index:0,
            location_address: '',
            short_address:'',
            show_phone:1,
            Address:[],
        };
    },
    onLoad(e){
        this.form.project_id = e.project_id;
    },
    mounted() {
    },
    onShow(){
        let self = this;
        self.getData();
    },
    methods: {
        /* 单选框 */
        changeShow(e, index) {
            let self = this;
            self.form.is_show = e.detail.value;
        },
        /* 单选框 */
        changeRadio(e, index) {
            let self = this;
            self.form.show_phone = e.detail.value;
        },
        //改变
        onChange(e) {
            let self = this;
            let val = e.detail.value;
            if(val == 0){
                self.index = 0;
                self.form.category_id = '';
                return;
            }
            self.index = val;
            let index = val - 1;
            self.form.category_id = this.categoryList[index].category_id;
        },
        bindDateChange(e){
            let self = this;
            self.form.finish_time = e.detail.value;
        },
        /*获取数据*/
        getData() {
            let self = this;
            uni.showLoading({
                title: '加载中'
            })
            self._get('plus.release.demandProject/detail', {
                project_id: self.form.project_id,
            }, function(res) {
                uni.hideLoading();
                self.loadding=false;
                self.categoryList = res.data.category_list;
                var detail = res.data.detail;
                var list = [];
                list.push("请选择分类");
                self.categoryList.forEach((item,index) => {
                        list.push(item.name);
                        if(item.category_id == detail.category_id){
                            self.index= index + 1;
                        }
                });
                self.list = list;
                self.form = detail;
                self.show_phone = detail.show_phone;
                if(detail.image_list && detail.image_list != 'undefined'){
                    self.form.image_list = detail.image_list;
                }else{
                    self.form.image_list = [];
                }
            });
        },
        /*提交*/
        submit() {
            let self = this;
            let formData=self.form;
            uni.showLoading({
                title: '加载中'
            });
            self._post(
                'plus.release.demandProject/edit', {
                    pay_source: self.getPlatform(),
                    formData: JSON.stringify(formData),
                },
                 function(res) {
                    uni.hideLoading();
                    self.showSuccess('提交成功!',function(){
                        self.gotoPage('/pages3/release/demandproject/index', 'redirect');
                    });
                }
            );
        },
        chooseLocation(n) {
            let self=this;
             uni.authorize({
             scope: 'scope.userLocation',
             success: () => {
                 uni.chooseLocation({
                     success: function (res) {
                        console.log(res)
                         self.form.longitude=res.longitude;
                         self.form.latitude=res.latitude;
                        self.form.detail= res.address;
                         self.location_address=res.address;
                         // 获取省市区
                        setTimeout(function(){
                            self.setLocationAddress();
                        },500)
                     },fail: function (err) {
                         //console.log(err)
                    }
                 });
             },
            })
        },
        // 获取省市区 by yj
        setLocationAddress() {
            let self = this;
            self._get('user.address/setLocationAddress', {
                address: self.location_address
            }, function(res) {
                self.short_address = res.data.short_address;
                self.form.province_id = res.data.cityCode[0];
                self.form.city_id = res.data.cityCode[1];
                self.form.region_id = res.data.cityCode[2];
            });
        },
        /*打开上传图片*/
        openUpload() {
            this.isUpload = true;
        },
        /*获取上传的图片*/
        getImgsFunc(e) {
            let self = this;
            if(e&&typeof(e)!='undefined'){
                self.form.image_list = self.form.image_list.concat(e);
            }
            self.isUpload = false;
        },
        /*点击图片删除*/
        deleteImg(i,n){
            this.loadding=true;
            this.form.image_list.splice(n,1);
            this.loadding=false;
        },
    }
};
</script>
<style>
.evaluate-item {
    margin-bottom: 20rpx;
    background: #ffffff;
}
.product .cover,
.product .cover image {
    width: 160rpx;
    height: 160rpx;
}
.evaluate .grade .item .iconfont {
    width: 60rpx;
    height: 60rpx;
    line-height: 60rpx;
    border-radius: 50%;
    font-size: 40rpx;
    color: #ffffff;
    text-align: center;
}
.evaluate .grade .item {
    height: 60rpx;
    padding-right: 20rpx;
    line-height: 60rpx;
    border-radius: 30rpx;
    transition: background-color 0.4s;
}
.grade .flex-1:nth-child(1) .iconfont {
    background: #f42222;
}
.grade .flex-1:nth-child(2) .iconfont {
    background: #f2b509;
}
.grade .flex-1:nth-child(3) .iconfont {
    background: #999999;
}
.grade .flex-1.active:nth-child(1) .item {
    background: #f42222;
    color: #ffffff;
}
.grade .flex-1.active:nth-child(2) .item {
    background: #f2b509;
    color: #ffffff;
}
.grade .flex-1.active:nth-child(3) .item {
    background: #999999;
    color: #ffffff;
}
.icon-start{
    color: #f5a623;
}
.evalu-value{
    display: flex;
    margin-bottom: 30rpx;
}
.eval{
    display: flex;
    justify-content: space-around;
    align-items: center;
}
.evalu{
    display: flex;
    align-items: baseline;
    flex-direction: column;
}
.form-item {
        padding: 20rpx 0;
        margin-bottom: 20rpx;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        font-size: 28rpx;
    }
    .form-item .field-name {
        width: 180rpx;
    }
    .form-item input {
        font-size: 28rpx;
    }
</style>
<style lang="scss">
    .foot-btns {
        position: fixed;
        bottom: 20rpx;
        left: 0rpx;
        width: 90%;
        height: 80rpx;
        line-height: 80rpx;
        border-radius: 80rpx;
        /* background: #ff5704; */
        @include background_color('background_color');
        color: #fff;
        font-size: 30rpx;
        display: flex;
        justify-content: center;
        margin: 0 auto;
    }
</style>
mobile/pages3/release/demandproject/index.vue
New file
@@ -0,0 +1,422 @@
<template>
    <view class="bargain-container" :data-theme='theme()' :class="theme() || ''">
        <!--内容-->
        <view class="bargain-list" v-if="!loading">
            <scroll-view scroll-y="true" class="scroll-Y" :style="'height:' + scrollviewHigh + 'px;'" lower-threshold="50" @scrolltolower="scrolltolowerFunc">
                <!-- 搜索框 -->
                <view class="d-b-c" id="searchBox">
                    <view class="index-search t-c flex-1" style="height: 70rpx; line-height: 70rpx; margin: 10rpx;">
                        <span class="icon iconfont icon-sousuo"></span>
                        <input type="text" v-model="keyword" class="flex-1 ml10 f30 gray3" value="" placeholder-class="f24 gray6"
                         placeholder="搜索标题" confirm-type="search" @confirm="gotoSearch()"/>
                    </view>
                </view>
                <!--列表-->
                <view class="list d-s-c f-w">
                    <view class="item d-stretch" v-for="(item, index) in listData" :key="index" >
                        <view class="product-info d-b-c d-c" @click="gotoDetail(item)">
                            <view class="product-title f26 gray3">
                               {{ item.name }}
                            </view>
                            <view class="people-num price d-b-c">
                                <text class="gray9 f26">{{ item.create_time }}</text>
                            </view>
                            <view class="people-num price d-b-c">
                                <text class="gray9 f26" v-if="item.status == 0">待审核</text>
                                <text style="color: green;" class="gray9 f26" v-else-if="item.status == 1">已通过</text>
                                <text style="color: red;" class="gray9 f26" v-else-if="item.status == 2">已驳回,{{ item.reject_reason }}</text>
                            </view>
                        </view>
                        <view style="float: left;">
                                    <block>
                                        <button @click="onEdit(item)" class="theme-borderbtn" style="border: 0rpx; padding: 0rpx;">编辑</button>
                                    </block>
                        </view>
                        <view style="float: right;">
                                    <block>
                                        <button @click="onCancel(item)" class="theme-borderbtn" style="border: 0rpx; padding: 0rpx;">删除</button>
                                    </block>
                        </view>
                    </view>
                </view>
                <!-- 没有记录 -->
                <view class="none-data-box" v-if="listData.length==0 && !loading">
                    <image src="/static/none.png" mode="widthFix"></image>
                    <text>暂无数据</text>
                </view>
            </scroll-view>
        </view>
        <view class="add_add" @click="addRelease()">我要发布</view>
    </view>
</template>
<script>
    export default {
        components: {
        },
        data() {
            return {
                /*手机高度*/
                phoneHeight: 0,
                /*可滚动视图区域高度*/
                scrollviewHigh: 0,
                /*列表*/
                listData: [],
                /*最后一页码数*/
                last_page: 0,
                /*当前页面*/
                page: 1,
                /*每页条数*/
                list_rows: 10,
                /*有没有更多*/
                no_more: false,
                /*是否正在加载*/
                loading: true,
                keyword:''
            };
        },
        computed: {
            /*加载中状态*/
            loadingType() {
                if (this.loading) {
                    return 1;
                } else {
                    if (this.listData.length != 0 && this.no_more) {
                        return 2;
                    } else {
                        return 0;
                    }
                }
            }
        },
        onLoad(e) {},
        onShow() {
            /*获取列表*/
            this.getlist();
        },
        mounted() {
            this.init();
        },
        onReachBottom() {},
        methods: {
            /*初始化*/
            init() {
                let _this = this;
                uni.getSystemInfo({
                    success(res) {
                        _this.scrollviewHigh  = res.windowHeight;
                    }
                });
            },
            /*可滚动视图区域到底触发*/
            scrolltolowerFunc() {
                let self = this;
                if (self.no_more) {
                    return;
                }
                self.page++;
                if (self.page <= self.last_page) {
                    self.getlist();
                } else {
                    self.no_more = true;
                }
            },
            /*搜索*/
            gotoSearch() {
                let self=this;
                self.page = 1;
                self.listData = [];
                self.getlist();
            },
            /*获取列表*/
            getlist() {
                let self = this;
                uni.showLoading({
                    title: '加载中'
                });
                self.loading = true;
                self._get(
                    'plus.release.demandProject/index', {
                        page: self.page,
                        list_rows: self.list_rows,
                        keyword:self.keyword,
                    },
                    function(res) {
                        self.loading = false;
                        self.listData = res.data.list.data;
                        self.last_page = res.data.list.last_page;
                        if (res.data.list.last_page <= 1) {
                            self.no_more = true;
                        } else {
                            self.no_more = false;
                        }
                        uni.hideLoading();
                    }
                );
            },
            /*跳转*/
            addRelease() {
                let url = 'pages3/release/demandproject/release'
                this.gotoPage(url);
            },
            /*跳转详情*/
            onEdit(e) {
                let url = 'pages3/release/demandproject/edit?project_id=' + e.project_id
                this.gotoPage(url);
            },
            //删除
            onCancel(e) {
                let self = this;
                // 请求的参数
                let id = e.project_id;
                wx.showModal({
                    title: "提示",
                    content: "您确定进行此操作吗?",
                    success: function(o) {
                        if(o.confirm){
                            self._post('plus.release.demandproject/delete', {
                                project_id:id,
                             }, (res) => {
                                    uni.showToast({
                                        title: res.msg,
                                        duration: 2000,
                                        icon: 'success',
                                    });
                                    self.page = 1;
                                    self.listData = [];
                                    self.getlist();
                            });
                        }
                    }
                });
            },
        }
    };
</script>
<style lang="scss">
    page {
        background: #f2f2f2;
    }
    .bargain-container .inner-tab {
        background: #ffffff;
    }
    .bargain-container .inner-tab .tab-list {
        height: 100rpx;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        background: #FFFFFF;
    }
    .bargain-container .inner-tab .item {
        height: 100rpx;
        line-height: 100rpx;
        white-space: nowrap;
        padding: 0 30rpx;
        font-size: 30rpx;
        color: #333333;
    }
    .bargain-container .inner-tab .item.active,
    .bargain-container .inner-tab .item .arrow.active .iconfont {
        background: #FFFFFF;
        font-size: 32rpx;
        color: #F6220C;
        position: relative;
    }
    .bargain-container .inner-tab .item.active::after {
        content: '';
        width: 60%;
        height: 4rpx;
        background: #F6220C;
        border-radius: 2rpx;
        position: absolute;
        bottom: 17rpx;
        left: 0;
        right: 0;
        margin: auto;
    }
    .bargain-container .inner-tab .box {
        display: flex;
        justify-content: center;
        align-items: center;
        flex-direction: row;
    }
    .bargain-container .inner-tab .arrows {
        margin-left: 10rpx;
        line-height: 0;
    }
    .bargain-container .inner-tab .iconfont {
        line-height: 24rpx;
        font-size: 24rpx;
    }
    .bargain-container .inner-tab .arrow,
    .bargain-container .inner-tab .svg-icon {
        width: 20rpx;
        height: 20rpx;
    }
    .bargain-container .banner-image {
        width: 100%;
        box-sizing: border-box;
    }
    .bargain-container .banner-image image {
        width: 750rpx;
        height: 365rpx;
    }
    .bargain-container .ad-datetime::v-deep text {
        color: #333333;
        font-size: 28rpx;
    }
    .bargain-container .ad-datetime::v-deep .box {
        padding: 4rpx;
        border-radius: 4rpx;
        background: #F6220C;
        color: #ffffff;
    }
    .bargain-list .list {
        padding: 20rpx;
    }
    .bargain-list .list .item {
        width: 100%;
        padding: 30rpx;
        margin-bottom: 20rpx;
        box-sizing: border-box;
        border-radius: 16rpx;
        background: #ffffff;
    }
    .bargain-list .product-cover {
        padding: 4rpx;
    }
    .bargain-list .product-cover image {
        width: 120rpx;
        height: 120rpx;
        border-radius: 12rpx;
    }
    .bargain-list .product-info {
        flex: 1;
        //padding-left: 20rpx;
        overflow: hidden;
    }
    .bargain-list .product-cover .people-num {
        position: absolute;
        right: 0;
        bottom: 0;
        left: 0;
        height: 50rpx;
        padding: 0 20rpx;
        line-height: 50rpx;
        font-size: 24rpx;
        box-sizing: border-box;
        background: rgba(0, 0, 0, 0.6);
    }
    .bargain-list .ad-datetime .box {
        padding: 4rpx;
        border-radius: 4rpx;
        background: #000000;
        color: #ffffff;
    }
    .bargain-list .product-title {
        width: 100%;
        min-height: 40rpx;
        line-height: 40rpx;
        font-size: 32rpx;
        color: #333333;
    }
    .bargain-list .people-num {
        width: 100%;
    }
    .bargain-list .already-sale {
        padding: 4rpx 0;
        color: #999;
        font-size: 24rpx;
    }
    .bargain-list .price {
        width: 100%;
        color: $dominant-color;
        font-size: 24rpx;
    }
    .bargain-list .price .num {
        padding: 0 4rpx;
    }
    .bargain-list .slider-box .slider {
        margin-top: 10rpx;
        height: 10rpx;
        background: #cccccc;
        border-radius: 5rpx;
    }
    .bargain-list .slider-box .slider-inner {
        height: 10rpx;
        background: #e2231a;
        border-radius: 5rpx;
    }
    .bargain-list .right-btn button {
        height: 60rpx;
        line-height: 60rpx;
        border-radius: 30rpx;
        background: #8D60FF;
        color: #ffffff;
        font-size: 32rpx;
    }
    .add_add {
        position: fixed;
        bottom: 20rpx;
        left: 5%;
        width: 90%;
        height: 80rpx;
        line-height: 80rpx;
        border-radius: 80rpx;
        /* background: #ff5704; */
        @include background_color('background_color');
        color: #fff;
        font-size: 30rpx;
        display: flex;
        justify-content: center;
        margin: 0 auto;
    }
</style>
mobile/pages3/release/demandproject/release.vue
New file
@@ -0,0 +1,381 @@
<template>
    <view class="evaluate pb100" :data-theme='theme()' :class="theme() || ''">
        <form @submit="formSubmit" @reset="formReset">
            <view class="evaluate-item p30">
                <view class="form-item border-b">
                    <view class="field-name">标题*:</view>
                    <input class="flex-1" v-model="form.name" type="text" placeholder-class="grary" placeholder="请输入标题" />
                </view>
                <view class="form-item border-b">
                    <view class="field-name">分类*:</view>
                    <picker @change="onChange" :value='index' :range="list">
                      <view class="label-right">
                        {{list[index]}}
                      </view>
                    </picker>
                </view>
                <view class="form-item border-b">
                    <view class="field-name">预算(元)*:</view>
                    <input class="flex-1" v-model="form.price" type="text" placeholder-class="grary" placeholder="请输入您的预算" />
                </view>
                <view class="textarea-box d-s-c f28">
                    <textarea class="p10 box-s-b border flex-1" v-model="form.content" placeholder="请输入详细要求*" />
                </view>
                <view class="upload-list d-s-c" v-model="form.image_list">
                    <view class="item" v-for="(imgs, img_num) in form.image_list" :key="img_num"  @click="deleteImg(img_num)">
                        <image :src="imgs.file_path" mode="aspectFit"></image>
                    </view>
                    <view class="item upload-btn d-c-c d-c" @click="openUpload()" v-if="form.image_list.length < 9" >
                        <text class="icon iconfont icon-xiangji"></text>
                        <text class="gray9">上传图片</text>
                    </view>
                </view>
                <view class="form-item border-b">
                    <view class="field-name">期望完成时间:</view>
                    <picker mode="date" @change="bindDateChange">
                      <view class="label-right">
                        {{form.finish_time}}
                      </view>
                    </picker>
                </view>
                <view class="form-item border-b">
                    <view class="field-name">期望地点:</view>
                    <input class="flex-1" v-model="form.detail" type="text" placeholder-class="grary" placeholder="请输入您的期望地点" />
                </view>
                <!-- <view class="form-item border-b">
                    <text class="field-name">需求所在地:</text>
                    <input class="flex-1" name="location_address" type="text"  placeholder-class="grary9" placeholder="请选择地址" v-model="short_address"
                         disabled @click="chooseLocation" />
                </view> -->
                <view class="form-item border-b">
                    <view class="field-name">公开联系方式:</view>
                    <radio-group class="d-s-c" @change="changeRadio($event,index)">
                        <label class="d-s-c make-item mr10">
                            <view><radio style="transform:scale(0.7)" color="#EE1413" :checked="show_phone == 1" value="1" /></view>
                            <view class="f26 color-57">是</view>
                        </label>
                        <label class="d-s-c make-item mr10">
                            <view><radio style="transform:scale(0.7)" color="#EE1413" :checked="show_phone == 0" value="0" /></view>
                            <view class="f26 color-57">否</view>
                        </label>
                    </radio-group>
                </view>
                <view class="form-item border-b">
                    <view class="field-name">是否展示:</view>
                    <radio-group class="d-s-c" @change="changeShow($event,index)">
                        <label class="d-s-c make-item mr10">
                            <view><radio style="transform:scale(0.7)" color="#EE1413" :checked="form.is_show == 1" value="1" /></view>
                            <view class="f26 color-57">是</view>
                        </label>
                        <label class="d-s-c make-item mr10">
                            <view><radio style="transform:scale(0.7)" color="#EE1413" :checked="form.is_show == 0" value="0" /></view>
                            <view class="f26 color-57">否</view>
                        </label>
                    </radio-group>
                </view>
            </view>
            <view v-if="!loadding" class="foot-btns" @click="submit">
                <button class="btn-red" style="background: none; border: 0;">确认提交</button>
            </view>
        </form>
        <!--上传图片-->
        <Upload v-if="isUpload" @getImgs="getImgsFunc"></Upload>
    </view>
</template>
<script>
import Upload from '@/components/upload/upload.vue';
export default {
    components: {
        Upload,
    },
    data() {
        return {
            /*是否加载完成*/
            loadding: true,
            /*页面数据*/
            tableData: [],
            form: {
                image_list:[],
                content:'',
                name:'',
                category_id:'',
                finish_time:'请选择日期',
                price:'',
                province_id: 0,
                city_id: 0,
                region_id: 0,
                longitude:'',
                latitude:'',
                location_address:'',
                detail:'',
                show_phone:1,
                is_show:1,
            },
            /*是否打开上传图片*/
            isUpload: false,
            categoryList:[],
            //所有项目列表
            list:[],
            //选中的项目
            index:0,
            location_address: '',
            short_address:'',
            show_phone:1,
            Address:[],
        };
    },
    onLoad(e){
    },
    mounted() {
    },
    onShow(){
        let self = this;
        self.getData();
    },
    methods: {
        /* 单选框 */
        changeShow(e, index) {
            let self = this;
            self.form.is_show = e.detail.value;
        },
        /* 单选框 */
        changeRadio(e, index) {
            let self = this;
            self.form.show_phone = e.detail.value;
        },
        //改变
        onChange(e) {
            let self = this;
            let val = e.detail.value;
            if(val == 0){
                self.index = 0;
                self.form.category_id = '';
                return;
            }
            self.index = val;
            let index = val - 1;
            self.form.category_id = this.categoryList[index].category_id;
        },
        bindDateChange(e){
            let self = this;
            self.form.finish_time = e.detail.value;
        },
        /*获取数据*/
        getData() {
            let self = this;
            uni.showLoading({
                title: '加载中'
            })
            self._get('plus.release.demandProject/defaultData', {
                platform: self.getPlatform(),
            }, function(res) {
                uni.hideLoading();
                self.loadding=false;
                self.categoryList = res.data.category_list;
                var list = [];
                list.push("请选择分类");
                self.categoryList.forEach(item => {
                        list.push(item.name);
                });
                self.list = list;
            });
        },
        /*提交*/
        submit() {
            let self = this;
            let formData=self.form;
            uni.showLoading({
                title: '加载中'
            });
            self._post(
                'plus.release.demandProject/add', {
                    pay_source: self.getPlatform(),
                    formData: JSON.stringify(formData),
                },
                 function(res) {
                    uni.hideLoading();
                    self.showSuccess('提交成功!',function(){
                        self.gotoPage('/pages3/release/demandproject/index', 'redirect');
                    });
                }
            );
        },
        chooseLocation(n) {
            let self=this;
             uni.authorize({
             scope: 'scope.userLocation',
             success: () => {
                 uni.chooseLocation({
                     success: function (res) {
                        console.log(res)
                         self.form.longitude=res.longitude;
                         self.form.latitude=res.latitude;
                        self.form.detail= res.address;
                         self.location_address=res.address;
                         // 获取省市区
                        setTimeout(function(){
                            self.setLocationAddress();
                        },500)
                     },fail: function (err) {
                         //console.log(err)
                    }
                 });
             },
            })
        },
        // 获取省市区 by yj
        setLocationAddress() {
            let self = this;
            self._get('user.address/setLocationAddress', {
                address: self.location_address
            }, function(res) {
                self.short_address = res.data.short_address;
                self.form.province_id = res.data.cityCode[0];
                self.form.city_id = res.data.cityCode[1];
                self.form.region_id = res.data.cityCode[2];
            });
        },
        /*打开上传图片*/
        openUpload() {
            this.isUpload = true;
        },
        /*获取上传的图片*/
        getImgsFunc(e) {
            let self = this;
            if(e&&typeof(e)!='undefined'){
                self.form.image_list = self.form.image_list.concat(e);
            }
            self.isUpload = false;
        },
        /*点击图片删除*/
        deleteImg(i,n){
            this.loadding=true;
            this.form.image_list.splice(n,1);
            this.loadding=false;
        },
    }
};
</script>
<style>
.evaluate-item {
    margin-bottom: 20rpx;
    background: #ffffff;
}
.product .cover,
.product .cover image {
    width: 160rpx;
    height: 160rpx;
}
.evaluate .grade .item .iconfont {
    width: 60rpx;
    height: 60rpx;
    line-height: 60rpx;
    border-radius: 50%;
    font-size: 40rpx;
    color: #ffffff;
    text-align: center;
}
.evaluate .grade .item {
    height: 60rpx;
    padding-right: 20rpx;
    line-height: 60rpx;
    border-radius: 30rpx;
    transition: background-color 0.4s;
}
.grade .flex-1:nth-child(1) .iconfont {
    background: #f42222;
}
.grade .flex-1:nth-child(2) .iconfont {
    background: #f2b509;
}
.grade .flex-1:nth-child(3) .iconfont {
    background: #999999;
}
.grade .flex-1.active:nth-child(1) .item {
    background: #f42222;
    color: #ffffff;
}
.grade .flex-1.active:nth-child(2) .item {
    background: #f2b509;
    color: #ffffff;
}
.grade .flex-1.active:nth-child(3) .item {
    background: #999999;
    color: #ffffff;
}
.icon-start{
    color: #f5a623;
}
.evalu-value{
    display: flex;
    margin-bottom: 30rpx;
}
.eval{
    display: flex;
    justify-content: space-around;
    align-items: center;
}
.evalu{
    display: flex;
    align-items: baseline;
    flex-direction: column;
}
.form-item {
        padding: 20rpx 0;
        margin-bottom: 20rpx;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        font-size: 28rpx;
    }
    .form-item .field-name {
        width: 180rpx;
    }
    .form-item input {
        font-size: 28rpx;
    }
</style>
<style lang="scss">
    .foot-btns {
        position: fixed;
        bottom: 20rpx;
        left: 0rpx;
        width: 90%;
        height: 80rpx;
        line-height: 80rpx;
        border-radius: 80rpx;
        /* background: #ff5704; */
        @include background_color('background_color');
        color: #fff;
        font-size: 30rpx;
        display: flex;
        justify-content: center;
        margin: 0 auto;
    }
</style>
mobile/pages3/release/project/detail.vue
New file
@@ -0,0 +1,1023 @@
<template>
    <view class="product-detail pr" :data-theme='theme()' :class="theme() || ''">
        <scroll-view scroll-y="true" class="scroll-Y scroll-box" :style="'height:' + scrollviewHigh + 'px;'" v-if="!loadding">
            <!--图片-->
            <view class="product-pic" v-if="detail.image_list.length > 0">
                <swiper
                    class="swiper"
                    indicator-active-color="#ffffff"
                    indicator-color="rgba(255,255,255,.3)"
                    :indicator-dots="indicatorDots"
                    :autoplay="autoplay"
                    :interval="interval"
                    :duration="duration"
                >
                    <swiper-item v-for="(item, index) in detail.image_list" :key="index"><image @click="yulan(detail.image_list,index)" :src="item.file_path" mode="aspectFit"></image></swiper-item>
                </swiper>
            </view>
            <!--基本信息-->
            <view class="bg-white p30 mb22">
                <view class="product-name text-ellipsis-2">
                    标题:{{ detail.name }}
                </view>
                <view class="product-describe"><text v-if="detail.product_type == 0">预算</text><text v-else>价格</text>:¥{{ detail.price }}</view>
                <view class="product-describe"><text v-if="detail.product_type == 0">期望完成时间</text><text v-else>交付时间</text>:{{ detail.finish_time }}</view>
                <view class="product-describe"><text v-if="detail.product_type == 0">期望地点</text><text v-else>服务地区</text>:{{ detail.detail }}</view>
                <view class="product-describe" v-if="detail.product_type == 0 && detail.show_phone == 1">电话:{{ user.mobile }}</view>
                <view class="product-describe" v-if="detail.tag_list.length > 0">
                       标签:<text v-for="(item, index) in detail.tag_list" :key="index">{{ item.name}};</text>
                </view>
            </view>
            <!--详情内容-->
            <view class="product-content">
                <view class="p-0-30  border-b-e">
                    <view class="group-hd d-s-c"><text class="min-name f28">详情描述</text></view>
                </view>
                <view class="content-box" v-html="detail.content"></view>
            </view>
            <view class="sage-bottom"></view>
        </scroll-view>
        <!--底部按钮-->
        <view class="btns-wrap">
            <view class="icon-box d-c-c" @click="gotoPage('/pages/index/index')">
                <button class="d-c-c d-c bg-white">
                    <text class="btn_btom pr icon iconfont icon-Homehomepagemenu gray3" style="height: 50rpx;line-height: 60rpx;"></text>
                    <text class="f22 gray3" style="height: 50rpx;line-height: 40rpx;">首页</text>
                </button>
            </view>
            <!-- <view class="icon-box d-c-c">
                <button class="d-c-c d-c bg-white">
                    <text class="icon iconfont icon-kefu2 gray3" style="height: 50rpx;line-height: 60rpx;"></text>
                    <text class="f22 gray3" style="height: 50rpx;line-height: 40rpx;">联系他</text>
                </button>
            </view> -->
            <template>
                <template>
                    <button class="buy" @click="onPayOrder()">创建订单</button>
                </template>
            </template>
        </view>
        <!--支付选择-->
        <Popup :show="isPayPopup" msg="支付方式" @hidePopup="hidePopupFunc">
            <!--支付方式-->
            <view class="buy-checkout ww100">
                <view :class="pay_type == 20 ? 'item active border-b-e' : 'item border-b-e'" @click="payTypeFunc(20)">
                    <view class="d-s-c">
                        <view class="icon-box d-c-c mr10"><span class="icon iconfont icon-weixin"></span></view>
                        <text class="key">微信支付</text>
                    </view>
                    <view class="icon-box d-c-c"></view>
                </view>
                 <view :class="pay_type == 10 ? 'item active' : 'item'" @click="payTypeFunc(10)">
                    <view class="d-s-c">
                        <view class="icon-box d-c-c mr10"><span class="icon iconfont icon-yue"></span></view>
                        <text class="key">余额支付</text>
                    </view>
                    <view class="icon-box d-c-c"></view>
                </view>
                <view :class="pay_type == 40 ? 'item active' : 'item'" @click="payTypeFunc(40)">
                    <view class="d-s-c">
                        <view class="icon-box d-c-c mr10"><span class="icon iconfont icon-yue"></span></view>
                        <text class="key">线下支付</text>
                    </view>
                    <view class="icon-box d-c-c"></view>
                </view>
            </view>
            <view class="bts"></view>
        </Popup>
    </view>
</template>
<script>
    import utils from '@/common/utils.js';
    import Popup from '@/components/uni-popup.vue';
    import {
            pay
        } from '@/common/pay.js';
    export default {
        components: {
            Popup,
        },
        data() {
            return {
                statusBarHeight: 0,
                titleBarHeight: 0,
                store_open: 1,
                store:[],
                /*手机高度*/
                phoneHeight: 0,
                /*可滚动视图区域高度*/
                scrollviewHigh: 0,
                /*是否加载完成*/
                loadding: true,
                /*是否显示面板指示点*/
                indicatorDots: false,
                /*是否知道切换*/
                autoplay: false,
                /*自动切换时间间隔*/
                interval: 2000,
                /*滑动动画时长*/
                duration: 500,
                /*项目id*/
                project_id: null,
                /*项目详情*/
                detail: {},
                user:{},
                /*是否显示支付类别弹窗*/
                isPayPopup: false,
                /*支付方式*/
                pay_type: 20,
                payData:[],
                topay:false,
        };
    },
    onLoad(e) {
        /*id*/
        this.GetStatusBarHeight();
        this.project_id = e.project_id ? e.project_id : 0;
    },
    onReady() {
        this.init();
        /*获取详情*/
        //this.getData();
    },
    onShow(){
        let self = this;
        let options = wx.getEnterOptionsSync();
        // 从半屏小程序返回时执行
        if (options.scene == '1038') {
            self.onPayResult(options.referrerInfo.extraData);
        }
        /*数据*/
        self.getData();
    },
    methods: {
        // 半屏小程序返回
        onPayResult(e) {
            let self = this;
            if (e.pay_result == 'success') {
                self.showSuccess('支付成功!',function(){
                    self.gotoPage('/pages3/release/demandorder/index', 'redirect');
                });
            } else {
                if(self.topay){
                    //兼容半屏跳转
                }else{
                    self.showError('支付失败');
                }
            }
        },
        GetStatusBarHeight() {
            // #ifdef MP-WEIXIN
            let that = this;
            const SystemInfo = uni.getSystemInfoSync();
            let statusBarHeight = SystemInfo.statusBarHeight;
            this.statusBarHeight = uni.getMenuButtonBoundingClientRect().top;
            this.titleBarHeight = uni.getMenuButtonBoundingClientRect().height;
            // #endif
            // #ifndef MP-WEIXIN
            const SystemInfo = uni.getSystemInfoSync();
            this.statusBarHeight = SystemInfo.statusBarHeight;
            this.titleBarHeight = 30;
            // #endif
        },
        /*初始化*/
        init() {
            let _this = this;
            uni.getSystemInfo({
                success(res) {
                    _this.phoneHeight = res.windowHeight;
                    // 计算组件的高度
                    let view = uni.createSelectorQuery().select('.btns-wrap');
                    view.boundingClientRect(data => {
                        let h = _this.phoneHeight - data.height;
                        //#ifdef MP-WEIXIN
                        h = _this.phoneHeight;
                        //#endif
                        _this.scrollviewHigh = h;
                    }).exec();
                }
            });
        },
        /*获取数据*/
        getData() {
            let self = this;
            let product_id = self.product_id;
            uni.showLoading({
                title: '加载中'
            });
            self._get(
                'plus.release.project/detail',
                {
                    project_id: self.project_id,
                },
                function(res) {
                    /*详情内容格式化*/
                    res.data.detail.content = utils.format_content(res.data.detail.content);
                    self.detail = res.data.detail;
                    self.user = res.data.user;
                    self.loadding = false;
                    uni.hideLoading();
                });
            },
        /*隐藏支付方式*/
        hidePopupFunc() {
            this.isPayPopup = false;
        },
        /*去支付*/
        payTypeFunc(payType) {
            let self = this;
            self.isPayPopup = false;
            uni.showLoading({
                title: '加载中'
            });
            self._post(
                'plus.release.order/submit', {
                    pay_type: payType,
                    pay_source: self.getPlatform(),
                    project_id: self.project_id,
                    //formData: JSON.stringify(formData),
                },
                function(res) {
                    self.payData = res;
                    // 半屏小程序支付
                    if (res.data.payment.is_embed) {
                        // console.log(res.data.payment);
                        uni.openEmbeddedMiniProgram({
                            appId: res.data.payment.embed_app_id,
                            path: res.data.payment.embed_path,
                            extraData: res.data.payment.extraData,
                            envVersion: 'release', // develop开发版 trial体验版 release正式版
                            success:function() {
                                console.log('打开半屏小程序成功');
                            },
                            fail:function() {
                                console.log('打开半屏小程序失败');
                            }
                        });
                        return;
                    }
                    pay(res, self, function() {
                        uni.hideLoading();
                        self.showSuccess('创建成功!',function(){
                            self.gotoPage('/pages3/release/demandorder/index', 'redirect');
                        });
                    }, function() {
                        uni.hideLoading();
                        self.showError('提交失败');
                    });
                }
            );
        },
        /*支付方式选择*/
        onPayOrder() {
            let self = this;
            if(self.detail.project_type == 1){
                //接供求项目支付订单
                self.isPayPopup = true;
            }else{
                //接需求项目创建订单
                uni.showLoading({
                    title: '加载中'
                });
                self._post(
                    'plus.release.order/createOrder', {
                        project_id: self.project_id,
                    },
                    function(res) {
                        uni.hideLoading();
                        self.showSuccess('创建成功!',function(){
                            self.gotoPage('/pages3/release/supplyorder/index', 'redirect');
                        });
                    }
                );
            }
        },
        goback() {
            let routes = getCurrentPages(); // 获取当前打开过的页面路由数组
            if (routes.length <= 1) {
                this.gotoPage('/pages/index/index');
            } else {
                uni.navigateBack();
            }
        },
    }
};
</script>
<style lang="scss">
page {
    background: #f2f2f2;
}
.product-detail {
}
    .product-detail .product-pic,
    .product-detail .product-pic .swiper,
    .product-detail .product-pic image {
        width: 750rpx;
        height: 750rpx;
    }
    .product-detail .price-wrap {
        display: flex;
        justify-content: space-between;
        align-items: center;
    }
    .product-detail .price-wrap .left {
        display: flex;
        justify-content: flex-start;
        align-items: flex-end;
    }
    .product-detail .price-wrap .new-price {
        @include font_color('price_color');
        font-size: 30rpx;
        font-weight: bold;
        margin-right: 14rpx;
    }
    .product-detail .persona_price {
        color: #e7032c;
        font-weight: bold;
        line-height: 20px;
    }
    .fn{
        font-weight: normal;
    }
    .product-detail .price-wrap .new-price .num {
        padding: 0 4rpx;
        font-size: 40rpx;
    }
    .product-detail .price-wrap .old-price {
        font-size: 26rpx;
        color: #999999;
        text-decoration: line-through;
    }
    .product-detail .already-sale {
        font-size: 24rpx;
        color: #999999;
    }
    .product-detail .product-name {
        padding-top: 26rpx;
        font-size: 30rpx;
        font-weight: 500;
        color: #333333;
    }
    .scroll-box {
        padding-bottom: env(safe-area-inset-bottom);
        box-sizing: border-box;
    }
    .product-detail .product-describe {
        /* padding: 18rpx; */
        line-height: 30rpx;
        font-size: 26rpx;
        color: #666666;
        word-break: break-all;
        margin-top: 28rpx;
    }
    .already-choice {
        background: #ffffff;
    }
    .already-choice .center-content {
        line-height: 90rpx;
    }
    .product-comment,
    .product-content {
        margin-top: 20rpx;
        background: #ffffff;
        border-bottom: 1rpx solid #fff;
    }
    .product-content .content-box p image {
        width: 100%;
    }
    .product-content .content-box {
        padding:5rpx 10rpx;
        font-size: 36rpx;
    }
    .sage-bottom {
        width: 100%;
        height: calc(100rpx + env(safe-area-inset-bottom));
    }
    .btns-wrap {
        position: fixed;
        height: 100rpx;
        right: 0;
        bottom: 0;
        left: 0;
        display: flex;
        background: #ffffff;
        align-items: center;
        padding-bottom: env(safe-area-inset-bottom);
    }
    .btns-wrap .icon-box {
        width: 92rpx;
        height: 100rpx;
    }
    .btns-wrap .icon-box .iconfont {
        font-size: 40rpx;
        color: #888888;
    }
    .btns-wrap .icon-box .iconfont .num {
        position: absolute;
        top: 10rpx;
        left: 50%;
        height: 30rpx;
        min-width: 30rpx;
        overflow: hidden;
        line-height: 32rpx;
        border-radius: 15rpx;
        font-size: 20rpx;
        color: #ffffff;
        background: red;
    }
    .btns-wrap button,
    .btns-wrap button:after {
        height: 100rpx;
        line-height: 100rpx;
        margin: 0;
        padding: 0;
        flex: 1;
        border-radius: 0;
        border: 0;
    }
    .btns-wrap button.add-cart {
        font-size: 28rpx;
        width: 214rpx;
        height: 75rpx;
        line-height: 75rpx;
        border-top-left-radius: 40rpx;
        border-bottom-left-radius: 40rpx;
        margin-left: 17rpx;
        @include font_color('text_color2');
         @include background_linearmore('cart_left1', 'cart_left2', 'left_deg', 0%, 100%);
    }
    .btns-wrap button.add-cart-no {
        font-size: 28rpx;
        width: 214rpx;
        height: 75rpx;
        line-height: 75rpx;
        border-top-left-radius: 40rpx;
        border-bottom-left-radius: 40rpx;
        color: #FFFFFF;
        margin-left: 17rpx;
        background: #CCCCCC;
    }
    .btns-wrap button.buy {
        font-size: 28rpx;
        width: 214rpx;
        height: 75rpx;
        line-height: 75rpx;
        border-radius: 40rpx;
        margin-right: 30rpx;
        @include font_color('text_color1');
         @include background_linearmore('cart_right1', 'cart_right2', 'right_deg', 0%, 100%);
    }
    .btns-wrap button.buy.ispresale {
        line-height: 1;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
    }
    .red {
        color: #f6220c !important;
    }
    .shoucang-box {
        position: fixed;
        padding-right: 10rpx;
        width: 80rpx;
        height: 80rpx;
        right: 0;
        bottom: 270rpx;
        display: flex;
        justify-content: center;
        align-items: center;
        border-radius: 16rpx 0 0 16rpx;
        background: rgba(0, 0, 0, 0.8);
    }
    .shoucang-box button {
        padding: 0;
        background: 0;
        line-height: 60rpx;
    }
    .shoucang-box .iconfont {
        margin-bottom: 10rpx;
        font-size: 50rpx;
        color: #ffffff;
        position: relative;
        top: 5rpx;
    }
    .share-box {
        position: absolute;
        width: 60rpx;
        height: 60rpx;
        right: 0;
        bottom: -16rpx;
        display: flex;
        justify-content: center;
        align-items: center;
    }
    .share-box button {
        padding: 0;
        background: 0;
        line-height: 60rpx;
        border-radius: 0;
    }
    .share-box .iconfont {
        margin-bottom: 10rpx;
        font-size: 50rpx;
        color: #ffffff;
    }
    .sc-box {
        position: absolute;
        width: 60rpx;
        height: 60rpx;
        right: 78rpx;
        bottom: -16rpx;
        display: flex;
        justify-content: center;
        align-items: center;
    }
    .sc-box button {
        padding: 0;
        background: 0;
        line-height: 60rpx;
        border-radius: 0;
    }
    .sc-box .iconfont.icon {
        font-size: 38rpx;
    }
    .create-img {
        width: 100%;
        padding: 20rpx;
        box-sizing: border-box;
    }
    .create-img image {
        width: 100%;
    }
    .create-img button {
        width: 100%;
        height: 88rpx;
        line-height: 88rpx;
        border-radius: 44rpx;
        box-shadow: 0 8rpx 16rpx 0 rgba(226, 35, 26, 0.6);
    }
    .shop_head_info {
        margin: 20rpx;
        padding: 30rpx;
        box-sizing: border-box;
        background-color: white;
        border-radius: 12rpx;
    }
    .shop_list_body_item_shop {
        width: 100%;
        height: 120rpx;
        display: flex;
        justify-content: space-between;
    }
    .shop_list_body_item_shop_logo {
        width: 120rpx;
        height: 120rpx;
    }
    .shop_list_body_item_shop_logo image {
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.1);
        border-radius: 12rpx;
    }
    .shop_list_body_item_shop_info {
        box-sizing: border-box;
        margin-left: 20rpx;
        padding-top: 0;
        display: flex;
        justify-content: space-between;
        flex-direction: column;
    }
    .shop_list_body_item_shop_others {
        box-sizing: border-box;
        display: flex;
        justify-content: space-between;
        flex-direction: column;
        text-align: right;
        padding-top: 0;
    }
    .shop_list_body_item_shop_others button {
        width: 160rpx;
        height: 60rpx;
        border: 1rpx solid #F6220C;
        border-radius: 30rpx;
        line-height: 60rpx;
        font-size: 26rpx;
        font-family: PingFang SC;
        font-weight: 500;
        color: #F6220C;
        text-align: center;
        padding: 0;
        background-color: #ffffff;
    }
    .h1 {
        font-size: 32rpx;
    }
    .h2 {
        font-size: 28rpx;
    }
    .h3 {
        font-size: 24rpx;
    }
    .h4 {
        font-size: 20rpx;
    }
    .h5 {
        font-size: 16rpx;
    }
    .h6 {
        font-size: 12rpx;
    }
    .collect text {
        color: #f6220c;
    }
    .store_type {
        display: inline-block;
        background-color: #f6220c;
        color: #FFFFFF;
        border-radius: 7rpx;
        font-weight: 200;
        height: 35rpx;
        line-height: 35rpx;
        font-size: 21rpx;
        padding: 0 10rpx;
        margin-right: 20rpx;
    }
    .share_img {
        width: 42rpx;
        height: 42rpx;
        margin: 0 auto;
        margin-bottom: 4rpx;
    }
    .share_img.img_gray {
        -webkit-filter: grayscale(100%);
        filter: grayscale(100%);
    }
    .share_text {
        line-height: 34rpx;
    }
    .reg180 {
        padding-right: 20rpx;
        text-align: center;
        transform: rotateY(180deg);
        display: flex;
        justify-content: flex-end;
        align-items: center;
    }
    .header {
        z-index: 99;
        position: fixed;
        height: 30px;
        line-height: 30px;
        top: 0;
        left: 0;
        width: 100%;
        padding-top: var(--status-bar-height);
    }
    .header .reg180 .icon-jiantou {
        color: #FFFFFF;
        background: rgba($color: #000000, $alpha: 0.6);
        display: block;
        width: 44rpx;
        height: 44rpx;
        line-height: 44rpx;
        border-radius: 50%;
    }
    .btn_btom {
        height: 90rpx;
        line-height: 45rpx;
    }
    .btnname {
        position: absolute;
        bottom: -16px;
        left: 0;
        right: 0;
    }
    .icon-dianpu1 {
        color: #333333;
    }
    .icon-kefu2 {
        color: #333333;
    }
    .coupon_item {
        height: 40rpx;
        line-height: 40rpx;
        border-radius: 6rpx;
        background-color: #fff2f1;
        color: #f6220c;
        padding: 0 16rpx;
        text-align: center;
        font-size: 22rpx;
        margin-left: 10rpx;
    }
    .pro_nameline {
        width: 4rpx;
        height: 24rpx;
        background-color: #f6220c;
        margin-right: 12rpx;
    }
    .icon.icon-shoucang {
        font-size: 34rpx;
    }
    .icon-shoucang.gray3 {
        color: #333333;
    }
    .cart_num {
        position: absolute;
        background: #f6220c;
        width: 30rpx;
        height: 30rpx;
        display: flex;
        justify-content: center;
        align-items: center;
        font-size: 22rpx;
        border-radius: 50%;
        color: #ffff;
        right: 4rpx;
        top: 4rpx;
    }
    .video {
        width: 100%;
        height: 100%;
    }
    .product-detail .product-pic .swiper .icon-bofang {
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        margin: auto;
        font-size: 48rpx;
        color: #FFFFFF;
        border-radius: 50%;
        border: 4rpx solid #FFFFFF;
        width: 120rpx;
        height: 120rpx;
        display: flex;
        justify-content: center;
        align-items: center;
        background-color: #00000080;
        padding-left: 16rpx;
        box-sizing: border-box;
        z-index: 10;
    }
    .group-hd {
        position: relative;
        padding-left: 24rpx;
        box-sizing: border-box;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        .text-box {
            padding: 2rpx 6rpx;
            background-color: #fbe9e7;
            color: #fd5342;
            margin-right: 10rpx;
            border-radius: 4rpx;
            font-size: 20rpx;
            height: 32rpx;
            line-height: 32rpx;
        }
    }
    .group-hd.d-b-s {
        height: auto;
        display: flex;
        justify-content: space-between;
        align-items: flex-start;
    }
    .text-box {
        padding: 2rpx 6rpx;
        background-color: #fbe9e7;
        color: #fd5342;
        margin-right: 10rpx;
        border-radius: 4rpx;
        font-size: 20rpx;
        height: 32rpx;
        line-height: 32rpx;
    }
    .group-hd::after {
        content: '';
        width: 8rpx;
        height: 33rpx;
        position: absolute;
        top: 30rpx;
        left: 0;
        @include background_linear('titleft1', 'titleft2', 180deg, 0%, 100%);
    }
    .hide.group-hd::after {
        width: 0;
    }
    .group-hd .line-h-90 {
        line-height: 90rpx;
    }
    .group-hd .line-h-50 {
        line-height: 50rpx;
    }
    .text-coupon-list {
        display: flex;
        justify-content: flex-start;
        align-items: center;
        flex-wrap: wrap;
    }
    .text-coupon-box {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 32rpx;
        border: 1rpx solid #DDDDDD;
        border-radius: 5rpx;
        position: relative;
        box-sizing: border-box;
        padding: 0 16rpx;
    }
    .text-coupon {
        color: #FF5649;
        font-size: 18rpx;
    }
    .text-coupon-left {
        position: absolute;
        left: -5rpx;
        width: 10rpx;
        height: 10rpx;
        border-radius: 50%;
        border-right: 1rpx solid #DDDDDD;
        z-index: 0;
        background: #ffffff;
    }
    .text-coupon-right {
        position: absolute;
        right: -5rpx;
        width: 10rpx;
        height: 10rpx;
        border-radius: 50%;
        border-left: 1rpx solid #DDDDDD;
        z-index: 0;
        background: #ffffff;
    }
    /* 预售 */
    .product-detail .limited-spike {
        position: relative;
        z-index: 2;
        margin-top: -112rpx;
        padding: 0 35rpx;
        color: #ffffff;
        background: linear-gradient(140deg, #F11E0B 0%, #F77737 100%);
        border-radius: 15rpx;
        height: 278rpx;
        padding: 40rpx 21rpx;
        box-sizing: border-box;
    }
    .product-detail .limited-spike .left-name {
        font-size: 22rpx;
        color: #ffffff;
    }
    .product-detail .limited-spike .right-time {
        position: absolute;
        right: 20rpx;
        top: 58rpx;
    }
    .product-detail .limited-spike .right-time .jiantou {
        width: 20rpx;
        height: 20rpx;
        margin-left: 9rpx;
    }
    .mt-down-box {
        margin-top: -107rpx;
        z-index: 3;
        position: relative;
        border-radius: 15rpx;
    min-height: 68rpx;
    }
    .tips-box {
        margin-left: 8rpx;
        height: 40rpx;
        line-height: 40rpx;
        padding: 0 24rpx 0 14rpx;
        box-sizing: border-box;
        font-size: 20rpx;
        font-weight: 500;
        color: #FFFFFF;
        background-color: rgba($color: #ffffff, $alpha: 0.45);
        border-radius: 20rpx;
    }
    .product-detail .product-presale {
        padding: 26rpx;
        line-height: 40rpx;
        font-size: 26rpx;
        color: #666666;
        background-color: rgba($color: #31C19E, $alpha: 0.1);
        border-radius: 12rpx;
        word-break: break-all;
        margin-top: 28rpx;
    }
    .staff_item{
        background-color: #f6f6f6;
        border-radius: 10rpx;
    }
    .staff-image {
        width: 108rpx;
        height: 108rpx;
    }
</style>
mobile/pages3/release/project/list.vue
New file
@@ -0,0 +1,439 @@
<template>
    <view class="bargain-container" :data-theme='theme()' :class="theme() || ''">
        <!--内容-->
        <view class="bargain-list" v-if="!loading">
            <scroll-view scroll-y="true" class="scroll-Y" :style="'height:' + scrollviewHigh + 'px;'" lower-threshold="50" @scrolltolower="scrolltolowerFunc">
                <!-- 搜索框 -->
                <view class="d-b-c" id="searchBox">
                    <view class="index-search t-c flex-1" style="height: 70rpx; line-height: 70rpx; margin: 10rpx;">
                        <span class="icon iconfont icon-sousuo"></span>
                        <input type="text" v-model="keyword" class="flex-1 ml10 f30 gray3" value="" placeholder-class="f24 gray6"
                         placeholder="搜索标题" confirm-type="search" @confirm="gotoSearch()"/>
                    </view>
                </view>
                <view v-if="category_list.length>0" style="position: relative;">
                    <view class="scroll_box">
                        <scroll-view class="scroll" scroll-x="true" upper-threshode="50">
                                <view :class="category_id == 0?'scroll-view-item_H active':'scroll-view-item_H'"  @click="changeCategory(0)">全部</view>
                                <view v-for="(item,index) in category_list" :key="index" :class="category_id==item.category_id?'scroll-view-item_H active':'scroll-view-item_H'"  @click="changeCategory(item.category_id)">{{item.name}}</view>
                         </scroll-view>
                    </view>
                </view>
                <!--列表-->
                <view class="list d-s-c f-w">
                    <view class="item d-stretch" v-for="(item, index) in listData" :key="index" >
                        <view class="product-info d-b-c d-c" @click="gotoDetail(item)">
                            <view style="border-bottom: 1px solid #ccc; width: 100%; display: flex; justify-content: flex-start; align-items: center; padding-bottom: 5rpx;">
                                <image style="width:100rpx;height: 100rpx; border-radius: 50%; margin-right: 10rpx;" :src="item.user.avatarUrl" mode="widthFix"></image>
                                {{ item.user.nickName }}
                            </view>
                            <view class="product-title f26 gray3">
                               {{ item.name }}
                            </view>
                            <view class="people-num price d-b-c">
                                <text class="red f26">¥{{item.price}}</text>
                                <text class="gray9 f26">{{ item.category.name }}</text>
                            </view>
                            <view class="people-num price d-b-c">
                                <text class="gray9 f26">{{ item.create_time }}</text>
                            </view>
                        </view>
                    </view>
                </view>
                <!-- 没有记录 -->
                <view class="none-data-box" v-if="listData.length==0 && !loading">
                    <image src="/static/none.png" mode="widthFix"></image>
                    <text>暂无数据</text>
                </view>
            </scroll-view>
        </view>
    </view>
</template>
<script>
    export default {
        components: {
        },
        data() {
            return {
                /*手机高度*/
                phoneHeight: 0,
                /*可滚动视图区域高度*/
                scrollviewHigh: 0,
                /*列表*/
                listData: [],
                /*最后一页码数*/
                last_page: 0,
                /*当前页面*/
                page: 1,
                /*每页条数*/
                list_rows: 10,
                /*有没有更多*/
                no_more: false,
                /*是否正在加载*/
                loading: true,
                keyword:'',
                category_id:'',
                product_type:0,
                category_list:[],
            };
        },
        computed: {
            /*加载中状态*/
            loadingType() {
                if (this.loading) {
                    return 1;
                } else {
                    if (this.listData.length != 0 && this.no_more) {
                        return 2;
                    } else {
                        return 0;
                    }
                }
            }
        },
        onLoad(e) {
            if(e.product_type){
                this.product_type = e.product_type;
            }
        },
        onShow() {
            /*获取列表*/
            this.getlist();
        },
        mounted() {
            this.init();
        },
        onReachBottom() {},
        methods: {
            initData(){
                let self=this;
                self.page = 1;
                self.listData = [];
                self.no_more=false;
            },
            /*初始化*/
            init() {
                let _this = this;
                uni.getSystemInfo({
                    success(res) {
                        _this.scrollviewHigh  = res.windowHeight;
                    }
                });
            },
            /*可滚动视图区域到底触发*/
            scrolltolowerFunc() {
                let self = this;
                if (self.no_more) {
                    return;
                }
                self.page++;
                if (self.page <= self.last_page) {
                    self.getlist();
                } else {
                    self.no_more = true;
                }
            },
            changeCategory(e) {
                let self = this;
                self.category_id = e;
                self.listData = [];
                self.page = 1;
                self.no_more = false;
                self.loading = true;
                self.getlist();
            },
            /*搜索*/
            gotoSearch() {
                let self=this;
                self.page = 1;
                self.listData = [];
                self.getlist();
            },
            /*获取列表*/
            getlist() {
                let self = this;
                uni.showLoading({
                    title: '加载中'
                });
                self.loading = true;
                self._get(
                    'plus.release.project/index', {
                        page: self.page,
                        list_rows: self.list_rows,
                        keyword:self.keyword,
                        category_id:self.category_id,
                        product_type:self.product_type,
                    },
                    function(res) {
                        self.loading = false;
                        self.category_list = res.data.category_list;
                        self.listData = res.data.list.data;
                        self.last_page = res.data.list.last_page;
                        if (res.data.list.last_page <= 1) {
                            self.no_more = true;
                        } else {
                            self.no_more = false;
                        }
                        uni.hideLoading();
                    }
                );
            },
            /*跳转详情*/
            gotoDetail(e) {
                let url = 'pages3/release/project/detail?project_id=' + e.project_id
                this.gotoPage(url);
            },
        }
    };
</script>
<style lang="scss">
    page {
        background: #f2f2f2;
    }
    .bargain-container .inner-tab {
        background: #ffffff;
    }
    .bargain-container .inner-tab .tab-list {
        height: 100rpx;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        background: #FFFFFF;
    }
    .bargain-container .inner-tab .item {
        height: 100rpx;
        line-height: 100rpx;
        white-space: nowrap;
        padding: 0 30rpx;
        font-size: 30rpx;
        color: #333333;
    }
    .bargain-container .inner-tab .item.active,
    .bargain-container .inner-tab .item .arrow.active .iconfont {
        background: #FFFFFF;
        font-size: 32rpx;
        color: #F6220C;
        position: relative;
    }
    .bargain-container .inner-tab .item.active::after {
        content: '';
        width: 60%;
        height: 4rpx;
        background: #F6220C;
        border-radius: 2rpx;
        position: absolute;
        bottom: 17rpx;
        left: 0;
        right: 0;
        margin: auto;
    }
    .bargain-container .inner-tab .box {
        display: flex;
        justify-content: center;
        align-items: center;
        flex-direction: row;
    }
    .bargain-container .inner-tab .arrows {
        margin-left: 10rpx;
        line-height: 0;
    }
    .bargain-container .inner-tab .iconfont {
        line-height: 24rpx;
        font-size: 24rpx;
    }
    .bargain-container .inner-tab .arrow,
    .bargain-container .inner-tab .svg-icon {
        width: 20rpx;
        height: 20rpx;
    }
    .bargain-container .banner-image {
        width: 100%;
        box-sizing: border-box;
    }
    .bargain-container .banner-image image {
        width: 750rpx;
        height: 365rpx;
    }
    .bargain-container .ad-datetime::v-deep text {
        color: #333333;
        font-size: 28rpx;
    }
    .bargain-container .ad-datetime::v-deep .box {
        padding: 4rpx;
        border-radius: 4rpx;
        background: #F6220C;
        color: #ffffff;
    }
    .bargain-list .list {
        padding: 20rpx;
    }
    .bargain-list .list .item {
        width: 100%;
        padding: 30rpx;
        margin-bottom: 20rpx;
        box-sizing: border-box;
        border-radius: 16rpx;
        background: #ffffff;
    }
    .bargain-list .product-cover {
        padding: 4rpx;
    }
    .bargain-list .product-cover image {
        width: 120rpx;
        height: 120rpx;
        border-radius: 12rpx;
    }
    .bargain-list .product-info {
        flex: 1;
        //padding-left: 20rpx;
        overflow: hidden;
    }
    .bargain-list .product-cover .people-num {
        position: absolute;
        right: 0;
        bottom: 0;
        left: 0;
        height: 50rpx;
        padding: 0 20rpx;
        line-height: 50rpx;
        font-size: 24rpx;
        box-sizing: border-box;
        background: rgba(0, 0, 0, 0.6);
    }
    .bargain-list .ad-datetime .box {
        padding: 4rpx;
        border-radius: 4rpx;
        background: #000000;
        color: #ffffff;
    }
    .bargain-list .product-title {
        width: 100%;
        min-height: 40rpx;
        line-height: 40rpx;
        font-size: 32rpx;
        color: #333333;
    }
    .bargain-list .people-num {
        width: 100%;
    }
    .bargain-list .already-sale {
        padding: 4rpx 0;
        color: #999;
        font-size: 24rpx;
    }
    .bargain-list .price {
        width: 100%;
        color: $dominant-color;
        font-size: 24rpx;
    }
    .bargain-list .price .num {
        padding: 0 4rpx;
    }
    .bargain-list .slider-box .slider {
        margin-top: 10rpx;
        height: 10rpx;
        background: #cccccc;
        border-radius: 5rpx;
    }
    .bargain-list .slider-box .slider-inner {
        height: 10rpx;
        background: #e2231a;
        border-radius: 5rpx;
    }
    .bargain-list .right-btn button {
        height: 60rpx;
        line-height: 60rpx;
        border-radius: 30rpx;
        background: #8D60FF;
        color: #ffffff;
        font-size: 32rpx;
    }
    .add_add {
        position: fixed;
        bottom: 20rpx;
        left: 5%;
        width: 90%;
        height: 80rpx;
        line-height: 80rpx;
        border-radius: 80rpx;
        /* background: #ff5704; */
        @include background_color('background_color');
        color: #fff;
        font-size: 30rpx;
        display: flex;
        justify-content: center;
        margin: 0 auto;
    }
    .scroll_box{
        height:80rpx;
        border-bottom: 1px solid #ccc;
    }
    .scroll{
        width: 100%;
        overflow: hidden;
        background: #fff;
        white-space: nowrap;
        position: absolute;
        left: 0px;
        top:0px;
        z-index: 999;
        font-size: 30rpx;
    }
    .scroll-view-item_H{
        height:80rpx;
        line-height: 80rpx;
        padding-left: 30rpx;
        display: inline-block;
    }
    .scroll-view-item_H.active{
        color: red;
    }
</style>
mobile/pages3/release/supplyapply/apply.vue
New file
@@ -0,0 +1,258 @@
<template>
    <view class="apply-team">
        <!--申请成功-->
        <template v-if="!is_applying && is_pass">
            <view class="form-wrap p30 f30">
                <view class="pb30 d-c-c gray3 f40 fb">
                    供应方入驻申请
                </view>
                <form @submit="formCheck" @reset="formReset">
                    <view class="form-item border-b">
                        <view class="field-name">姓名:</view>
                        <input class="flex-1 ml10" name="name" type="text" value="" placeholder-class="grary" placeholder="请输入姓名" />
                    </view>
                    <view class="form-item border-b">
                        <view class="field-name">手机号:</view>
                        <input class="flex-1 ml10" name="mobile" type="number" value="" placeholder-class="grary" placeholder="请输入手机" />
                    </view>
                    <!-- <view class="form-item border-b">
                        <text class="field-name">地址:</text>
                        <input class="flex-1 ml10" name="location_address" type="text"  placeholder-class="grary9" placeholder="请选择地址" v-model="short_address"
                             disabled @click="chooseLocation" />
                    </view> -->
                    <view class="d-c-c mt30">
                        <button class="btn-red" form-type="submit">立即申请</button>
                    </view>
                </form>
                <view class="form-wrap p30 f30" v-if="reason">
                    <view class="d-c-c pt30">
                        <text style=" font-size: 100rpx;" class="icon iconfont icon-icon_xianshi-xian"></text>
                    </view>
                    <view class="p-30-0 d-c-c gray6 f30">
                        上次的申请已被驳回,原因:{{reason}}!
                    </view>
                </view>
            </view>
        </template>
        <!--审核中-->
        <template v-if="is_applying">
            <view class="form-wrap p30 f30">
                <view class="d-c-c pt30">
                    <text style=" font-size: 100rpx;" class="icon iconfont icon-icon_xianshi-xian"></text>
                </view>
                <view class="p-30-0 d-c-c gray6 f30">
                    您的申请正在审核,请耐心等待!
                </view>
            </view>
        </template>
    </view>
</template>
<script>
    import Popup from '@/components/uni-popup.vue'
    export default {
        components: {
            Popup,
        },
        data() {
            return {
                /*弹窗是否打开*/
                isPopup: false,
                is_applying: false,
                is_release:'',
                /*小程序订阅消息*/
                temlIds: [],
                iphone_x: false,
                is_pass: true,
                reason:'',
                releaseData:[],
                province_id: 0,
                city_id: 0,
                region_id: 0,
                address: {},
                location_address: '',
                short_address:'',
            }
        },
        mounted() {
            /*数据*/
            this.getData();
        },
        created() {
            let self = this;
            uni.getSystemInfo({
                success: function (res) {
                    let model = ['X', 'XR', 'XS', '11', '12', '13', '14', '15'];
                    model.forEach(item => {
                        //适配iphoneX以上的底部,给tabbar一定高度的padding-bottom
                        if(res.model.indexOf(item) != -1 && res.model.indexOf('iPhone') != -1) {
                            self.iphone_x = true;
                        }
                    })
                }
            });
        },
        methods: {
            /*获取数据*/
            getData() {
                let self = this;
                uni.showLoading({
                    title: '加载中'
                })
                self._get('plus.release.supplyIndex/apply', {
                    platform: self.getPlatform()
                }, function(res) {
                    uni.hideLoading();
                    self.is_applying = res.data.is_applying;
                    self.is_release=res.data.is_release;
                    self.temlIds = res.data.template_arr;
                    self.releaseData = res.data.releaseData;
                    if(self.is_release){
                        uni.navigateBack({});
                    }
                    if(res.data.reason){
                        self.reason = res.data.reason;
                    }
                });
            },
            chooseLocation(n) {
                let self=this;
                 uni.authorize({
                 scope: 'scope.userLocation',
                 success: () => {
                     uni.chooseLocation({
                         success: function (res) {
                            console.log(res)
                             self.address.longitude=res.longitude;
                             self.address.latitude=res.latitude;
                             self.location_address=res.address;
                             // 获取省市区
                            setTimeout(function(){
                                self.setLocationAddress();
                            },500)
                         },fail: function (err) {
                             //console.log(err)
                        }
                     });
                 },
                })
            },
            // 获取省市区 by yj
            setLocationAddress() {
                let self = this;
                self._get('user.address/setLocationAddress', {
                    address: self.location_address
                }, function(res) {
                    self.short_address = res.data.short_address;
                    self.address.location_address = res.data.short_address;
                    self.province_id = res.data.cityCode[0];
                    self.city_id = res.data.cityCode[1];
                    self.region_id = res.data.cityCode[2];
                });
            },
            /*申请*/
            formCheck: function(e) {
                let self = this;
                let formdata = e.detail.value;
                // formdata.province_id = self.province_id;
                // formdata.city_id = self.city_id;
                // formdata.region_id = self.region_id;
                // formdata.longitude = self.address.longitude;
                // formdata.latitude = self.address.latitude;
                // formdata.location_address = self.address.location_address;
                // formdata.detail= self.location_address;
                if(formdata.name==''){
                    uni.showToast({
                        title: '请输入姓名!',
                        icon:'none'
                    });
                    return;
                }
                if(formdata.mobile.length==''){
                    uni.showToast({
                        title: '请输入手机号!',
                        icon: 'none'
                    });
                    return;
                }
                if (!/^1(3|4|5|6|7|8|9)\d{9}$/.test(formdata.mobile)) {
                    uni.showToast({
                        title: '手机有误,请重填!',
                        icon: 'none'
                    });
                    return;
                }
                // if (formdata.province_id == 0 || formdata.city_id == 0 || formdata.region_id == 0 || formdata.location_address == '') {
                //     uni.showToast({
                //             title: '请选择完整省市区',
                //             duration: 1000,
                //             icon: 'none'
                //     });
                //     return false;
                // }
                uni.showLoading({
                    title: '正在提交',
                    mask: true
                })
                self.formSubmit(formdata);
            },
            formSubmit(e) {
                let self = this;
                let callback = function(){
                    self._post('plus.release.supplyIndex/submit', e, function(res) {
                        uni.hideLoading();
                        uni.showToast({
                            title: '申请成功'
                        });
                        self.getData();
                    });
                };
                self.subMessage(self.temlIds, callback);
            },
            goback() {
                uni.navigateBack();
            },
        }
    }
</script>
<style lang="scss">
    .form-wrap {
        background: #FFFFFF;
        position: relative;
    }
    .form-item {
        padding: 20rpx 0;
        margin-bottom: 20rpx;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        font-size: 28rpx;
    }
    .form-item .field-name {
        width: 100rpx;
    }
    .form-item input {
        font-size: 28rpx;
    }
    .apply-team .btn-red {
        width: 600rpx;
        height: 88rpx;
        line-height: 88rpx;
        border-radius: 44rpx;
        box-shadow: 0 8rpx 16rpx 0 rgba(226,35,26,.6);
    }
</style>
mobile/pages3/release/supplycash/apply/apply.vue
New file
@@ -0,0 +1,338 @@
<template>
    <view class="apply-cash" v-if="!loadding">
        <!--申请成功-->
        <view class="form-wrap f30">
            <form @submit="formSubmit" @reset="formReset">
                <view class="p-0-20 pt30 txje">
                    提现金额<text class="f26 gray9 ml30">最低提现{{ release.settlement.min_money+'元' }}</text>
                </view>
                <view class="p-0-20 ">
                    <view class="withd-bc">
                        <view class="withd-bct">
                            <view style="height: 100%;display: flex;align-items: center;">
                                <text style="font-size: 48rpx;">¥</text>
                                <input class="tx-inpt" name="money" v-model="money" type="number" @input="moneyInput()"/>
                            </view>
                        </view>
                        <view class="withd-bcb">
                            可提现金额{{release.release.money}}元,提现手续费比例{{fee_rate}}%,<text @click="getAll" style="color: #0479FF;">全部提现</text>
                        </view>
                        <view class="withd-bcb">
                            当前应扣除手续费<text class="redEe">{{fee_money}}元</text>
                            ,实际到账<text class="redEe">{{real_money}}元</text>
                        </view>
                    </view>
                </view>
                <view class="p20 f32 gray3 txbt">提现方式</view>
                <view class="form-item p20">
                    <view class="ww100">
                        <template v-if="hasType('10')">
                            <view class="p-30-0 border-b">
                                <view class="d-b-c" :class="withdraw_type==10?'active':''" @click="TabType(10)">
                                    <view class="d-s-c flex-1">
                                        <image style="width: 28rpx;height: 28rpx;margin-right: 22rpx;" src="/static/wx.png" mode=""></image>
                                        <text class="f26 gray3">微信支付</text>
                                    </view>
                                    <text class="icon iconfont icon-xuanze"></text>
                                </view>
                            </view>
                        </template>
                        <template v-if="hasType('20')">
                            <view class="p-30-0 border-b">
                                <view class="d-b-c" :class="withdraw_type==20?'active':''" @click="TabType(20)">
                                    <view class="d-s-c flex-1">
                                        <image style="width: 28rpx;height: 28rpx;margin-right: 22rpx;" src="/static/zfb.png" mode=""></image>
                                        <text class="f26 gray3">支付宝</text>
                                    </view>
                                    <text class="icon iconfont icon-xuanze"></text>
                                </view>
                                <template v-if="withdraw_type==20">
                                    <view class="mt20">
                                        <input class="p20 border-tb" name="alipay_name" type="text" value="" placeholder-class="grary" placeholder="请输入姓名" />
                                    </view>
                                    <view class="mt20">
                                        <input class="p20 border-tb" name="alipay_account" type="text" value="" placeholder-class="grary" placeholder="请输入支付宝账号" />
                                    </view>
                                </template>
                            </view>
                        </template>
                        <template v-if="hasType('30')">
                            <view class="p-30-0 border-b">
                                <view class="d-b-c" :class="withdraw_type==30?'active':''" @click="TabType(30)">
                                    <view class="d-s-c flex-1">
                                        <image style="width: 28rpx;height: 22rpx;margin-right: 22rpx;" src="/static/yinxingqia.png" mode=""></image>
                                        <text class="f26 gray3">银行卡</text>
                                    </view>
                                    <text class="icon iconfont icon-xuanze"></text>
                                </view>
                                <template v-if="withdraw_type==30">
                                    <view class="mt20">
                                        <input class="p20 border-tb" name="real_name" type="text" value="" placeholder-class="grary" placeholder="请输入开户姓名" />
                                    </view>
                                    <view class="mt20">
                                        <input class="p20 border-tb" name="bank_name" type="text" value="" placeholder-class="grary" placeholder="请输入开户行名称" />
                                    </view>
                                    <view class="mt20">
                                        <input class="p20 border-tb" name="bank_account" type="text" value="" placeholder-class="grary" placeholder="请输入开户行地址" />
                                    </view>
                                    <view class="mt20">
                                        <input class="p20 border-tb" name="bank_card" type="text" value="" placeholder-class="grary" placeholder="请输入银行卡号" />
                                    </view>
                                </template>
                            </view>
                        </template>
                    </view>
                </view>
                <view class="d-c-c mt60" style="border: 16rpx solid #F2F2F2">
                    <button type="primary" class="btn-red flex-1" form-type="submit">提交申请</button>
                </view>
                <view class="fb mt20 p-0-20 gray6" v-if="explain">提现说明:</view>
                <view class="mt10 p20" v-if="explain" style="white-space: pre-wrap;">{{explain}}</view>
            </form>
        </view>
    </view>
</template>
<script>
    export default {
        components: {},
        data() {
            return {
                loadding: true,
                /*是否加载完成*/
                indicatorDots: true,
                autoplay: true,
                interval: 2000,
                duration: 500,
                /*支付类别*/
                withdraw_type: 30,
                isData: false,
                release: {},
                payType: [],
                /*小程序订阅消息*/
                temlIds: [],
                money: '',
                fee_rate:0,
                fee_money:0,
                real_money:0,
                explain:''
            }
        },
        mounted() {
            /*获取数据*/
            this.getData();
        },
        onLoad() {
            uni.setNavigationBarTitle({
                title: '申请提现'
              })
        },
        methods: {
            /*获取数据*/
            getData() {
                let self = this;
                uni.showLoading({
                    title: '加载中'
                });
                self.loadding = true;
                self._get('plus.release.cash/index', {
                    platform: self.getPlatform()
                }, function(res) {
                    self.release = res.data;
                    self.payType = self.release.settlement.pay_type;
                    self.release.isData = true;
                    self.temlIds = res.data.template_arr;
                    self.fee_rate=Number(self.release.settlement.fee_rate)||0;
                    self.explain = self.release.settlement.explain;
                    self.loadding = false;
                    uni.hideLoading();
                });
            },
            /*切换提现方式*/
            TabType(e) {
                let self = this;
                this.withdraw_type = e;
            },
            /*判断是否存在*/
            hasType(e) {
                if (this.payType.indexOf(e) != -1) {
                    return true;
                } else {
                    return false;
                }
            },
            getAll() {
                this.money = this.release.release.money;
                this.checkFee();
            },
            moneyInput(e){
                this.checkFee();
            },
            checkFee(){
                if(Number(this.money)>0){
                    this.fee_money=(Number(this.money)*Number(this.fee_rate)/100).toFixed(2);
                    this.real_money=(Number(this.money)-Number(this.fee_money)).toFixed(2);
                }else{
                    this.fee_money=0;
                    this.real_money=0;
                }
            },
            /*申请*/
            formSubmit: function(e) {
                let self = this;
                var formdata = e.detail.value;
                formdata.fee_rate=self.fee_rate;
                formdata.fee_money=self.fee_money;
                formdata.real_money=self.real_money;
                formdata.pay_type = self.withdraw_type;
                var data = JSON.stringify(formdata);
                let callback = function() {
                    uni.showLoading({
                        title: '正在提交',
                        mask: true
                    })
                    self._post('plus.release.Cash/submit', {
                        data: data
                    }, function(data) {
                        uni.hideLoading();
                        uni.showToast({
                            title: '申请成功',
                            duration: 2000,
                            icon: 'success'
                        });
                        setTimeout(function(){
                            uni.navigateBack(-1);
                        },200);
                    });
                }
                self.subMessage(self.temlIds, callback);
            },
        }
    }
</script>
<style>
    page {
        background-color: #F2F2F2;
    }
    .txje {
        font-size: 32rpx;
        font-family: PingFang SC;
        font-weight: 500;
        color: #333333;
        margin-top: 16rpx;
    }
    .apply-cash {
        /* padding-top: 16rpx; */
    }
    .form-wrap {
        /* border-radius: 20rpx; */
        background: #FFFFFF;
        /* box-shadow: 0 0 16rpx 0 rgba(0, 0, 0, .2); */
    }
    .form-item {
        margin-bottom: 20rpx;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        font-size: 28rpx;
    }
    .form-item .field-name {
        width: 140rpx;
    }
    .form-item input {
        font-size: 28rpx;
    }
    .txbt {
        border-top: 16rpx solid #F2F2F2;
    }
    .form-item .text-price {
        padding: 0 10rpx;
        height: 80rpx;
        line-height: 80rpx;
        border-radius: 40rpx;
        border: 1px solid #CCCCCC;
    }
    .agreement-content {
        max-height: 60vh;
        overflow-y: auto;
    }
    .iconfont.icon-xuanze {
        font-size: 30rpx;
    }
    .form-item .active .iconfont.icon-xuanze {
        color: #FF5649;
    }
    .apply-cash .btn-red {
        height: 88rpx;
        line-height: 88rpx;
        border-radius: 44rpx;
        background: #FF5649;
        border-color: #FF5649;
        border: none;
        font-size: 32rpx;
    }
    .withd-b {
        background-color: #FFFFFF;
        margin-bottom: 97rpx;
    }
    .withd-bct {
        height: 92rpx;
        padding-top: 59rpx;
        padding-right: 49rpx;
        display: flex;
        justify-content: space-between;
        align-items: center;
        border-bottom: 1rpx solid #d0d0d0;
    }
    .tx-inpt {
        background-color: #FFFFFF;
        font-size: 48rpx;
        line-height: 92rpx;
    }
    .withd-bcb {
        font-size: 26rpx;
        color: #999999;
        padding: 27rpx 0 49rpx 0;
    }
    .withdrawal-btn {
        margin: 0 30rpx;
        background-color: #f36a24;
        height: 60rpx;
        line-height: 60rpx;
        color: #FFFFFF;
        text-align: center;
        border-radius: 30rpx;
        padding: 0;
        font-size: 24rpx;
    }
    .border-tb{
        border: none;
        border-top: 1rpx solid #eeeeee;
        border-bottom: 1rpx solid #eeeeee;
    }
</style>
mobile/pages3/release/supplycash/list/list.vue
New file
@@ -0,0 +1,200 @@
<template>
    <view>
        <!--切换-->
        <view class="top-tabbar">
            <view :class="state_active == item.value? 'tab-item active' : 'tab-item'" @click="stateFunc(item.value)"
                v-for="(item,index) in tableList" :key="index">{{item.text}}</view>
        </view>
        <!--列表-->
        <scroll-view scroll-y="true" class="scroll-Y" :style="'height:' + scrollviewHigh + 'px;'" lower-threshold="50"
            @scrolltoupper="scrolltoupperFunc" @scrolltolower="scrolltolowerFunc">
            <view class="p-0-30 bg-white mt20">
                <view class="d-b-c border-b p-20-0" v-for="(item,index) in tableData" :key="index">
                    <view class="d-s-s f-w d-c flex-1">
                        <text class="f28 mb16">提现</text>
                        <text class="gray9 f22">手续费:<text class="orange">{{ item.fee_money||0 }}元</text>; 实际到账:<text class="orange">{{ item.real_money || item.money }}元</text></text>
                        <text class="gray9 f22">{{item.create_time}}</text>
                    </view>
                    <view>
                        <view class="tr" :class="item.apply_status.text=='审核通过'?'green':'gray9'">
                            {{ item.apply_status.text }}
                        </view>
                        <view class="red ml20">¥{{ item.money }}</view>
                    </view>
                </view>
                <!--<view class="">
                    <view class="bottom-refresh">
                        <view class="d-c-c p30" v-if="tableData.length && no_more">
                            <text class="gray3">亲, 没有更多了</text>
                        </view>
                        <view v-if="loading" class="d-c-c p30">
                            <text class="gray3">加载中...</text>
                        </view>
                    </view>
                </view>-->
                <!-- 没有记录 -->
                <view class="d-c-c p30" v-if="tableData.length==0 && !loading">
                    <text class="iconfont icon-wushuju"></text>
                    <text class="cont">亲,暂无相关记录哦</text>
                </view>
                <uni-load-more v-else :loadingType="loadingType"></uni-load-more>
            </view>
        </scroll-view>
    </view>
</template>
<script>
    import uniLoadMore from "@/components/uni-load-more.vue";
    export default {
        components: {
            uniLoadMore
        },
        data() {
            return {
                /*手机高度*/
                phoneHeight: 0,
                /*可滚动视图区域高度*/
                scrollviewHigh: 0,
                /*状态选中*/
                state_active: -1,
                /*数据列表*/
                tableData: [],
                no_more: false,
                loading: true,
                /*最后一页码数*/
                last_page: 0,
                /*当前页面*/
                page: 1,
                /*每页条数*/
                list_rows: 20,
                tableList: [],
            }
        },
        computed: {
            /*加载中状态*/
            loadingType() {
                if (this.loading) {
                    return 1;
                } else {
                    if (this.tableData.length != 0 && this.no_more) {
                        return 2;
                    } else {
                        return 0;
                    }
                }
            }
        },
        mounted() {
            /*初始化*/
            this.init();
            /*获取数据*/
            this.getData();
        },
        methods: {
            /*初始化*/
            init() {
                let self = this;
                uni.getSystemInfo({
                    success(res) {
                        self.phoneHeight = res.windowHeight;
                        // 计算组件的高度
                        let view = uni.createSelectorQuery().select('.top-tabbar');
                        view.boundingClientRect(data => {
                            let h = self.phoneHeight - data.height;
                            self.scrollviewHigh = h;
                        }).exec();
                    }
                });
            },
            /*获取数据*/
            getData() {
                let self = this;
                let page = self.page;
                self.loading = true;
                let list_rows = self.list_rows;
                self._get('plus.release.cash/lists', {
                    status: self.state_active,
                    page: page || 1,
                    list_rows: list_rows,
                }, function(data) {
                    self.loading = false;
                     // 导航栏数据
                        self.tableList  = [{
                            value: -1,
                            text: '全部',
                          }, {
                            value: 10,
                            text: '审核中',
                          }, {
                            value: 20,
                            text: '审核通过',
                          },
                          {
                            value: 40,
                            text: '已打款',
                          },
                          {
                            value: 30,
                            text: '已驳回',
                          }
                        ];
                    self.tableData = self.tableData.concat(data.data.list.data);
                    self.last_page = data.data.list.last_page;
                    if (data.data.list.last_page <= 1) {
                        self.no_more = true;
                        return false;
                    }
                });
            },
            /*切换*/
            stateFunc(e) {
                let self = this;
                if(e!=self.state_active){
                    self.tableData = [];
                    self.page = 1;
                    self.state_active = e;
                    self.getData();
                }
            },
            /*可滚动视图区域到顶触发*/
            scrolltoupperFunc() {
                console.log('滚动视图区域到顶');
            },
            /*可滚动视图区域到底触发*/
            scrolltolowerFunc() {
                let self = this;
                if (self.page < self.last_page) {
                    self.page++;
                    self.getData();
                }
                self.no_more = true;
            }
        }
    }
</script>
<style lang="scss">
    .tab-item {
        font-size: 28rpx;
    }
    .tab-item.active {
        font-weight: normal;
        font-size: 28rpx;
    }
    .tab-item.active::after {
        width: 57rpx;
        height: 6rpx;
        background-color: #ff5649;
    }
</style>
mobile/pages3/release/supplyindex/index.vue
New file
@@ -0,0 +1,373 @@
<template>
    <view class="index-team o-h" v-if="!loadding">
        <!-- #ifdef MP-WEIXIN || APP-PLUS -->
        <view v-if="!is_release && isData" class="ww100" :style="'height:'+topBarTop()+'px;'"></view>
        <view v-if="!is_release && isData" class="tc  head_top" :style="topBarHeight() == 0 ? '': 'height:'+topBarHeight()+'px;'">
            <view class="reg180" @click="goback"><text class="icon iconfont icon-jiantou"></text></view>
            <view class="fb">{{titel}}</view>
        </view>
        <!-- #endif -->
        <!--头部图片-->
        <view class="banner d-c-c d-c" v-if="!is_release && isData">
            <image :src="top_background" mode="widthFix"></image>
        </view>
        <!--是-->
        <template v-if="is_release && isData">
            <view class="agent-wrap pr m-0-20 mt20">
                <view class="d-b-c f28 lh150 user-info">
                    <view class="d-b-c">
                        <view class="photo">
                            <image :src="user.avatarUrl" mode="aspectFill"></image>
                        </view>
                        <view class="user-name">
                            <view class="gray3 f32">{{ user.nickName }}</view>
                        </view>
                    </view>
                </view>
                <view class="d-s-c p-30-0 top_dash">
                    <view class="flex-1 d-c-c d-c">
                        <view class="redF6">
                            <text class="f24">¥</text>
                            <text class="f40">{{ release.money }}</text>
                        </view>
                        <view class="pt20 f26 gray3">可提现</view>
                    </view>
                    <view class="flex-1 d-c-c d-c">
                        <view class="">
                            <text class="f24">¥</text>
                            <text class="f40">{{ release.freeze_money }}</text>
                        </view>
                        <view class="pt20 f28 gray3">待提现</view>
                    </view>
                    <view class="flex-1 d-c-c d-c">
                        <view class="">
                            <text class="f24">¥</text>
                            <text class="f40">{{ release.total_money }}</text>
                        </view>
                        <view class="pt20 f28 gray3">已提现</view>
                    </view>
                </view>
                <view class="d-c-c pt30">
                    <button type="primary" class="btn-gcred theme-btn flex-1" @click="gotoCash">我要提现</button>
                </view>
            </view>
            <!--图标入口-->
            <view class="agent-wrap m-0-20 p30 d-s-c f-w mt20 bg-white">
                <view class="d-c-c d-c flex-1" @click="gotoPage('/pages3/release/project/list?product_type=0')">
                    <view>
                        <image class="agent_index_img" src="../../../static/icon/icon-erweima.png" mode=""></image>
                    </view>
                    <text class="pt10 f26 mt20">供需大厅</text>
                </view>
                <view class="d-c-c d-c flex-1" @click="gotoPage('/pages3/release/supplyproject/index')">
                    <view>
                        <image class="agent_index_img" src="../../../static/icon/icon-fenxiaodingdan.png" mode=""></image>
                    </view>
                    <text class="pt10 f26 mt20">发布服务</text>
                </view>
                <view class="d-c-c d-c flex-1" @click="gotoPage('/pages3/release/supplyorder/index')">
                    <view>
                        <image class="agent_index_img" src="../../../static/icon/icon-zijinmingxi.png" mode=""></image>
                    </view>
                    <text class="pt10 f26 mt20">服务订单</text>
                </view>
                <view class="d-c-c d-c flex-1" @click="gotoPage('/pages3/release/supplycash/list/list')">
                    <view>
                        <image class="agent_index_img" src="../../../static/icon/icon-zijinmingxi.png" mode=""></image>
                    </view>
                    <text class="pt10 f26 mt20">提现明细</text>
                </view>
                <!-- <view class="d-c-c d-c flex-1" @click="gotoPage('/pages2/salesman/qrcode/qrcode')">
                    <view>
                        <image class="agent_index_img" src="../../../static/icon/icon-erweima.png" mode=""></image>
                    </view>
                    <text class="pt10 f26 mt20">关注公众号</text>
                </view> -->
            </view>
            <!-- <view class="no-team">
                <view class="mt50 p-0-20 pt30 red f34 tc">恭喜您,已申请成为</view>
            </view>
            <view class="p30 mt30">
                <button type="primary" class="btn-gcred" @click="toOrder()">立即</button>
            </view>     -->
        </template>
        <!--不是-->
        <template v-if="!is_release && isData">
            <view class="no-team">
                <view class="mt50 p-0-20 pt30 red f34 tc">很抱歉,您还不是供应方</view>
            </view>
            <view class="p30 mt30">
                <button type="primary" class="btn-gcred" @click="apply()">立即申请入驻</button>
            </view>
        </template>
    </view>
</template>
<script>
    export default {
        data() {
            return {
                /*是否加载完成*/
                loadding: true,
                indicatorDots: true,
                autoplay: true,
                interval: 2000,
                duration: 500,
                is_release: false,
                isData: false,
                release: {},
                /*顶部背景*/
                top_background: '',
                user:[],
            };
        },
        onLoad(e) {
        },
        onShow() {
            uni.showLoading({
                title: '加载中'
            });
            /*获取数据*/
            this.getData();
        },
        methods: {
            /*获取数据*/
            getData() {
                let self = this;
                self._get('plus.release.supplyIndex/index', {}, function(data) {
                    self.is_release= data.data.is_release;
                    self.top_background = data.data.background;
                    self.release = data.data.release;
                    self.user = data.data.user;
                    self.isData = true;
                    self.loadding = false;
                    uni.hideLoading();
                });
            },
            /*申请入驻*/
            apply() {
                this.gotoPage('/pages3/release/supplyapply/apply');
            },
            /*发布*/
            toOrder() {
                this.gotoPage('/pages3/release/supplyorder/myorder');
            },
            /*去提现*/
            gotoCash() {
                this.gotoPage('/pages3/release/supplycash/apply/apply');
            },
            goback() {
                uni.navigateBack();
            },
        }
    };
</script>
<style lang="scss">
    page {
        background-color: #f9f9f9;
    }
    .index-agent .banner {
        position: absolute;
        width: 750rpx;
        height: 348rpx;
        z-index: 0;
        min-height: 167rpx;
        /* padding-bottom: 60rpx; */
        background-repeat: no-repeat;
        background-size: 100%;
    }
    .index-agent .banner image {
        width: 100%;
    }
    .no-agent {
        // padding-top: 190rpx;
    }
    .no-agent-image {
        padding-top: 20rpx;
        margin: 0 auto;
    }
    .no-agent-image image {
        width: 532rpx;
        height: 340rpx;
    }
    .agent-wrap {
        background: #FFFFFF;
        background-size: 100% 100%;
        padding: 31rpx 25rpx 36rpx 25rpx;
        box-shadow: 0px 8rpx 3rpx 0px rgba(6,0,1,0.03);
        border-radius: 20rpx;
    }
    .index-agent .agent-wrap .iconfont {
        font-size: 60rpx;
    }
    .index-agent .btn-gcred {
        height: 88rpx;
        line-height: 88rpx;
        border-radius: 44rpx;
        background: #FF5649;
        border-color: #FF5649;
    }
    .reg180 {
        padding-right: 20rpx;
        text-align: right;
        transform: rotateY(180deg);
        position: absolute;
        bottom: 0;
    }
    .icon-jiantou {
        color: #FFFFFF;
        font-size: 30rpx;
    }
    .head_top {
        position: absolute;
        width: 100%;
        padding-top: var(--status-bar-height);
        height: 30px;
        line-height: 30px;
        color: #FFFFFF;
        font-size: 32rpx;
        z-index: 2;
    }
    .top_dash {
        border-bottom: 1rpx dashed #D9D9D9;
        padding-bottom: 9px;
    }
    .agent_index_img {
        width: 78rpx;
        height: 78rpx;
    }
    .info-top{
        padding: 74rpx 0 63rpx 44rpx;
    }
    .info-ava {
        width: 108rpx;
        height: 108rpx;
        border-radius: 50%;
        position: relative;
        margin-right: 30rpx;
    }
    .info-avatar {
        width: 108rpx;
        height: 108rpx;
        border-radius: 50%;
    }
    .info-grade {
        min-width: 114rpx;
        height: 30rpx;
        line-height: 30rpx;
        padding: 0 22rpx;
        box-sizing: border-box;
        font-size: 18rpx;
        color: #ffffff;
        background: #FFC519;
        box-shadow: 0px 3rpx 7rpx 0px rgba(0, 0, 0, 0.15);
        border-radius: 15rpx;
        text-align: center;
        white-space: nowrap;
        position: absolute;
        left: 0;
        right: 0;
        bottom: -16rpx;
        z-index: 2;
    }
    .section-product .price {
        color: #F6220C;
        font-size: 24rpx;
    }
    .section-product .price .num {
        padding: 0 4rpx;
        font-size: 32rpx;
    }
    .section-product .level-box {
        margin-top: 20rpx;
        display: flex;
        justify-content: space-between;
        align-items: center;
    }
    .section-product .level-box .key {
        font-size: 24rpx;
        color: #999999;
    }
    .section-product .level-box .num-wrap {
        display: flex;
        justify-content: flex-end;
        align-items: center;
    }
    .section-product .level-box .icon-box {
        width: 33rpx;
        height: 33rpx;
        border: 1px solid #c5c5c5;
        background: #f2f2f2;
    }
    .section-product .level-box .icon-box .gray {
        color: #cccccc;
    }
    .section-product .level-box .icon-box .gray3 {
        color: #333333;
    }
    .section-product .level-box .text-wrap {
        margin: 0 20rpx;
        height: 33rpx;
        border: none;
        background: none;
    }
    .section-product .level-box .text-wrap input {
        padding: 0 4rpx;
        height: 33rpx;
        line-height: 1;
        width: 40rpx;
        font-size: 32rpx;
        text-align: center;
        display: flex;
        align-items: center;
        min-height: 33rpx;
    }
    .section-product .icon-jiantou {
        color: #999;
    }
    .user-info .photo,
    .user-info .photo image {
        width: 100rpx;
        height: 100rpx;
        border-radius: 50%;
    }
    .user-info .photo {
        padding-right: 20rpx;
    }
</style>
mobile/pages3/release/supplyorder/detail.vue
New file
@@ -0,0 +1,129 @@
<template>
    <view class="p30">
        <view class="title p30 bg-white f30 lh200 radius8">
            <view>姓名:{{ detail.real_name }}</view>
            <view>电话:{{ detail.mobile }}</view>
            <view>服务地址:{{ detail.detail }}</view>
            <view>服务项目:
              <text class="mr10" v-for="(item,index) in detail.project">[{{ item.project_name }}x{{ item.total_num }}]</text>
            </view>
            <view>支付费用:¥{{ detail.pay_price }}</view>
            <view>预约服务时间:{{ detail.booking_time }}
               <view class="ml20 red" style="float: right;" v-if="detail.is_settled == 0">
                   <picker mode="date" @change="bindDateChange">修改时间</picker>
               </view>
            </view>
            <view v-if="detail.settle_time">服务完成时间:{{ detail.settle_time }}</view>
            <view>服务完成图片:</view>
            <view v-for="(item, index) in img_list2" :key="index">
                 <image :src="item.file_path" mode="aspectFit"></image>
            </view>
            <view class="d-s-c" v-if="detail.repair_user_id == 0">单号:
               <input class="ml20 border-b" v-model="odd_num" type="text" placeholder="请输入单号" />
               <button style="background: none; border: 0; color: red;" @click="editChange()">确定修改</button>
            </view>
            <view class="d-s-c" v-if="detail.repair_user_id == 0">产品:
               <input class="ml20 border-b" v-model="goods_name" type="text" placeholder="请输入产品" />
               <button style="background: none; border: 0;color: red;" @click="editChange()">确定修改</button>
            </view>
            <view v-if="detail.repair_user_id > 0">单号:<text v-if="detail.odd_num != null">{{ detail.odd_num }}</text></view>
            <view v-if="detail.repair_user_id > 0">产品:<text v-if="detail.goods_name != null">{{ detail.goods_name }}</text></view>
            <view>师傅留言:<text v-if="detail.remark!= null">{{ detail.remark }}</text></view>
            <view>买家图片:</view>
            <view v-for="(item, index) in img_list" :key="index">
                 <image :src="item.file_path" mode="aspectFit"></image>
            </view>
            <view>买家留言:<text v-if="detail.content!= null">{{ detail.content }}</text></view>
            <view>备注:<text v-if="detail.message!= null">{{ detail.message }}</text></view>
              <view v-if="detail.Repairuser && detail.is_receive == 1">
                  售后师傅:{{ detail.Repairuser.real_name }} {{ detail.Repairuser.mobile }}
                  <view>温馨提示:尊敬的顾客,您好!我们已安排好师傅上门为您服务,如有需求可以致电师傅。如您对我们的服务不满意,可以和我们客服联系。</view>
              </view>
        </view>
        </view>
    </view>
</template>
<script>
    import utils from '@/common/utils.js';
    export default {
        data() {
            return {
                detail: '',
                img_list:[],
                img_list2:[],
                odd_num:'',
                goods_name:'',
            }
        },
        onLoad(e) {
            /*id*/
            this.id = e.id;
        },
        mounted(){
            uni.showLoading({
                title: '加载中'
            });
            this.getData();
        },
        methods: {
            getData(){
                let self = this;
                let id = self.id;
                self._get('plus.repair.order/detail', {id: id}, function (res)
                {
                    self.detail= res.data.detail;
                    self.img_list= res.data.detail.image;
                    self.img_list2= res.data.detail.image2;
                    self.odd_num = res.data.detail.odd_num;
                    self.goods_name = res.data.detail.goods_name;
                    uni.hideLoading();
                });
            },
            bindDateChange(e){
                let self = this;
                var booking_time = e.detail.value;
                uni.showLoading({
                    title: '加载中'
                });
                self._post(
                    'plus.repair.order/updateTime', {
                        booking_time: booking_time,
                        id: self.id,
                    },
                    function(res) {
                        uni.hideLoading();
                        self.showSuccess(res.msg,function(){
                            self.getData();
                        });
                    }
                );
            },
            editChange(e){
                let self = this;
                uni.showLoading({
                    title: '加载中'
                });
                self._post(
                    'plus.repair.order/editGoods', {
                        odd_num: self.odd_num,
                        goods_name: self.goods_name,
                        id: self.id,
                    },
                    function(res) {
                        uni.hideLoading();
                        self.showSuccess(res.msg,function(){
                            self.getData();
                        });
                    }
                );
            },
        }
    }
</script>
<style>
</style>
mobile/pages3/release/supplyorder/index.vue
New file
@@ -0,0 +1,414 @@
<template>
    <view class="bargain-container" :data-theme='theme()' :class="theme() || ''">
        <view class="top-tabbar">
            <view :class="state_active == 0 ? 'tab-item active' : 'tab-item'" @click="stateFunc(0)">全部</view>
            <view :class="state_active == 10 ? 'tab-item active' : 'tab-item'" @click="stateFunc(10)">确认订单</view>
            <view :class="state_active == 20 ? 'tab-item active' : 'tab-item'" @click="stateFunc(20)">进行中</view>
            <view :class="state_active == 30 ? 'tab-item active' : 'tab-item'" @click="stateFunc(30)">已完成</view>
            <view :class="state_active == 40 ? 'tab-item active' : 'tab-item'" @click="stateFunc(40)">已取消</view>
        </view>
        <!--内容-->
        <view class="bargain-list" v-if="!loading">
            <scroll-view scroll-y="true" class="scroll-Y" :style="'height:' + scrollviewHigh + 'px;'" lower-threshold="50">
                <!-- 搜索框 -->
                <!-- <view class="d-b-c" id="searchBox">
                    <view class="index-search t-c flex-1" style="height: 70rpx; line-height: 70rpx; margin: 10rpx;">
                        <span class="icon iconfont icon-sousuo"></span>
                        <input type="text" v-model="keyword" class="flex-1 ml10 f30 gray3" value="" placeholder-class="f24 gray6"
                         placeholder="单号" confirm-type="search" @confirm="gotoSearch()"/>
                    </view>
                </view> -->
                <!--列表-->
                <view class="list d-s-c f-w">
                    <view class="item d-stretch" v-for="(item, index) in listData" :key="index" >
                         <!-- <view class="product-cover pr" @click="gotoDetail(item)">
                            <image :src="item.image[0].file_path" mode="aspectFit"></image>
                        </view> -->
                        <view class="product-info d-b-c d-c" @click="gotoDetail(item)">
                            <view class="product-title f26 gray3">
                               <view>{{item.project_name}}</view>
                            </view>
                            <view class="people-num price d-b-c">
                                <text class="gray9 f26">{{ item.create_time }}</text>
                                <text class="red f26">{{item.state_text}}</text>
                            </view>
                        </view>
                        <view class="d-s-s">
                            <view class="pl30">
                                <view class="p-20-0">
                                    <text>订单号:</text>
                                    <text>{{ item.order_no }}</text>
                                    <text class="ml30">支付金额:</text>
                                    <text>¥{{ item.pay_price }}</text>
                                </view>
                            </view>
                        </view>
                        <view style="float: right;" v-if="item.pay_status == 10">
                                    <block>
                                        <button @click="onCancel(item)" class="theme-borderbtn" style="border: 0rpx; padding: 0rpx;">取消</button>
                                    </block>
                        </view>
                    </view>
                </view>
                <!-- 没有记录 -->
                <view class="none-data-box" v-if="listData.length==0 && !loading">
                    <image src="/static/none.png" mode="widthFix"></image>
                    <text>暂无数据</text>
                </view>
            </scroll-view>
        </view>
    </view>
</template>
<script>
    export default {
        components: {
        },
        data() {
            return {
                /*手机高度*/
                phoneHeight: 0,
                /*可滚动视图区域高度*/
                scrollviewHigh: 0,
                /*列表*/
                listData: [],
                status: 0,
                /*是否正在加载*/
                loading: true,
                order_data:[],
                /*状态选中*/
                state_active: 0,
                keyword:''
            };
        },
        computed: {},
        onLoad(e) {},
        onShow() {
            /*获取列表*/
            this.getlist();
        },
        mounted() {
            this.init();
        },
        onReachBottom() {},
        methods: {
            /*初始化*/
            init() {
                let _this = this;
                uni.getSystemInfo({
                    success(res) {
                        _this.scrollviewHigh  = res.windowHeight;
                    }
                });
            },
            /*状态切换*/
            stateFunc(e) {
                let self = this;
                if (self.state_active != e) {
                //    self.page = 1;
                    self.loading = true;
                    self.state_active = e;
                    self.listData = [];
                    self.getlist();
                }
            },
            /*搜索*/
            gotoSearch() {
                let self=this;
                //self.page = 1;
                self.listData = [];
                self.getlist();
            },
            /*获取列表*/
            getlist() {
                let self = this;
                uni.showLoading({
                    title: '加载中'
                });
                let status = self.status;
                self.loading = true;
                self._get(
                    'plus.release.order/lists', {
                        state_active:self.state_active,
                        keyword:self.keyword,
                        product_type:1,
                    },
                    function(res) {
                        self.listData = res.data.list.data;
                        uni.hideLoading();
                        self.loading = false;
                    }
                );
            },
            /*跳转详情*/
            gotoDetail(e) {
                //let url = 'pages3/release/order/detail?id=' + e.id
                //this.gotoPage(url);
            },
            /*修改*/
            onEva: function(e) {
                let self = this;
                self.order_data = e;
                self.isEva = true;
            },
            /*关闭修改*/
            closeEva: function(e) {
                let self = this;
                self.page = 1;
                self.listData = [];
                self.getlist();
                self.isEva = false;
            },
            //删除
            onCancel(e) {
                let self = this;
                // 请求的参数
                let id = e.id;
                wx.showModal({
                    title: "提示",
                    content: "您确定进行此操作吗?",
                    success: function(o) {
                        if(o.confirm){
                            self._post('plus.release.order/cancel', {
                                id:id,
                             }, (res) => {
                                    uni.showToast({
                                        title: res.msg,
                                        duration: 2000,
                                        icon: 'success',
                                    });
                                    self.page = 1;
                                    self.listData = [];
                                    self.getlist();
                            });
                        }
                    }
                });
            },
        }
    };
</script>
<style lang="scss">
    page {
        background: #f2f2f2;
    }
    .bargain-container .inner-tab {
        background: #ffffff;
    }
    .bargain-container .inner-tab .tab-list {
        height: 100rpx;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        background: #FFFFFF;
    }
    .bargain-container .inner-tab .item {
        height: 100rpx;
        line-height: 100rpx;
        white-space: nowrap;
        padding: 0 30rpx;
        font-size: 30rpx;
        color: #333333;
    }
    .bargain-container .inner-tab .item.active,
    .bargain-container .inner-tab .item .arrow.active .iconfont {
        background: #FFFFFF;
        font-size: 32rpx;
        color: #F6220C;
        position: relative;
    }
    .bargain-container .inner-tab .item.active::after {
        content: '';
        width: 60%;
        height: 4rpx;
        background: #F6220C;
        border-radius: 2rpx;
        position: absolute;
        bottom: 17rpx;
        left: 0;
        right: 0;
        margin: auto;
    }
    .bargain-container .inner-tab .box {
        display: flex;
        justify-content: center;
        align-items: center;
        flex-direction: row;
    }
    .bargain-container .inner-tab .arrows {
        margin-left: 10rpx;
        line-height: 0;
    }
    .bargain-container .inner-tab .iconfont {
        line-height: 24rpx;
        font-size: 24rpx;
    }
    .bargain-container .inner-tab .arrow,
    .bargain-container .inner-tab .svg-icon {
        width: 20rpx;
        height: 20rpx;
    }
    .bargain-container .banner-image {
        width: 100%;
        box-sizing: border-box;
    }
    .bargain-container .banner-image image {
        width: 750rpx;
        height: 365rpx;
    }
    .bargain-container .ad-datetime::v-deep text {
        color: #333333;
        font-size: 28rpx;
    }
    .bargain-container .ad-datetime::v-deep .box {
        padding: 4rpx;
        border-radius: 4rpx;
        background: #F6220C;
        color: #ffffff;
    }
    .bargain-list .list {
        padding: 20rpx;
    }
    .bargain-list .list .item {
        width: 100%;
        padding: 30rpx;
        margin-bottom: 20rpx;
        box-sizing: border-box;
        border-radius: 16rpx;
        background: #ffffff;
    }
    .bargain-list .product-cover {
        padding: 4rpx;
    }
    .bargain-list .product-cover image {
        width: 120rpx;
        height: 120rpx;
        border-radius: 12rpx;
    }
    .bargain-list .product-info {
        flex: 1;
        //padding-left: 20rpx;
        overflow: hidden;
    }
    .bargain-list .product-cover .people-num {
        position: absolute;
        right: 0;
        bottom: 0;
        left: 0;
        height: 50rpx;
        padding: 0 20rpx;
        line-height: 50rpx;
        font-size: 24rpx;
        box-sizing: border-box;
        background: rgba(0, 0, 0, 0.6);
    }
    .bargain-list .ad-datetime .box {
        padding: 4rpx;
        border-radius: 4rpx;
        background: #000000;
        color: #ffffff;
    }
    .bargain-list .product-title {
        width: 100%;
        min-height: 40rpx;
        line-height: 40rpx;
        font-size: 32rpx;
        color: #333333;
    }
    .bargain-list .people-num {
        width: 100%;
    }
    .bargain-list .already-sale {
        padding: 4rpx 0;
        color: #999;
        font-size: 24rpx;
    }
    .bargain-list .price {
        width: 100%;
        color: $dominant-color;
        font-size: 24rpx;
    }
    .bargain-list .price .num {
        padding: 0 4rpx;
    }
    .bargain-list .slider-box .slider {
        margin-top: 10rpx;
        height: 10rpx;
        background: #cccccc;
        border-radius: 5rpx;
    }
    .bargain-list .slider-box .slider-inner {
        height: 10rpx;
        background: #e2231a;
        border-radius: 5rpx;
    }
    .bargain-list .right-btn button {
        height: 60rpx;
        line-height: 60rpx;
        border-radius: 30rpx;
        background: #8D60FF;
        color: #ffffff;
        font-size: 32rpx;
    }
    .add_add {
        position: fixed;
        bottom: 20rpx;
        left: 5%;
        width: 90%;
        height: 80rpx;
        line-height: 80rpx;
        border-radius: 80rpx;
        /* background: #ff5704; */
        @include background_color('background_color');
        color: #fff;
        font-size: 30rpx;
        display: flex;
        justify-content: center;
        margin: 0 auto;
    }
</style>
mobile/pages3/release/supplyorder/popup/evaluate.vue
New file
@@ -0,0 +1,178 @@
<template>
    <view style="flex: 1;">
        <uniPopup :show="isEva" type="middle" @hidePopup="hidePopupFunc">
            <view class="ww100">
                <view class="t-c f36 pb20">评语</view>
                <view class="p-30-0 border-b-d9 border-t-d9 f32">
                    <view v-for="(item,index) in orderData.project">{{item.project_name}}x{{item.total_num}}</view>
                </view>
                <view class="d-s-c p-30-0 border-b-d9 border-t-d9 f32">
                    <view class="eval">
                        服务星级:
                        <i v-for="(itemEv,indexEv) in service" :key="indexEv" :class="itemEv?'icon iconfont icon-start':'icon iconfont icon-start1'"
                         @click="chooseServ(indexEv,index)"></i>
                    </view>
                </view>
                <view class="d-s-c p-30-0 border-b-d9 border-t-d9 f32">
                    <radio-group class="d-s-c" @change="changeRadio($event,index)">
                        <label class="d-s-c make-item mr10">
                            <view><radio style="transform:scale(0.7)" color="#EE1413" :checked="score == 10" value="10" /></view>
                            <view class="f26 color-57">好评</view>
                        </label>
                        <label class="d-s-c make-item mr10">
                            <view><radio style="transform:scale(0.7)" color="#EE1413" :checked="score == 20" value="20" /></view>
                            <view class="f26 color-57">中评</view>
                        </label>
                        <label class="d-s-c make-item mr10">
                            <view><radio style="transform:scale(0.7)" color="#EE1413" :checked="score == 30" value="30" /></view>
                            <view class="f26 color-57">差评</view>
                        </label>
                    </radio-group>
                </view>
                <view class="d-s-c p-30-0 border-b-d9 border-t-d9 f32">
                    <textarea class="border-box" placeholder="请输入你的评语" v-model="evaluate_content"></textarea>
                </view>
                <button class="revise_btn" @click="revise">确定完成</button>
            </view>
        </uniPopup>
    </view>
</template>
<script>
    import uniPopup from '@/components/uni-popup.vue';
    export default {
        data() {
            return {
                score:10,
                server_score:0,
                service:[false,false,false,false,false],
                evaluate_content:'',
            };
        },
        components: {
            uniPopup
        },
        props: ['isEva', 'orderData'],
        watch:{
            isEva(val){
            }
        },
        methods: {
            /* 服务评分 */
            chooseServ(n,m){
                let self=this;
                self.server_score =0;
                this.service.forEach((item,index)=>{
                    if(index<=n){
                        this.service.splice(index,1,true);
                        self.server_score++;
                    }else{
                        this.service.splice(index,1,false);
                    }
                })
            },
            /* 单选框 */
            changeRadio(e, index) {
                this.score = e.detail.value;
            },
            revise(){
                let self = this;
                uni.showModal({
                    title: '提示',
                    content: '此操作不可恢复,您确定已完成了吗?',
                    success: function(o) {
                        if (o.confirm) {
                            uni.showLoading({
                                title: '加载中',
                                mask: true
                            });
                            uni.showLoading({
                                    title: '正在提交',
                                    mask: true
                                })
                                self._post('plus.repair.Order/finish', {
                                    id: self.orderData.id,
                                    server_score:self.server_score,
                                    score:self.score,
                                    evaluate_content:self.evaluate_content,
                                }, function(data) {
                                    uni.hideLoading();
                                    uni.showToast({
                                        title: '操作成功',
                                        duration: 2000,
                                        icon: 'success'
                                    });
                                    setTimeout(function(){
                                        self.hidePopupFunc();
                                    },2000);
                                });
                        }
                    },
                });
            },
            hidePopupFunc(){
                this.$emit('close', {
                  type: 'success',
                })
            },
        }
    };
</script>
<style scoped lang="scss">
    .buy-checkout.vender .item .key {
        width: 200rpx;
    }
    .pr20 {
        padding-right: 20rpx;
        /* padding-bottom: 40rpx; */
    }
    .icon-box.linkmen_add{
        background-color: $dominant-color;
        width: 38rpx;
        height: 38rpx;
        border-radius: 8rpx;
        display: flex;
        justify-content: center;
        align-items: center;
    }
    .icon-box.linkmen_add .icon-jia{
        color: #FFFFFF;
        font-size: 22rpx;
    }
    .revise_btn{
        background-color: #E2231A;
        border: none;
        margin-top: 30rpx;
        color: #FFFFFF;
    }
    .t-c{
        text-align: center;
    }
    .m-30-0{
        margin: 30rpx 0;
    }
    .icon.icon-jiantou{
        color: #999999;
        font-size: 26rpx;
    }
    .icon.icon-zhanghumingcheng, .icon.icon-dizhi, .icon.icon-icon_xianshi-xian, .icon.icon-bangzhu {
        color: #333;
        font-size: 28rpx;
    }
    .address-defalut-wrap {
        padding: 0;
    }
    .icon-start{
        color: #f5a623;
    }
    .eval{
        display: flex;
        justify-content: space-around;
        align-items: center;
    }
</style>
mobile/pages3/release/supplyproject/edit.vue
New file
@@ -0,0 +1,411 @@
<template>
    <view class="evaluate pb100" :data-theme='theme()' :class="theme() || ''">
        <form @submit="formSubmit" @reset="formReset">
            <view class="evaluate-item p30">
                <view class="form-item border-b">
                    <view class="field-name">标题*:</view>
                    <input class="flex-1" v-model="form.name" type="text" placeholder-class="grary" placeholder="请输入标题" />
                </view>
                <view class="form-item border-b">
                    <view class="field-name">分类*:</view>
                    <picker @change="onChange" :value='index' :range="list">
                      <view class="label-right">
                        {{list[index]}}
                      </view>
                    </picker>
                </view>
                <view class="form-item border-b">
                    <view class="field-name">价格(元)*:</view>
                    <input class="flex-1" v-model="form.price" type="text" placeholder-class="grary" placeholder="请输入您的价格" />
                </view>
                <view class="textarea-box d-s-c f28">
                    <textarea class="p10 box-s-b border flex-1" v-model="form.content" placeholder="请输入详细描述*" />
                </view>
                <view class="upload-list d-s-c" v-model="form.image_list">
                    <view class="item" v-for="(imgs, img_num) in form.image_list" :key="img_num"  @click="deleteImg(img_num)">
                        <image :src="imgs.file_path" mode="aspectFit"></image>
                    </view>
                    <view class="item upload-btn d-c-c d-c" @click="openUpload()" v-if="form.image_list.length < 9" >
                        <text class="icon iconfont icon-xiangji"></text>
                        <text class="gray9">上传图片</text>
                    </view>
                </view>
                <view class="form-item border-b">
                    <view class="field-name">标签:</view>
                    <view>
                        <view v-if="tagList" class="tag-item" v-for="(item, index) in tagList" :key="index">
                            <label class="d-c-c" @tap.stop="checkItem(item, index)">
                                <checkbox color="red" value="cb" class="checkbox" :checked="item.checked" />
                            </label>
                            <view class="info">
                                <view class="title">{{ item.name }}</view>
                            </view>
                        </view>
                    </view>
                </view>
                <view class="form-item border-b">
                    <view class="field-name">交付时间:</view>
                    <picker mode="date" @change="bindDateChange">
                      <view class="label-right">
                        {{form.finish_time}}
                      </view>
                    </picker>
                </view>
                <view class="form-item border-b">
                    <view class="field-name">服务地区:</view>
                    <input class="flex-1" v-model="form.detail" type="text" placeholder-class="grary" placeholder="请输入您的期望地点" />
                </view>
                <view class="form-item border-b">
                    <view class="field-name">是否展示:</view>
                    <radio-group class="d-s-c" @change="changeShow($event,index)">
                        <label class="d-s-c make-item mr10">
                            <view><radio style="transform:scale(0.7)" color="#EE1413" :checked="form.is_show == 1" value="1" /></view>
                            <view class="f26 color-57">是</view>
                        </label>
                        <label class="d-s-c make-item mr10">
                            <view><radio style="transform:scale(0.7)" color="#EE1413" :checked="form.is_show == 0" value="0" /></view>
                            <view class="f26 color-57">否</view>
                        </label>
                    </radio-group>
                </view>
                <!-- <view class="form-item border-b">
                    <text class="field-name">需求所在地:</text>
                    <input class="flex-1" name="location_address" type="text"  placeholder-class="grary9" placeholder="请选择地址" v-model="short_address"
                         disabled @click="chooseLocation" />
                </view> -->
            </view>
            <view v-if="!loadding" class="foot-btns" @click="submit">
                <button class="btn-red" style="background: none; border: 0;">确认提交</button>
            </view>
        </form>
        <!--上传图片-->
        <Upload v-if="isUpload" @getImgs="getImgsFunc"></Upload>
    </view>
</template>
<script>
import Upload from '@/components/upload/upload.vue';
export default {
    components: {
        Upload,
    },
    data() {
        return {
            /*是否加载完成*/
            loadding: true,
            /*页面数据*/
            tableData: [],
            form: {
                project_id:'',
                image_list:[],
                tag_list:[],
                content:'',
                name:'',
                category_id:'',
                finish_time:'请选择日期',
                price:'',
                province_id: 0,
                city_id: 0,
                region_id: 0,
                longitude:'',
                latitude:'',
                location_address:'',
                detail:'',
                is_show:1,
            },
            /*是否打开上传图片*/
            isUpload: false,
            categoryList:[],
            tagList:[],
            //所有分类
            list:[],
            //选中的分类
            index:0,
            location_address: '',
            short_address:'',
            Address:[],
        };
    },
    onLoad(e){
        this.form.project_id = e.project_id;
    },
    mounted() {
    },
    onShow(){
        let self = this;
        self.getData();
    },
    methods: {
        /* 单选框 */
        changeShow(e, index) {
            let self = this;
            self.form.is_show = e.detail.value;
        },
        /*单选*/
        checkItem(e, index) {
            e.checked = !e.checked;
            this.$set(this.tagList, index, e);
        },
        //改变
        onChange(e) {
            let self = this;
            let val = e.detail.value;
            if(val == 0){
                self.index = 0;
                self.form.category_id = '';
                return;
            }
            self.index = val;
            let index = val - 1;
            self.form.category_id = this.categoryList[index].category_id;
        },
        bindDateChange(e){
            let self = this;
            self.form.finish_time = e.detail.value;
        },
        /*获取数据*/
        getData() {
            let self = this;
            uni.showLoading({
                title: '加载中'
            })
            self._get('plus.release.supplyProject/detail', {
                project_id: self.form.project_id,
            }, function(res) {
                uni.hideLoading();
                self.loadding=false;
                self.tagList = res.data.tag_list;
                self.categoryList = res.data.category_list;
                var detail = res.data.detail;
                var list = [];
                list.push("请选择分类");
                self.categoryList.forEach((item,index) => {
                        list.push(item.name);
                        if(item.category_id == detail.category_id){
                            self.index= index + 1;
                        }
                });
                self.list = list;
                self.form = detail;
                if(detail.image_list && detail.image_list != 'undefined'){
                    self.form.image_list = detail.image_list;
                }else{
                    self.form.image_list = [];
                }
            });
        },
        /*提交*/
        submit() {
            let self = this;
            let formData=self.form;
            //获取选中的标签
            var tag_ids = [];
            for (let j = 0; j < this.tagList.length; j++) {
                    if (this.tagList[j]['checked'] == true) {
                        tag_ids.push(this.tagList[j]['tag_id']);
                    }
            }
            formData.tag_list = tag_ids;
            uni.showLoading({
                title: '加载中'
            });
            self._post(
                'plus.release.supplyProject/edit', {
                    pay_source: self.getPlatform(),
                    formData: JSON.stringify(formData),
                },
                 function(res) {
                    uni.hideLoading();
                    self.showSuccess('提交成功!',function(){
                        self.gotoPage('/pages3/release/supplyproject/index', 'redirect');
                    });
                }
            );
        },
        chooseLocation(n) {
            let self=this;
             uni.authorize({
             scope: 'scope.userLocation',
             success: () => {
                 uni.chooseLocation({
                     success: function (res) {
                        console.log(res)
                         self.form.longitude=res.longitude;
                         self.form.latitude=res.latitude;
                        self.form.detail= res.address;
                         self.location_address=res.address;
                         // 获取省市区
                        setTimeout(function(){
                            self.setLocationAddress();
                        },500)
                     },fail: function (err) {
                         //console.log(err)
                    }
                 });
             },
            })
        },
        // 获取省市区 by yj
        setLocationAddress() {
            let self = this;
            self._get('user.address/setLocationAddress', {
                address: self.location_address
            }, function(res) {
                self.short_address = res.data.short_address;
                self.form.province_id = res.data.cityCode[0];
                self.form.city_id = res.data.cityCode[1];
                self.form.region_id = res.data.cityCode[2];
            });
        },
        /*打开上传图片*/
        openUpload() {
            this.isUpload = true;
        },
        /*获取上传的图片*/
        getImgsFunc(e) {
            let self = this;
            if(e&&typeof(e)!='undefined'){
                console.log(self.form.image_list)
                console.log('----')
                console.log(e)
                self.form.image_list = self.form.image_list.concat(e);
            }
            self.isUpload = false;
        },
        /*点击图片删除*/
        deleteImg(i,n){
            this.loadding=true;
            this.form.image_list.splice(n,1);
            this.loadding=false;
        },
    }
};
</script>
<style>
.evaluate-item {
    margin-bottom: 20rpx;
    background: #ffffff;
}
.product .cover,
.product .cover image {
    width: 160rpx;
    height: 160rpx;
}
.evaluate .grade .item .iconfont {
    width: 60rpx;
    height: 60rpx;
    line-height: 60rpx;
    border-radius: 50%;
    font-size: 40rpx;
    color: #ffffff;
    text-align: center;
}
.evaluate .grade .item {
    height: 60rpx;
    padding-right: 20rpx;
    line-height: 60rpx;
    border-radius: 30rpx;
    transition: background-color 0.4s;
}
.grade .flex-1:nth-child(1) .iconfont {
    background: #f42222;
}
.grade .flex-1:nth-child(2) .iconfont {
    background: #f2b509;
}
.grade .flex-1:nth-child(3) .iconfont {
    background: #999999;
}
.grade .flex-1.active:nth-child(1) .item {
    background: #f42222;
    color: #ffffff;
}
.grade .flex-1.active:nth-child(2) .item {
    background: #f2b509;
    color: #ffffff;
}
.grade .flex-1.active:nth-child(3) .item {
    background: #999999;
    color: #ffffff;
}
.icon-start{
    color: #f5a623;
}
.evalu-value{
    display: flex;
    margin-bottom: 30rpx;
}
.eval{
    display: flex;
    justify-content: space-around;
    align-items: center;
}
.evalu{
    display: flex;
    align-items: baseline;
    flex-direction: column;
}
.form-item {
        padding: 20rpx 0;
        margin-bottom: 20rpx;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        font-size: 28rpx;
    }
    .form-item .field-name {
        width: 180rpx;
    }
    .form-item input {
        font-size: 28rpx;
    }
    .form-item .tag-item {
        display: flex;
        align-items: center;
        margin-right: 20rpx;
        float: left;
        margin-bottom:2px;
    }
</style>
<style lang="scss">
    .foot-btns {
        position: fixed;
        bottom: 20rpx;
        left: 0rpx;
        width: 90%;
        height: 80rpx;
        line-height: 80rpx;
        border-radius: 80rpx;
        /* background: #ff5704; */
        @include background_color('background_color');
        color: #fff;
        font-size: 30rpx;
        display: flex;
        justify-content: center;
        margin: 0 auto;
    }
</style>
mobile/pages3/release/supplyproject/index.vue
New file
@@ -0,0 +1,422 @@
<template>
    <view class="bargain-container" :data-theme='theme()' :class="theme() || ''">
        <!--内容-->
        <view class="bargain-list" v-if="!loading">
            <scroll-view scroll-y="true" class="scroll-Y" :style="'height:' + scrollviewHigh + 'px;'" lower-threshold="50" @scrolltolower="scrolltolowerFunc">
                <!-- 搜索框 -->
                <view class="d-b-c" id="searchBox">
                    <view class="index-search t-c flex-1" style="height: 70rpx; line-height: 70rpx; margin: 10rpx;">
                        <span class="icon iconfont icon-sousuo"></span>
                        <input type="text" v-model="keyword" class="flex-1 ml10 f30 gray3" value="" placeholder-class="f24 gray6"
                         placeholder="搜索标题" confirm-type="search" @confirm="gotoSearch()"/>
                    </view>
                </view>
                <!--列表-->
                <view class="list d-s-c f-w">
                    <view class="item d-stretch" v-for="(item, index) in listData" :key="index" >
                        <view class="product-info d-b-c d-c" @click="gotoDetail(item)">
                            <view class="product-title f26 gray3">
                               {{ item.name }}
                            </view>
                            <view class="people-num price d-b-c">
                                <text class="gray9 f26">{{ item.create_time }}</text>
                            </view>
                            <view class="people-num price d-b-c">
                                <text class="gray9 f26" v-if="item.status == 0">待审核</text>
                                <text style="color: green;" class="gray9 f26" v-else-if="item.status == 1">已通过</text>
                                <text style="color: red;" class="gray9 f26" v-else-if="item.status == 2">已驳回,{{ item.reject_reason }}</text>
                            </view>
                        </view>
                        <view style="float: left;">
                                    <block>
                                        <button @click="onEdit(item)" class="theme-borderbtn" style="border: 0rpx; padding: 0rpx;">编辑</button>
                                    </block>
                        </view>
                        <view style="float: right;">
                                    <block>
                                        <button @click="onCancel(item)" class="theme-borderbtn" style="border: 0rpx; padding: 0rpx;">删除</button>
                                    </block>
                        </view>
                    </view>
                </view>
                <!-- 没有记录 -->
                <view class="none-data-box" v-if="listData.length==0 && !loading">
                    <image src="/static/none.png" mode="widthFix"></image>
                    <text>暂无数据</text>
                </view>
            </scroll-view>
        </view>
        <view class="add_add" @click="addRelease()">我要发布</view>
    </view>
</template>
<script>
    export default {
        components: {
        },
        data() {
            return {
                /*手机高度*/
                phoneHeight: 0,
                /*可滚动视图区域高度*/
                scrollviewHigh: 0,
                /*列表*/
                listData: [],
                /*最后一页码数*/
                last_page: 0,
                /*当前页面*/
                page: 1,
                /*每页条数*/
                list_rows: 10,
                /*有没有更多*/
                no_more: false,
                /*是否正在加载*/
                loading: true,
                keyword:''
            };
        },
        computed: {
            /*加载中状态*/
            loadingType() {
                if (this.loading) {
                    return 1;
                } else {
                    if (this.listData.length != 0 && this.no_more) {
                        return 2;
                    } else {
                        return 0;
                    }
                }
            }
        },
        onLoad(e) {},
        onShow() {
            /*获取列表*/
            this.getlist();
        },
        mounted() {
            this.init();
        },
        onReachBottom() {},
        methods: {
            /*初始化*/
            init() {
                let _this = this;
                uni.getSystemInfo({
                    success(res) {
                        _this.scrollviewHigh  = res.windowHeight;
                    }
                });
            },
            /*可滚动视图区域到底触发*/
            scrolltolowerFunc() {
                let self = this;
                if (self.no_more) {
                    return;
                }
                self.page++;
                if (self.page <= self.last_page) {
                    self.getlist();
                } else {
                    self.no_more = true;
                }
            },
            /*搜索*/
            gotoSearch() {
                let self=this;
                self.page = 1;
                self.listData = [];
                self.getlist();
            },
            /*获取列表*/
            getlist() {
                let self = this;
                uni.showLoading({
                    title: '加载中'
                });
                self.loading = true;
                self._get(
                    'plus.release.supplyProject/index', {
                        page: self.page,
                        list_rows: self.list_rows,
                        keyword:self.keyword,
                    },
                    function(res) {
                        self.loading = false;
                        self.listData = res.data.list.data;
                        self.last_page = res.data.list.last_page;
                        if (res.data.list.last_page <= 1) {
                            self.no_more = true;
                        } else {
                            self.no_more = false;
                        }
                        uni.hideLoading();
                    }
                );
            },
            /*跳转*/
            addRelease() {
                let url = 'pages3/release/supplyproject/release'
                this.gotoPage(url);
            },
            /*跳转详情*/
            onEdit(e) {
                let url = 'pages3/release/supplyproject/edit?project_id=' + e.project_id
                this.gotoPage(url);
            },
            //删除
            onCancel(e) {
                let self = this;
                // 请求的参数
                let id = e.project_id;
                wx.showModal({
                    title: "提示",
                    content: "您确定进行此操作吗?",
                    success: function(o) {
                        if(o.confirm){
                            self._post('plus.release.supplyproject/delete', {
                                project_id:id,
                             }, (res) => {
                                    uni.showToast({
                                        title: res.msg,
                                        duration: 2000,
                                        icon: 'success',
                                    });
                                    self.page = 1;
                                    self.listData = [];
                                    self.getlist();
                            });
                        }
                    }
                });
            },
        }
    };
</script>
<style lang="scss">
    page {
        background: #f2f2f2;
    }
    .bargain-container .inner-tab {
        background: #ffffff;
    }
    .bargain-container .inner-tab .tab-list {
        height: 100rpx;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        background: #FFFFFF;
    }
    .bargain-container .inner-tab .item {
        height: 100rpx;
        line-height: 100rpx;
        white-space: nowrap;
        padding: 0 30rpx;
        font-size: 30rpx;
        color: #333333;
    }
    .bargain-container .inner-tab .item.active,
    .bargain-container .inner-tab .item .arrow.active .iconfont {
        background: #FFFFFF;
        font-size: 32rpx;
        color: #F6220C;
        position: relative;
    }
    .bargain-container .inner-tab .item.active::after {
        content: '';
        width: 60%;
        height: 4rpx;
        background: #F6220C;
        border-radius: 2rpx;
        position: absolute;
        bottom: 17rpx;
        left: 0;
        right: 0;
        margin: auto;
    }
    .bargain-container .inner-tab .box {
        display: flex;
        justify-content: center;
        align-items: center;
        flex-direction: row;
    }
    .bargain-container .inner-tab .arrows {
        margin-left: 10rpx;
        line-height: 0;
    }
    .bargain-container .inner-tab .iconfont {
        line-height: 24rpx;
        font-size: 24rpx;
    }
    .bargain-container .inner-tab .arrow,
    .bargain-container .inner-tab .svg-icon {
        width: 20rpx;
        height: 20rpx;
    }
    .bargain-container .banner-image {
        width: 100%;
        box-sizing: border-box;
    }
    .bargain-container .banner-image image {
        width: 750rpx;
        height: 365rpx;
    }
    .bargain-container .ad-datetime::v-deep text {
        color: #333333;
        font-size: 28rpx;
    }
    .bargain-container .ad-datetime::v-deep .box {
        padding: 4rpx;
        border-radius: 4rpx;
        background: #F6220C;
        color: #ffffff;
    }
    .bargain-list .list {
        padding: 20rpx;
    }
    .bargain-list .list .item {
        width: 100%;
        padding: 30rpx;
        margin-bottom: 20rpx;
        box-sizing: border-box;
        border-radius: 16rpx;
        background: #ffffff;
    }
    .bargain-list .product-cover {
        padding: 4rpx;
    }
    .bargain-list .product-cover image {
        width: 120rpx;
        height: 120rpx;
        border-radius: 12rpx;
    }
    .bargain-list .product-info {
        flex: 1;
        //padding-left: 20rpx;
        overflow: hidden;
    }
    .bargain-list .product-cover .people-num {
        position: absolute;
        right: 0;
        bottom: 0;
        left: 0;
        height: 50rpx;
        padding: 0 20rpx;
        line-height: 50rpx;
        font-size: 24rpx;
        box-sizing: border-box;
        background: rgba(0, 0, 0, 0.6);
    }
    .bargain-list .ad-datetime .box {
        padding: 4rpx;
        border-radius: 4rpx;
        background: #000000;
        color: #ffffff;
    }
    .bargain-list .product-title {
        width: 100%;
        min-height: 40rpx;
        line-height: 40rpx;
        font-size: 32rpx;
        color: #333333;
    }
    .bargain-list .people-num {
        width: 100%;
    }
    .bargain-list .already-sale {
        padding: 4rpx 0;
        color: #999;
        font-size: 24rpx;
    }
    .bargain-list .price {
        width: 100%;
        color: $dominant-color;
        font-size: 24rpx;
    }
    .bargain-list .price .num {
        padding: 0 4rpx;
    }
    .bargain-list .slider-box .slider {
        margin-top: 10rpx;
        height: 10rpx;
        background: #cccccc;
        border-radius: 5rpx;
    }
    .bargain-list .slider-box .slider-inner {
        height: 10rpx;
        background: #e2231a;
        border-radius: 5rpx;
    }
    .bargain-list .right-btn button {
        height: 60rpx;
        line-height: 60rpx;
        border-radius: 30rpx;
        background: #8D60FF;
        color: #ffffff;
        font-size: 32rpx;
    }
    .add_add {
        position: fixed;
        bottom: 20rpx;
        left: 5%;
        width: 90%;
        height: 80rpx;
        line-height: 80rpx;
        border-radius: 80rpx;
        /* background: #ff5704; */
        @include background_color('background_color');
        color: #fff;
        font-size: 30rpx;
        display: flex;
        justify-content: center;
        margin: 0 auto;
    }
</style>
mobile/pages3/release/supplyproject/release.vue
New file
@@ -0,0 +1,397 @@
<template>
    <view class="evaluate pb100" :data-theme='theme()' :class="theme() || ''">
        <form @submit="formSubmit" @reset="formReset">
            <view class="evaluate-item p30">
                <view class="form-item border-b">
                    <view class="field-name">标题*:</view>
                    <input class="flex-1" v-model="form.name" type="text" placeholder-class="grary" placeholder="请输入标题" />
                </view>
                <view class="form-item border-b">
                    <view class="field-name">分类*:</view>
                    <picker @change="onChange" :value='index' :range="list">
                      <view class="label-right">
                        {{list[index]}}
                      </view>
                    </picker>
                </view>
                <view class="form-item border-b">
                    <view class="field-name">价格(元)*:</view>
                    <input class="flex-1" v-model="form.price" type="text" placeholder-class="grary" placeholder="请输入您的价格" />
                </view>
                <view class="textarea-box d-s-c f28">
                    <textarea class="p10 box-s-b border flex-1" v-model="form.content" placeholder="请输入详细描述*" />
                </view>
                <view class="upload-list d-s-c" v-model="form.image_list">
                    <view class="item" v-for="(imgs, img_num) in form.image_list" :key="img_num"  @click="deleteImg(img_num)">
                        <image :src="imgs.file_path" mode="aspectFit"></image>
                    </view>
                    <view class="item upload-btn d-c-c d-c" @click="openUpload()" v-if="form.image_list.length < 9" >
                        <text class="icon iconfont icon-xiangji"></text>
                        <text class="gray9">上传图片</text>
                    </view>
                </view>
                <view class="form-item border-b">
                    <view class="field-name">标签:</view>
                    <view>
                        <view v-if="tagList" class="tag-item" v-for="(item, index) in tagList" :key="index">
                            <label class="d-c-c" @tap.stop="checkItem(item, index)">
                                <checkbox color="red" value="cb" class="checkbox" :checked="item.checked" />
                            </label>
                            <view class="info">
                                <view class="title">{{ item.name }}</view>
                            </view>
                        </view>
                    </view>
                </view>
                <view class="form-item border-b">
                    <view class="field-name">交付时间:</view>
                    <picker mode="date" @change="bindDateChange">
                      <view class="label-right">
                        {{form.finish_time}}
                      </view>
                    </picker>
                </view>
                <view class="form-item border-b">
                    <view class="field-name">服务地区:</view>
                    <input class="flex-1" v-model="form.detail" type="text" placeholder-class="grary" placeholder="请输入您的服务地区" />
                </view>
                <view class="form-item border-b">
                    <view class="field-name">是否展示:</view>
                    <radio-group class="d-s-c" @change="changeShow($event,index)">
                        <label class="d-s-c make-item mr10">
                            <view><radio style="transform:scale(0.7)" color="#EE1413" :checked="form.is_show == 1" value="1" /></view>
                            <view class="f26 color-57">是</view>
                        </label>
                        <label class="d-s-c make-item mr10">
                            <view><radio style="transform:scale(0.7)" color="#EE1413" :checked="form.is_show == 0" value="0" /></view>
                            <view class="f26 color-57">否</view>
                        </label>
                    </radio-group>
                </view>
                <!-- <view class="form-item border-b">
                    <text class="field-name">需求所在地:</text>
                    <input class="flex-1" name="location_address" type="text"  placeholder-class="grary9" placeholder="请选择地址" v-model="short_address"
                         disabled @click="chooseLocation" />
                </view> -->
            </view>
            <view v-if="!loadding" class="foot-btns" @click="submit">
                <button class="btn-red" style="background: none; border: 0;">确认提交</button>
            </view>
        </form>
        <!--上传图片-->
        <Upload v-if="isUpload" @getImgs="getImgsFunc"></Upload>
    </view>
</template>
<script>
import Upload from '@/components/upload/upload.vue';
export default {
    components: {
        Upload,
    },
    data() {
        return {
            /*是否加载完成*/
            loadding: true,
            /*页面数据*/
            tableData: [],
            form: {
                image_list:[],
                tag_list:[],
                content:'',
                name:'',
                category_id:'',
                finish_time:'请选择日期',
                price:'',
                province_id: 0,
                city_id: 0,
                region_id: 0,
                longitude:'',
                latitude:'',
                location_address:'',
                detail:'',
                is_show:1,
            },
            /*是否打开上传图片*/
            isUpload: false,
            categoryList:[],
            tagList:[],
            //所有列表
            list:[],
            //选中的分类
            index:0,
            location_address: '',
            short_address:'',
            Address:[],
        };
    },
    onLoad(e){
    },
    mounted() {
    },
    onShow(){
        let self = this;
        self.getData();
    },
    methods: {
        /* 单选框 */
        changeShow(e, index) {
            let self = this;
            self.form.is_show = e.detail.value;
        },
        /*单选*/
        checkItem(e, index) {
            e.checked = !e.checked;
            this.$set(this.tagList, index, e);
        },
        //改变
        onChange(e) {
            let self = this;
            let val = e.detail.value;
            if(val == 0){
                self.index = 0;
                self.form.category_id = '';
                return;
            }
            self.index = val;
            let index = val - 1;
            self.form.category_id = this.categoryList[index].category_id;
        },
        bindDateChange(e){
            let self = this;
            self.form.finish_time = e.detail.value;
        },
        /*获取数据*/
        getData() {
            let self = this;
            uni.showLoading({
                title: '加载中'
            })
            self._get('plus.release.supplyProject/defaultData', {
                platform: self.getPlatform(),
            }, function(res) {
                uni.hideLoading();
                self.loadding=false;
                self.tagList = res.data.tag_list;
                self.categoryList = res.data.category_list;
                var list = [];
                list.push("请选择分类");
                self.categoryList.forEach(item => {
                        list.push(item.name);
                });
                self.list = list;
            });
        },
        /*提交*/
        submit() {
            let self = this;
            let formData=self.form;
            //获取选中的标签
            var tag_ids = [];
            for (let j = 0; j < this.tagList.length; j++) {
                    if (this.tagList[j]['checked'] == true) {
                        tag_ids.push(this.tagList[j]['tag_id']);
                    }
            }
            formData.tag_list = tag_ids;
            uni.showLoading({
                title: '加载中'
            });
            self._post(
                'plus.release.supplyProject/add', {
                    pay_source: self.getPlatform(),
                    formData: JSON.stringify(formData),
                },
                 function(res) {
                    uni.hideLoading();
                    self.showSuccess('提交成功!',function(){
                        self.gotoPage('/pages3/release/supplyproject/index', 'redirect');
                    });
                }
            );
        },
        chooseLocation(n) {
            let self=this;
             uni.authorize({
             scope: 'scope.userLocation',
             success: () => {
                 uni.chooseLocation({
                     success: function (res) {
                        console.log(res)
                         self.form.longitude=res.longitude;
                         self.form.latitude=res.latitude;
                        self.form.detail= res.address;
                         self.location_address=res.address;
                         // 获取省市区
                        setTimeout(function(){
                            self.setLocationAddress();
                        },500)
                     },fail: function (err) {
                         //console.log(err)
                    }
                 });
             },
            })
        },
        // 获取省市区 by yj
        setLocationAddress() {
            let self = this;
            self._get('user.address/setLocationAddress', {
                address: self.location_address
            }, function(res) {
                self.short_address = res.data.short_address;
                self.form.province_id = res.data.cityCode[0];
                self.form.city_id = res.data.cityCode[1];
                self.form.region_id = res.data.cityCode[2];
            });
        },
        /*打开上传图片*/
        openUpload() {
            this.isUpload = true;
        },
        /*获取上传的图片*/
        getImgsFunc(e) {
            let self = this;
            if(e&&typeof(e)!='undefined'){
                self.form.image_list = self.form.image_list.concat(e);
            }
            self.isUpload = false;
        },
        /*点击图片删除*/
        deleteImg(i,n){
            this.loadding=true;
            this.form.image_list.splice(n,1);
            this.loadding=false;
        },
    }
};
</script>
<style>
.evaluate-item {
    margin-bottom: 20rpx;
    background: #ffffff;
}
.product .cover,
.product .cover image {
    width: 160rpx;
    height: 160rpx;
}
.evaluate .grade .item .iconfont {
    width: 60rpx;
    height: 60rpx;
    line-height: 60rpx;
    border-radius: 50%;
    font-size: 40rpx;
    color: #ffffff;
    text-align: center;
}
.evaluate .grade .item {
    height: 60rpx;
    padding-right: 20rpx;
    line-height: 60rpx;
    border-radius: 30rpx;
    transition: background-color 0.4s;
}
.grade .flex-1:nth-child(1) .iconfont {
    background: #f42222;
}
.grade .flex-1:nth-child(2) .iconfont {
    background: #f2b509;
}
.grade .flex-1:nth-child(3) .iconfont {
    background: #999999;
}
.grade .flex-1.active:nth-child(1) .item {
    background: #f42222;
    color: #ffffff;
}
.grade .flex-1.active:nth-child(2) .item {
    background: #f2b509;
    color: #ffffff;
}
.grade .flex-1.active:nth-child(3) .item {
    background: #999999;
    color: #ffffff;
}
.icon-start{
    color: #f5a623;
}
.evalu-value{
    display: flex;
    margin-bottom: 30rpx;
}
.eval{
    display: flex;
    justify-content: space-around;
    align-items: center;
}
.evalu{
    display: flex;
    align-items: baseline;
    flex-direction: column;
}
.form-item {
        padding: 20rpx 0;
        margin-bottom: 20rpx;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        font-size: 28rpx;
    }
    .form-item .field-name {
        width: 180rpx;
    }
    .form-item input {
        font-size: 28rpx;
    }
    .form-item .tag-item {
        display: flex;
        align-items: center;
        margin-right: 20rpx;
        float: left;
        margin-bottom:2px;
    }
</style>
<style lang="scss">
    .foot-btns {
        position: fixed;
        bottom: 20rpx;
        left: 0rpx;
        width: 90%;
        height: 80rpx;
        line-height: 80rpx;
        border-radius: 80rpx;
        /* background: #ff5704; */
        @include background_color('background_color');
        color: #fff;
        font-size: 30rpx;
        display: flex;
        justify-content: center;
        margin: 0 auto;
    }
</style>
shop_vue/src/api/plus/release.js
New file
@@ -0,0 +1,154 @@
import request from '@/utils/request'
let PlusApi = {
    /*需求方申请列表*/
    demandApplyList(data, errorback) {
        return request._post('/shop/plus.release.demandApply/index', data, errorback);
    },
    /*审核*/
    editDemandApplyStatus(data, errorback) {
        return request._post('/shop/plus.release.demandApply/editApplyStatus', data, errorback);
    },
    /*列表*/
    demandUserList(data, errorback) {
        return request._post('/shop/plus.release.demandUser/index', data, errorback);
    },
    /*修改*/
    demandUserEdit(data, errorback) {
        return request._post('/shop/plus.release.demandUser/edit', data, errorback);
    },
    /*删除*/
    deleteDemandUser(data, errorback) {
        return request._post('/shop/plus.release.demandUser/delete', data, errorback);
    },
    /*供应方申请列表*/
    supplyApplyList(data, errorback) {
        return request._post('/shop/plus.release.supplyApply/index', data, errorback);
    },
    /*审核*/
    editSupplyApplyStatus(data, errorback) {
        return request._post('/shop/plus.release.supplyApply/editApplyStatus', data, errorback);
    },
    /*列表*/
    supplyUserList(data, errorback) {
        return request._post('/shop/plus.release.supplyUser/index', data, errorback);
    },
    /*修改*/
    supplyUserEdit(data, errorback) {
        return request._post('/shop/plus.release.supplyUser/edit', data, errorback);
    },
    /*删除*/
    deleteSupplyUser(data, errorback) {
        return request._post('/shop/plus.release.supplyUser/delete', data, errorback);
    },
    /*分类管理*/
    catList(data, errorback) {
        return request._post('/shop/plus.release.ReleaseCategory/index', data, errorback);
    },
    /*分类添加*/
    catAdd(data, errorback) {
        return request._post('/shop/plus.release.ReleaseCategory/add', data, errorback);
    },
    /*分类删除*/
    catDel(data, errorback) {
        return request._post('/shop/plus.release.ReleaseCategory/delete', data, errorback);
    },
    /*分类修改*/
    catEdit(data, errorback) {
        return request._post('/shop/plus.release.ReleaseCategory/edit', data, errorback);
    },
    /*获取标签*/
    Tag(data, errorback) {
      return request._post('/shop/plus.release.Tag/index', data, errorback);
    },
    /*添加标签*/
      addTag(data, errorback) {
      return request._post('/shop/plus.release.Tag/add', data, errorback);
    },
      /*编辑标签*/
      editTag(data, errorback) {
      return request._post('/shop/plus.release.Tag/edit', data, errorback);
    },
      /*删除标签*/
      deleteTag(data, errorback) {
      return request._post('/shop/plus.release.Tag/delete', data, errorback);
    },
    /*需求发布列表*/
    demandProject(data, errorback) {
        return request._post('/shop/plus.release.DemandProject/index', data, errorback);
    },
    demandProjectSubmit(data, errorback) {
        return request._post('/shop/plus.release.demandProject/submit', data, errorback);
    },
    /*删除*/
    demandDel(data, errorback) {
        return request._post('/shop/plus.release.DemandProject/delete', data, errorback);
    },
    /*详情*/
    demandEdit(data, errorback) {
        return request._post('/shop/plus.release.DemandProject/edit', data, errorback);
    },
    /*供应发布列表*/
    supplyProject(data, errorback) {
        return request._post('/shop/plus.release.supplyProject/index', data, errorback);
    },
    /*审核*/
    supplyProjectSubmit(data, errorback) {
        return request._post('/shop/plus.release.supplyProject/submit', data, errorback);
    },
    /*删除*/
    supplyDel(data, errorback) {
        return request._post('/shop/plus.release.supplyProject/delete', data, errorback);
    },
    /*详情*/
    supplyEdit(data, errorback) {
        return request._post('/shop/plus.release.supplyProject/edit', data, errorback);
    },
    /*订单列表*/
    releaseOrder(data, errorback) {
        return request._post('/shop/plus.release.order/index', data, errorback);
    },
    onCash(data, errorback) {
        return request._post('/shop/plus.release.order/onCash', data, errorback);
    },
    onFinish(data, errorback) {
        return request._post('/shop/plus.release.order/onFinish', data, errorback);
    },
    onCancel(data, errorback) {
        return request._post('/shop/plus.release.order/onCancel', data, errorback);
    },
    /*提现申请*/
    cash(data, errorback) {
        return request._post('/shop/plus.release.cash/index', data, errorback);
    },
    /*提现审核*/
    cashSubmit(data, errorback) {
        return request._post('/shop/plus.release.cash/submit', data, errorback);
    },
    /*微信打款*/
    WxPay(data, errorback) {
        return request._post('/shop/plus.release.cash/wechat_pay', data, errorback);
    },
    /*付呗分账打款*/
    FbPay(data, errorback) {
        return request._post('/shop/plus.release.cash/fb_pay', data, errorback);
    },
    /*确认打款*/
    money(data, errorback) {
        return request._post('/shop/plus.release.cash/money', data, errorback);
    },
    /*设置*/
    releaseSet(data, errorback) {
        return request._post('/shop/plus.release.setting/index', data, errorback);
    },
    /*佣金设置*/
    settlement(data, errorback) {
        return request._post('/shop/plus.release.setting/settlement', data, errorback);
    },
}
export default PlusApi;
shop_vue/src/components/setlink/part/Menu.vue
@@ -132,6 +132,16 @@
                        url: 'pages/plus/vip/index',
                        name: 'VIP专区',
                        type: '菜单',
                    },
                    {
                        url: 'pages3/release/demandindex/index',
                        name: '需求方',
                        type: '菜单',
                    },
                    {
                        url: 'pages3/release/supplyindex/index',
                        name: '供应方',
                        type: '菜单',
                    }
                    ],
                /*选中的值*/
shop_vue/src/views/plus/release/cash/Cash.vue
New file
@@ -0,0 +1,333 @@
<template>
  <!--
          作者:yj
      -->
  <div class="user">
    <div class="common-seach-wrap">
      <el-form size="small" :inline="true" :model="formInline" class="demo-form-inline">
        <el-form-item label="审核状态">
          <el-select v-model="formInline.apply_status" placeholder="请选择状态">
            <el-option label="全部" value="-1"></el-option>
            <el-option label="待审核" value="10"></el-option>
            <el-option label="审核通过" value="20"></el-option>
            <el-option label="已打款" value="40"></el-option>
            <el-option label="驳回" value="30"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="提现方式">
          <el-select v-model="formInline.pay_type" placeholder="请选择提现方式">
            <el-option label="全部" value="-1"></el-option>
            <el-option label="微信" value="10"></el-option>
            <el-option label="支付宝" value="20"></el-option>
            <el-option label="银行卡" value="30"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="用户id">
          <el-input v-model="formInline.user_id" placeholder="请输入用户ID"></el-input>
        </el-form-item>
        <el-form-item label="">
          <el-input v-model="formInline.search" placeholder="请输入昵称/姓名/手机号"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onSubmit">查询</el-button>
        </el-form-item>
        <!-- <el-form-item>
          <el-button size="small" type="success" @click="onExport" v-auth="'/plus/agent/cash/export'">导出</el-button>
        </el-form-item> -->
      </el-form>
    </div>
    <!--内容-->
    <div class="product-content">
      <div class="table-wrap">
        <el-table :data="tableData" border style="width: 100%" v-loading="loading">
          <el-table-column prop="user_id" label="用户ID" width="60"></el-table-column>
          <el-table-column prop="nickName" label="微信头像" width="70">
            <template slot-scope="scope">
              <img class="radius" v-img-url="scope.row.avatarUrl" width="30" height="30" />
            </template>
          </el-table-column>
          <el-table-column prop="nickName" label="微信昵称" width="100"></el-table-column>
          <el-table-column prop="real_name" label="姓名"></el-table-column>
          <el-table-column prop="mobile" label="手机号">
            <template slot-scope="scope">
              <p class="text-ellipsis" :title="scope.row.mobile">{{ scope.row.mobile }}</p>
            </template>
          </el-table-column>
          <el-table-column prop="money" label="提现金额">
            <template slot-scope="scope">
              <span class="orange">{{ scope.row.money }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="fee_money" label="手续费">
            <template slot-scope="scope">
              <span class="black">{{ scope.row.fee_money || 0 }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="real_money" label="实际到账">
            <template slot-scope="scope">
              <span class="green">{{ scope.row.real_money || scope.row.money }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="pay_type.text" label="提现方式"></el-table-column>
          <el-table-column prop="pay_type" label="提现信息    ">
            <template slot-scope="scope">
              <div v-if="scope.row.pay_type.value == 20">
                <p>
                  <span>{{ scope.row.alipay_name }}</span>
                </p>
                <p>
                  <span>{{ scope.row.alipay_account }}</span>
                </p>
              </div>
              <div v-else-if="scope.row.pay_type.value == 30">
                <p>
                  <span>{{ scope.row.bank_name }}</span>
                </p>
                <p>
                  <span>{{ scope.row.bank_account }}</span>
                </p>
                <p>
                  <span>{{ scope.row.bank_card }}</span>
                </p>
              </div>
              <div v-else>
                <p><span>--</span></p>
              </div>
            </template>
          </el-table-column>
          <el-table-column prop="apply_status.text" label="审核状态"></el-table-column>
          <el-table-column prop="create_time" label="申请时间" width="135"></el-table-column>
          <el-table-column prop="audit_time" label="审核时间" width="135"></el-table-column>
          <el-table-column fixed="right" label="操作" width="180">
            <template slot-scope="scope">
              <div v-if="scope.row.apply_status.value == 10 || scope.row.apply_status.value == 20">
                <el-button @click="editClick(scope.row)" type="text" size="small" v-auth="'/plus/release/cash/submit'">审核</el-button>
                <template v-if="scope.row.apply_status.value == 20">
                  <el-button @click="makeMoney(scope.row)" type="text" size="small" v-auth="'/plus/release/cash/money'">确认打款</el-button>
                </template>
                <template v-if="scope.row.apply_status.value == 20 && scope.row.pay_type.value == 10">
                  <el-button @click="WxPay(scope.row.id)" type="text" size="small" v-auth="'/plus/release/cash/money'">微信付款</el-button>
                </template>
              </div>
              <div v-if="scope.row.apply_status.value == 30">
                <el-button @click="editClick(scope.row)" type="text" size="small">查看详情</el-button>
               </div>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <!--分页-->
      <div class="pagination">
        <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" background
          :current-page="curPage" :page-size="pageSize" layout="total, prev, pager, next, jumper"
          :total="totalDataNumber"></el-pagination>
      </div>
    </div>
    <Edit v-if="open_edit" :open_edit="open_edit" :form="userModel" @closeDialog="closeDialogFunc($event, 'edit')">
    </Edit>
  </div>
</template>
<script>
  import PlusApi from '@/api/plus/release.js';
  import Edit from './dialog/Edit.vue';
  import qs from 'qs';
  export default {
    components: {
      /*编辑组件*/
      Edit
    },
    data() {
      return {
        /*是否加载完成*/
        loading: true,
        /*列表数据*/
        tableData: [],
        /*一页多少条*/
        pageSize: 20,
        /*一共多少条数据*/
        totalDataNumber: 0,
        /*当前是第几页*/
        curPage: 1,
        formInline: {
          apply_status: '-1',
          pay_type: '-1',
          search: '',
          /*用户ID*/
          user_id: ''
        },
        /*是否打开编辑弹窗*/
        open_edit: false,
        /*当前编辑的对象*/
        userModel: {}
      };
    },
    props: {},
    watch: {
    $route(to, from) {
      if (to.query.user_id != null) {
        this.formInline.user_id = to.query.user_id;
      }else{
        this.formInline.user_id ='';
      }
      this.curPage = 1;
      this.getData();
    }
  },
  created() {
    if (this.$route.query.user_id != null) {
      this.formInline.user_id = this.$route.query.user_id;
    }
    /*获取列表*/
    this.getData();
  },
  methods: {
    /*获取数据*/
    getData() {
      let self = this;
      let Params = self.formInline;
      Params.page = self.curPage;
      Params.list_rows = self.pageSize;
      PlusApi.cash(Params, true)
        .then(data => {
          self.loading = false;
          self.tableData = data.data.list.data;
          self.totalDataNumber = data.data.list.total;
        })
        .catch(error => {});
    },
    /*搜索*/
    onSubmit() {
      let self = this;
      self.loading = true;
      let Params = self.formInline;
      PlusApi.cash(Params, true)
        .then(data => {
          self.loading = false;
          self.tableData = data.data.list.data;
          self.totalDataNumber = data.data.list.total;
        })
        .catch(error => {
          self.loading = false;
        });
    },
      onExport: function() {
        let baseUrl = window.location.protocol + '//' + window.location.host;
        window.location.href = baseUrl + '/index.php/shop/plus.release.cash/export?' + qs.stringify(this.formInline);
      },
    /*每页多少条*/
    handleSizeChange(val) {
      this.curPage = 1;
      this.pageSize = val;
      this.getData();
    },
    /*选择第几页*/
    handleCurrentChange(val) {
      let self = this;
      self.curPage = val;
      self.getData();
    },
    /*打开弹出层编辑*/
    editClick(item) {
      this.userModel = item;
      this.open_edit = true;
    },
    /*关闭弹窗*/
    closeDialogFunc(e, f) {
      if (f == 'add') {
        this.open_add = e.openDialog;
        if (e.type == 'success') {
          this.getData();
        }
      }
      if (f == 'edit') {
        this.open_edit = e.openDialog;
        if (e.type == 'success') {
          this.getData();
        }
      }
    },
    /*确认打款*/
    makeMoney(e) {
      let self = this;
      self
        .$confirm('确认要打款吗?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
        .then(() => {
          self.loading = true;
            PlusApi.money({
              id: e.id
            },
            true
          )
            .then(data => {
              self.loading = false;
              if (data.code == 1) {
                self.$message({
                  message: '恭喜你,操作成功',
                  type: 'success'
                });
                this.getData();
              } else {
                self.loading = false;
              }
            })
            .catch(error => {
              self.loading = false;
            });
        })
        .catch(() => {});
    },
    /*微信打款*/
    WxPay(e) {
      let self = this;
      self
        .$confirm('该操作 将使用分账功能,确定打款吗?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
        .then(() => {
          self.loading = true;
            PlusApi.FbPay({
              id: e
            },
            true
          )
            .then(data => {
              self.loading = false;
              if (data.code == 1) {
                self.$message({
                  message: '恭喜你,操作成功',
                  type: 'success'
                });
                this.getData();
              } else {
                self.loading = false;
              }
            })
            .catch(error => {
              self.loading = false;
            });
        })
        .catch(() => {});
    }
  }
};
</script>
<style></style>
shop_vue/src/views/plus/release/cash/dialog/Edit.vue
New file
@@ -0,0 +1,94 @@
<template>
  <!--
          作者:luoyiming
          时间:2020-06-01
          描述:插件中心-分销-提现申请-弹窗
      -->
  <div v-if="status != 30">
    <el-dialog title="提现审核" :visible.sync="dialogVisible" @close="dialogFormVisible" :close-on-click-modal="false" :close-on-press-escape="false">
      <el-form :model="form">
        <el-form-item label="审核状态" :label-width="formLabelWidth">
          <div>
            <el-radio v-model="form.apply_status" label="20">审核通过</el-radio>
            <el-radio v-model="form.apply_status" label="30">驳回</el-radio>
          </div>
        </el-form-item>
        <div v-if="form.apply_status == 30">
          <el-form-item label="驳回原因" :label-width="formLabelWidth"><el-input v-model="form.reject_reason" autocomplete="off"></el-input></el-form-item>
        </div>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible">取 消</el-button>
        <el-button type="primary" @click="editApplyStatus">确 定</el-button>
      </div>
    </el-dialog>
  </div>
  <div v-else>
    <el-dialog title="驳回原因" :visible.sync="dialogVisible" @close="dialogFormVisible" :close-on-click-modal="false" :close-on-press-escape="false">
      <p>{{ reject_reason }}</p>
      <!-- <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible">取 消</el-button>
        <el-button type="primary" @click="dialogFormVisible">确 定</el-button>
      </div> -->
    </el-dialog>
  </div>
</template>
<script>
import PlusApi from '@/api/plus/release.js';
export default {
  data() {
    return {
      status: '',
      reject_reason: '',
      /*左边长度*/
      formLabelWidth: '120px',
      /*是否显示*/
      dialogVisible: false
    };
  },
  props: ['open_edit', 'form'],
  created() {
    this.dialogVisible = this.open_edit;
    this.status = this.form.apply_status.value;
    if (this.status == 30) {
      this.reject_reason = this.form.reject_reason;
    }
  },
  methods: {
    /*修改*/
    editApplyStatus() {
      let self = this;
      let params = this.form;
      PlusApi.cashSubmit(params, true)
        .then(data => {
          self.$message({
            message: '恭喜你,修改成功',
            type: 'success'
          });
          self.dialogFormVisible(true);
        })
        .catch(error => {});
    },
    /*关闭弹窗*/
    dialogFormVisible(e) {
      if (e) {
        this.$emit('closeDialog', {
          type: 'success',
          openDialog: false
        });
      } else {
        this.$emit('closeDialog', {
          type: 'error',
          openDialog: false
        });
      }
    }
  }
};
</script>
<style></style>
shop_vue/src/views/plus/release/demand/apply/Apply.vue
New file
@@ -0,0 +1,169 @@
<template>
  <!--
          作者:yj
          时间:2025-11-9
          描述:申请
      -->
  <div class="user">
    <div class="common-seach-wrap">
      <el-form size="small" :inline="true" :model="formInline" class="demo-form-inline">
        <el-form-item label=""><el-input v-model="formInline.nick_name" placeholder="请输入昵称/姓名/手机号"></el-input></el-form-item>
        <el-form-item><el-button type="primary" @click="onSubmit">查询</el-button></el-form-item>
      </el-form>
    </div>
    <!--内容-->
    <div class="product-content">
      <div class="table-wrap">
        <el-table :data="tableData" size="small" border style="width: 100%" v-loading="loading">
          <el-table-column prop="user_id" label="用户ID" width="60"></el-table-column>
          <el-table-column prop="nickName" label="微信头像" width="70">
            <template slot-scope="scope">
              <img class="radius" v-img-url="scope.row.avatarUrl" width="30" height="30" />
            </template>
          </el-table-column>
          <el-table-column prop="nickName" label="    微信昵称" width="250"></el-table-column>
          <el-table-column prop="real_name" label="姓名" width="100"></el-table-column>
          <el-table-column prop="mobile" label="手机号">
            <template slot-scope="scope">
              <p class="text-ellipsis">{{ scope.row.mobile }}</p>
            </template>
          </el-table-column>
          <!-- <el-table-column prop="detail" label="地址"></el-table-column> -->
          <el-table-column prop="apply_status" label="审核状态" width="100">
            <template slot-scope="scope">
              <span :class="{
                red: scope.row.apply_status.value == 10,
                green: scope.row.apply_status.value == 20,
                gray: scope.row.apply_status.value == 30 }">
                {{ scope.row.apply_status.text }}
              </span>
            </template>
          </el-table-column>
          <el-table-column prop="apply_time" label="申请时间" width="135"></el-table-column>
          <el-table-column fixed="right" label="操作" width="50">
            <template slot-scope="scope">
              <div>
                <el-button v-if="scope.row.apply_status.value == 10" @click="editClick(scope.row)" type="text" size="small">
                  审核
                </el-button>
                <el-button v-if="scope.row.apply_status.value == 30" @click="editClick(scope.row)" type="text" size="small">查看</el-button>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <!--分页-->
      <div class="pagination">
        <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          background
          :current-page="curPage"
          :page-size="pageSize"
          layout="total, prev, pager, next, jumper"
          :total="totalDataNumber"
        ></el-pagination>
      </div>
    </div>
    <Edit v-if="open_edit" :open_edit="open_edit" :form="userModel" @closeDialog="closeDialogFunc($event, 'edit')"></Edit>
  </div>
</template>
<script>
import PlusApi from '@/api/plus/release.js';
import Edit from './dialog/Edit.vue';
export default {
  components: {
    /*编辑组件*/
    Edit
  },
  data() {
    return {
      /*是否加载完成*/
      loading: true,
      /*列表数据*/
      tableData: [],
      /*一页多少条*/
      pageSize: 20,
      /*一共多少条数据*/
      totalDataNumber: 0,
      /*当前是第几页*/
      curPage: 1,
      formInline: {
        nick_name: ''
      },
      /*是否打开编辑弹窗*/
      open_edit: false,
      /*当前编辑的对象*/
      userModel: {}
    };
  },
  created() {
    /*获取列表*/
    this.getData();
  },
  methods: {
    /*选择第几页*/
    handleCurrentChange(val) {
      let self = this;
      self.curPage = val;
      self.loading = true;
      self.getData();
    },
    /*获取数据*/
    getData() {
      let self = this;
      let Params = {};
      Params.page = self.curPage;
      Params.list_rows = self.pageSize;
      Params.nick_name = this.formInline.nick_name;
      PlusApi.demandApplyList(Params, true)
        .then(data => {
          self.loading = false;
          self.tableData = data.data.apply_list.data;
          self.totalDataNumber = data.data.apply_list.total;
        })
        .catch(error => {});
    },
    //搜索
    onSubmit() {
      this.curPage = 1;
      this.getData();
    },
    /*每页多少条*/
    handleSizeChange(val) {
      this.curPage = 1;
      this.getData();
    },
    /*打开弹出层编辑*/
    editClick(item) {
      this.userModel = item;
      this.open_edit = true;
    },
    /*关闭弹窗*/
    closeDialogFunc(e, f) {
      if (f == 'add') {
        this.open_add = e.openDialog;
        if (e.type == 'success') {
          this.getData();
        }
      }
      if (f == 'edit') {
        this.open_edit = e.openDialog;
        if (e.type == 'success') {
          this.getData();
        }
      }
    }
  }
};
</script>
<style></style>
shop_vue/src/views/plus/release/demand/apply/dialog/Edit.vue
New file
@@ -0,0 +1,88 @@
<template>
  <!--
          作者:yj
          时间:2025-11-9
      -->
  <div v-if="status != 30">
    <el-dialog title="申请审核" :visible.sync="dialogVisible" @close="dialogFormVisible" :close-on-click-modal="false" :close-on-press-escape="false">
      <el-form :model="form">
        <el-form-item label="审核状态" :label-width="formLabelWidth">
          <div>
            <el-radio v-model="form.apply_status" label="20">审核通过</el-radio>
            <el-radio v-model="form.apply_status" label="30">驳回</el-radio>
          </div>
        </el-form-item>
        <div v-if="form.apply_status == 30">
          <el-form-item label="驳回原因" :label-width="formLabelWidth"><el-input v-model="form.reject_reason" autocomplete="off"></el-input></el-form-item>
        </div>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible">取 消</el-button>
        <el-button type="primary" @click="editApplyStatus">确 定</el-button>
      </div>
    </el-dialog>
  </div>
  <div v-else>
    <el-dialog title="驳回原因" :visible.sync="dialogVisible" @close="dialogFormVisible" :close-on-click-modal="false" :close-on-press-escape="false">
      <p>{{ reject_reason }}</p>
    </el-dialog>
  </div>
</template>
<script>
import PlusApi from '@/api/plus/release.js';
export default {
  data() {
    return {
      status: '',
      reject_reason: '',
      /*左边长度*/
      formLabelWidth: '120px',
      /*是否显示*/
      dialogVisible: false
    };
  },
  props: ['open_edit', 'form'],
  created() {
    this.dialogVisible = this.open_edit;
    this.status = this.form.apply_status.value;
    if (this.status == 30) {
      this.reject_reason = this.form.reject_reason;
    }
  },
  methods: {
    /*修改用户*/
    editApplyStatus() {
      let self = this;
      let params = this.form;
      PlusApi.editDemandApplyStatus(params, true)
        .then(data => {
          self.$message({
            message: '恭喜你,修改成功',
            type: 'success'
          });
          self.dialogFormVisible(true);
        })
        .catch(error => {});
    },
    /*关闭弹窗*/
    dialogFormVisible(e) {
      if (e) {
        this.$emit('closeDialog', {
          type: 'success',
          openDialog: false
        });
      } else {
        this.$emit('closeDialog', {
          type: 'error',
          openDialog: false
        });
      }
    }
  }
};
</script>
<style></style>
shop_vue/src/views/plus/release/demand/user/User.vue
New file
@@ -0,0 +1,205 @@
<template>
  <!--
          作者:yj
          时间:2025-11-9
      -->
  <div class="user">
    <div class="common-seach-wrap">
      <el-form size="small" :inline="true" :model="formInline" class="demo-form-inline">
        <el-form-item label=""><el-input v-model="formInline.nick_name" placeholder="请输入昵称/姓名/手机号"></el-input></el-form-item>
        <el-form-item><el-button type="primary" @click="onSubmit">查询</el-button></el-form-item>
      </el-form>
    </div>
    <!--内容-->
    <div class="product-content">
      <div class="table-wrap">
        <el-table size="small" :data="tableData" border style="width: 100%" v-loading="loading">
          <el-table-column prop="user_id" label="用户ID" width="70"></el-table-column>
          <el-table-column prop="nickName" label="微信头像" width="70">
            <template slot-scope="scope">
              <img class="radius" v-img-url="scope.row.avatarUrl" width="30" height="30" />
            </template>
          </el-table-column>
          <el-table-column prop="nickName" label="微信昵称" width="250"></el-table-column>
          <el-table-column prop="real_name" label="姓名" width="100"></el-table-column>
          <el-table-column prop="mobile" label="手机号"></el-table-column>
         <!-- <el-table-column prop="detail" label="地址"></el-table-column> -->
          <el-table-column prop="create_time" label="成为时间" width="140"></el-table-column>
          <el-table-column fixed="right" label="操作" width="160">
            <template slot-scope="scope">
              <div>
                <el-button @click="saleClick(scope.row)" type="text" size="small">需求订单</el-button>
                <el-button @click="EditClick(scope.row)" type="text" size="small">修改</el-button>
                <el-button @click="delClick(scope.row)" type="text" size="small">删除</el-button>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <!--分页-->
      <div class="pagination">
        <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          background
          :current-page="curPage"
          :page-size="pageSize"
          layout="total, prev, pager, next, jumper"
          :total="totalDataNumber"
        ></el-pagination>
      </div>
    </div>
    <!--编辑-->
    <Edit :open_edit="open_edit" :userModel="userModel" @close="closeEditFunc"></Edit>
  </div>
</template>
<script>
import { deepClone } from '@/utils/base.js'
import PlusApi from '@/api/plus/release.js';
import Edit from './dialog/Edit.vue';
export default {
  components: {
    Edit,
  },
  data() {
    return {
      /*是否加载完成*/
      loading: true,
      /*列表数据*/
      tableData: [],
      /*一页多少条*/
      pageSize: 20,
      /*一共多少条数据*/
      totalDataNumber: 0,
      /*当前是第几页*/
      curPage: 1,
      /*搜索对象*/
      formInline: {
        nick_name: ''
      },
      /*是否打开弹窗*/
      open_dialog: false,
      /*选中的用户*/
      userModel:{},
      /*是否打开修改*/
      open_edit:false,
    };
  },
  created() {
    /*获取列表*/
    this.getData();
  },
  methods: {
    /*选择第几页*/
    handleCurrentChange(val) {
      let self = this;
      self.curPage = val;
      self.loading = true;
      self.getData();
    },
    /*获取数据*/
    getData() {
      let self = this;
      let Params = {};
      Params.page = self.curPage;
      Params.list_rows = self.pageSize;
      if(self.formInline.nick_name!=''){
        Params.nick_name=self.formInline.nick_name;
      }
      PlusApi.demandUserList(Params, true)
        .then(data => {
          self.loading = false;
          self.tableData = data.data.list.data;
          self.totalDataNumber = data.data.list.total;
        })
        .catch(error => {
          self.loading = false;
        });
    },
    //搜索
    onSubmit() {
      this.curPage = 1;
      this.getData();
    },
    /*每页多少条*/
    handleSizeChange(val) {
      this.curPage = 1;
      this.pageSize = val;
      this.getData();
    },
    /*订单*/
    saleClick(item) {
      this.$router.push({
        path:'/plus/release/index',
        query:{
          type:'demandorder',
          repair_user_id:item.user_id
        }
      })
    },
    /*删除*/
    delClick(row) {
      let self = this;
      self
        .$confirm('此操作将永久删除该记录, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
        .then(() => {
          self.loading = true;
          PlusApi.deleteDemandUser(
            {
              user_id: row.user_id
            },
            true
          )
            .then(data => {
              self.loading = false;
              self.$message({
                message: data.msg,
                type: 'success'
              });
              self.getData();
            })
            .catch(error => {
              self.loading = false;
            });
        })
        .catch(() => {
          self.loading = false;
        });
    },
     /*打开编辑用户弹窗*/
    EditClick(e){
      this.userModel=deepClone(e);
      this.open_edit=true;
    },
    /*关闭编辑用户弹窗*/
    closeEditFunc(e){
      this.open_edit=false;
      if(e.type=='success'){
        this.getData();
      }
    }
  }
};
</script>
<style scoped="scoped">
  .el-button{margin-left: 0; margin-right: 10px;}
</style>
shop_vue/src/views/plus/release/demand/user/dialog/Edit.vue
New file
@@ -0,0 +1,91 @@
<template>
  <!--
          作者:yj
          时间:2025-11-9
      -->
  <el-dialog title="编辑" :visible.sync="dialogVisible" @close="cancelFunc" :close-on-click-modal="false" :close-on-press-escape="false" width="60%">
    <el-form :model="formData">
      <el-form-item label="微信昵称" :label-width="formLabelWidth">
        <el-input type="text" v-model="formData.nickName" autocomplete="off" :disabled="true"></el-input>
      </el-form-item>
      <el-form-item label="微信头像" :label-width="formLabelWidth">
        <img v-img-url="formData.avatarUrl" width="50" height="50" />
      </el-form-item>
      <el-form-item label="姓名" :label-width="formLabelWidth">
        <el-input type="text" v-model="formData.real_name" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="手机号" :label-width="formLabelWidth">
        <el-input type="text" v-model="formData.mobile" autocomplete="off"></el-input>
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="cancelFunc">取 消</el-button>
      <el-button type="primary" @click="confirmFunc">确 定</el-button>
    </div>
  </el-dialog>
</template>
<script>
import PlusApi from '@/api/plus/release.js';
import UserApi from '@/api/user.js';
export default {
  data() {
    return {
      /*左边长度*/
      formLabelWidth: '100px',
      /*是否显示*/
      dialogVisible: false,
      /*表单数据模型*/
      formData: {},
    };
  },
  props: {
    open_edit: Boolean,
    userModel: Object
  },
  watch: {
    open_edit: function(n, o) {
      if (n != o) {
        this.dialogVisible = this.open_edit;
        if (n) {
          this.formData = this.userModel;
        }
      }
    }
  },
  created() {
  },
  methods: {
    /*修改用户*/
    confirmFunc() {
      let self = this;
      let params ={};
      params.user_id= this.formData.user_id;
      params.real_name=this.formData.real_name;
      params.mobile=this.formData.mobile;
      PlusApi.demandUserEdit(params, true)
        .then(data => {
          self.$message({
            message: '恭喜你,修改成功',
            type: 'success'
          });
          self.cancelFunc(true);
        })
        .catch(error => {});
    },
    /*关闭弹窗*/
    cancelFunc(e) {
      let type='cancel';
      if(e){
        type='success';
      }
      this.$emit('close', {
        type:type
      });
    }
  }
};
</script>
<style></style>
shop_vue/src/views/plus/release/demandproject/Edit.vue
New file
@@ -0,0 +1,79 @@
<template>
  <!--
      作者:yj
  -->
  <el-dialog title="详情" :visible.sync="dialogVisible" @close='dialogFormVisible' :close-on-click-modal="false"
    :close-on-press-escape="false" width="600px">
    <el-form size="small" :model="form" ref="form">
      <el-form-item label="标题:" :label-width="formLabelWidth">
        {{form.name}}
      </el-form-item>
      <el-form-item label="分类:" :label-width="formLabelWidth">
        {{form.category.name}}
      </el-form-item>
      <el-form-item label="预算:" :label-width="formLabelWidth">
        ¥{{form.price}}
      </el-form-item>
      <el-form-item label="详细需求:" :label-width="formLabelWidth" >
        {{form.content}}
      </el-form-item>
      <el-form-item label="图片:" :label-width="formLabelWidth">
         <div v-if="form.image_list" v-for="(item,index) in form.image_list">
          <a target="_blank" :href="item.file_path"><img style="max-width: 50px; height: 50px;" v-img-url="item.file_path" />
          </a>
        </div>
      </el-form-item>
      <el-form-item label="期望完成时间:" :label-width="formLabelWidth" >
        {{form.finish_time}}
      </el-form-item>
      <el-form-item label="期望地点:" :label-width="formLabelWidth">
        {{form.detail}}
      </el-form-item>
      <el-form-item label="联系方式:" :label-width="formLabelWidth">
        <span v-if="form.show_phone == 0">不公开</span>
        <span v-if="form.show_phone == 1">公开</span>
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="dialogFormVisible">返回</el-button>
    </div>
  </el-dialog>
</template>
<script>
  import PlusApi from '@/api/plus.js';
  export default {
    data() {
      return {
        /*左边长度*/
        formLabelWidth: '120px',
        /*是否显示*/
        dialogVisible: false,
      };
    },
    props: ['open_edit', 'form'],
    created() {
      this.dialogVisible = this.open_edit;
    },
    methods: {
      /*关闭弹窗*/
      dialogFormVisible(e) {
        if (e) {
          this.$emit('closeDialog', {
            type: 'success',
            openDialog: false
          })
        } else {
          this.$emit('closeDialog', {
            type: 'error',
            openDialog: false
          })
        }
      }
    }
  };
</script>
<style></style>
shop_vue/src/views/plus/release/demandproject/dialog/Edit.vue
New file
@@ -0,0 +1,92 @@
<template>
  <!--
          作者:yj
      -->
  <div v-if="status != 2">
    <el-dialog title="审核" :visible.sync="dialogVisible" @close="dialogFormVisible" :close-on-click-modal="false" :close-on-press-escape="false">
      <el-form :model="form">
        <el-form-item label="审核状态" :label-width="formLabelWidth">
          <div>
            <el-radio v-model="form.status" label="1">审核通过</el-radio>
            <el-radio v-model="form.status" label="2">驳回</el-radio>
          </div>
        </el-form-item>
        <div v-if="form.status == 2">
          <el-form-item label="驳回原因" :label-width="formLabelWidth"><el-input v-model="form.reject_reason" autocomplete="off"></el-input></el-form-item>
        </div>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible">取 消</el-button>
        <el-button type="primary" @click="editApplyStatus">确 定</el-button>
      </div>
    </el-dialog>
  </div>
  <div v-else>
    <el-dialog title="驳回原因" :visible.sync="dialogVisible" @close="dialogFormVisible" :close-on-click-modal="false" :close-on-press-escape="false">
      <p>{{ reject_reason }}</p>
      <!-- <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible">取 消</el-button>
        <el-button type="primary" @click="dialogFormVisible">确 定</el-button>
      </div> -->
    </el-dialog>
  </div>
</template>
<script>
import PlusApi from '@/api/plus/release.js';
export default {
  data() {
    return {
      status: '',
      reject_reason: '',
      /*左边长度*/
      formLabelWidth: '120px',
      /*是否显示*/
      dialogVisible: false
    };
  },
  props: ['open_edit', 'form'],
  created() {
    this.dialogVisible = this.open_edit;
    this.status = this.form.status.value;
    if (this.status == 30) {
      this.reject_reason = this.form.reject_reason;
    }
  },
  methods: {
    /*修改*/
    editApplyStatus() {
      let self = this;
      let params = this.form;
      PlusApi.demandProjectSubmit(params, true)
        .then(data => {
          self.$message({
            message: '恭喜你,修改成功',
            type: 'success'
          });
          self.dialogFormVisible(true);
        })
        .catch(error => {});
    },
    /*关闭弹窗*/
    dialogFormVisible(e) {
      if (e) {
        this.$emit('closeDialog', {
          type: 'success',
          openDialog: false
        });
      } else {
        this.$emit('closeDialog', {
          type: 'error',
          openDialog: false
        });
      }
    }
  }
};
</script>
<style></style>
shop_vue/src/views/plus/release/demandproject/index.vue
New file
@@ -0,0 +1,214 @@
<template>
  <!--
          作者:yj
      -->
  <div class="user">
    <!--搜索表单-->
    <div class="common-seach-wrap">
      <el-form size="small" :inline="true" :model="searchForm" class="demo-form-inline">
        <!-- <el-form-item label="类目">
          <el-select size="small" v-model="searchForm.category_id" placeholder="所有分类">
            <el-option label="全部" value="0"></el-option>
            <el-option v-for="(item, index) in categoryList" :key="index" :label="item.name" :value="item.category_id">
            </el-option>
          </el-select>
        </el-form-item> -->
        <el-form-item label="标题">
          <el-input size="small" v-model="searchForm.name" placeholder="请输入标题"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button size="small" type="primary" icon="el-icon-search" @click="onSubmit">查询</el-button>
        </el-form-item>
      </el-form>
    </div>
    <!--内容-->
    <div class="product-content">
      <div class="table-wrap">
        <el-table size="small" :data="tableData" border style="width: 100%" v-loading="loading">
          <el-table-column prop="project_id" label="ID" width="100"></el-table-column>
          <el-table-column prop="name" label="标题"></el-table-column>
          <el-table-column prop="category.name" label="分类" width="200"></el-table-column>
          <el-table-column prop="price" label="预算" width="200"></el-table-column>
          <el-table-column prop="status" label="状态"  width="200">
            <template slot-scope="scope">
              <span v-if="scope.row.status == 0">未审核</span>
              <span v-if="scope.row.status == 1" class="green">已通过</span>
              <span v-if="scope.row.status == 2" class="green">已驳回</span>
            </template>
          </el-table-column>
          <el-table-column fixed="right" label="操作" width="150">
            <template slot-scope="scope">
              <el-button v-if="scope.row.status == 0" @click="shClick(scope.row)" type="text" size="small">审核</el-button>
              <el-button @click="editClick(scope.row)" type="text" size="small" >详情</el-button>
              <el-button @click="deleteClick(scope.row)" type="text" size="small">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <!--分页-->
      <div class="pagination">
        <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" background
          :current-page="curPage" :page-size="pageSize" layout="total, prev, pager, next, jumper"
          :total="totalDataNumber"></el-pagination>
      </div>
    </div>
    <!--编辑-->
    <Edit v-if="open_edit" :open_edit="open_edit" :form="userModel" @closeDialog="closeDialogFunc($event, 'edit')"></Edit>
    <Editsh v-if="open_sh" :open_edit="open_sh" :form="userModel" @closeDialog="closeDialogFunc($event, 'editsh')"></Editsh>
  </div>
</template>
<script>
  import PlusApi from '@/api/plus/release.js';
  import Edit from './Edit.vue';
  import Editsh from './dialog/Edit.vue';
  import {deepClone} from '@/utils/base.js';
  export default {
    components: {
      /*编辑组件*/
      Edit,
      Editsh,
    },
    data() {
      return {
        /*是否加载完成*/
        loading: true,
        /*一页多少条*/
        pageSize: 10,
        /*一共多少条数据*/
        totalDataNumber: 0,
        /*当前是第几页*/
        curPage: 1,
        /*列表数据*/
        tableData: [],
        /*横向表单数据模型*/
        /*搜索参数*/
        searchForm: {
          name: '',
          category_id: ''
        },
        /*是否打开编辑弹窗*/
        open_edit: false,
        /*当前编辑的对象*/
        userModel: {},
        open_sh:false,
      };
    },
    created() {
      /*获取列表*/
      this.getTableList();
    },
    methods: {
      /*选择第几页*/
      handleCurrentChange(val) {
        let self = this;
        self.loading = true;
        self.curPage = val;
        self.getTableList();
      },
      /*每页多少条*/
      handleSizeChange(val) {
        this.pageSize = val;
        this.getTableList();
      },
      /*获取列表*/
      getTableList() {
        let self = this;
        let Params = self.searchForm;
        Params.page = self.curPage;
        Params.list_rows = self.pageSize;
        PlusApi.demandProject(Params, true)
          .then(data => {
            self.loading = false;
            self.tableData = data.data.list.data;
            self.totalDataNumber = data.data.list.total;
          })
          .catch(error => {
          });
      },
      /*搜索查询*/
      onSubmit() {
        this.curPage = 1;
        this.getTableList();
      },
      /*打开编辑*/
      editClick(item) {
        this.userModel = deepClone(item);
        this.open_edit = true;
      },
      /*打开弹出层审核*/
      shClick(item) {
        this.userModel = item;
        this.open_sh = true;
      },
      /*关闭弹窗*/
      closeDialogFunc(e, f) {
        if (f == 'add') {
          this.open_add = e.openDialog;
          if (e.type == 'success') {
            this.getTableList();
          }
        }
        if (f == 'edit') {
          this.open_edit = e.openDialog;
          if (e.type == 'success') {
            this.getTableList();
          }
        }
        if (f == 'editsh') {
          this.open_sh = e.openDialog;
          if (e.type == 'success') {
            this.getTableList();
          }
        }
      },
      /*删除*/
      deleteClick(row) {
        let self = this;
        self.$confirm('此操作将永久删除该记录, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          self.loading = true;
          PlusApi.demandDel({
              project_id: row.project_id
            }, true)
            .then(data => {
              self.loading = false;
              if (data.code == 1) {
                self.$message({
                  message: data.msg,
                  type: 'success'
                });
                self.getTableList();
              } else {
                self.$message.error('错了哦,这是一条错误消息');
              }
            })
            .catch(error => {
              self.loading = false;
            });
        }).catch(() => {
        });
      }
    }
  };
</script>
<style></style>
shop_vue/src/views/plus/release/index.vue
New file
@@ -0,0 +1,185 @@
<template>
  <!--
          作者:yj
      -->
  <div>
    <DemandApply v-if="activeName == 'demandapply'"></DemandApply>
    <DemandUser v-if="activeName == 'demanduser'"></DemandUser>
    <SupplyApply v-if="activeName == 'supplyapply'"></SupplyApply>
    <SupplyUser v-if="activeName == 'supplyuser'"></SupplyUser>
    <DemandProject v-if="activeName == 'demandproject'"></DemandProject>
    <SupplyProject v-if="activeName == 'supplyproject'"></SupplyProject>
    <Order v-if="activeName == 'order'"></Order>
    <Category v-if="activeName == 'category'"></Category>
    <Tag v-if="activeName == 'tag'"></Tag>
    <Cash v-if="activeName == 'cash'"></Cash>
    <Setting v-if="activeName == 'setting'"></Setting>
  </div>
</template>
<script>
import bus from '@/utils/eventBus.js';
import PlusApi from '@/api/plus.js';
import DemandApply from './demand/apply/Apply';
import DemandUser from './demand/user/User';
import SupplyApply from './supply/apply/Apply';
import SupplyUser from './supply/user/User';
import DemandProject from './demandproject/index';
import SupplyProject from './supplyproject/index';
import Order from './order/Order';
import Category from './releasecategory/index';
import Tag from './tag/index';
import Cash from './cash/Cash';
import Setting from './setting/Setting';
export default {
  components: {
    DemandApply,
    DemandUser,
    SupplyApply,
    SupplyUser,
    DemandProject,
    SupplyProject,
    Order,
    Category,
    Tag,
    Cash,
    Setting,
  },
  data() {
    return {
      formInline: {
        nick_name: ''
      },
      /*参数*/
      param: {},
      /*当前选中*/
      activeName: 'demandapply',
      /*切换数组*/
      sourceList: [
        {
          key: 'demandapply',
          value: '需求方申请',
          path:'/plus/release/demand/apply/index'
        },
        {
          key: 'demanduser',
          value: '需求方用户',
          path:'/plus/release/demand/user/index'
        },{
          key: 'supplyapply',
          value: '供应方申请',
          path:'/plus/release/supply/apply/index'
        },
        {
          key: 'supplyuser',
          value: '供应方用户',
          path:'/plus/release/supply/user/index'
        },
        {
          key: 'demandproject',
          value: '需求发布',
          path:'/plus/release/demandproject/index'
        },
        {
          key: 'supplyproject',
          value: '供应发布',
          path:'/plus/release/supplyproject/index'
        },
        {
          key: 'order',
          value: '用户订单',
          path:'/plus/release/order/Order'
        },
        {
          key: 'category',
          value: '分类列表',
          path:'/plus/release/releasecategory/index'
        },
        {
          key: 'tag',
          value: '标签列表',
          path:'/plus/release/tag/index'
        },
        {
          key: 'cash',
          value: '提现列表',
          path:'/plus/release/cash/Cash'
        },
        {
          key: 'setting',
          value: '发布设置',
          path:'/plus/release/setting/Setting'
        }
      ],
      /*权限筛选后的数据*/
      tabList:[],
      /*判断third是否有参数*/
      is_third_param: false
    };
  },
  watch:{
    //监听路由
    $route(to, from) {
      this.init();
    }
  },
  created() {
    this.init();
  },
  beforeDestroy() {
    //发送类别切换
    bus.$emit('tabData', { active: null, tab_type:'release',list: [] });
    bus.$off('activeValue');
  },
  methods: {
    /*初始化方法*/
    init(){
      this.tabList=this.authFilter();
      if(this.tabList.length>0){
        this.activeName=this.tabList[0].key;
      }
      if (this.$route.query.type != null) {
        this.activeName = this.$route.query.type;
      }
      /*监听传插件的值*/
      bus.$on('activeValue', res => {
        if (this.is_third_param) {
          this.param.user_id = '';
          this.is_third_param = false;
        }
        this.activeName = res;
      });
      //发送类别切换
      let params = {
        active: this.activeName,
        list: this.tabList,
        tab_type:'release'
      };
      bus.$emit('tabData', params);
    },
    /*权限过滤*/
    authFilter(){
      let list=[];
      for(let i=0;i<this.sourceList.length;i++){
        let item=this.sourceList[i];
        if(this.$filter.isAuth(item.path)){
          list.push(item);
        }
      }
      return list;
    }
  }
};
</script>
shop_vue/src/views/plus/release/order/Order.vue
New file
@@ -0,0 +1,281 @@
<template>
  <!--
          作者:yj
      -->
  <div class="user">
    <div class="common-seach-wrap">
      <el-form size="small" :inline="true" :model="formInline" class="demo-form-inline">
        <el-form-item label="创建时间">
          <div class="block">
            <span class="demonstration"></span>
            <el-date-picker size="small" v-model="formInline.create_time" type="daterange" value-format="yyyy-MM-dd"
              range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
          </div>
        </el-form-item>
        <el-form-item label="支付方式">
          <el-select v-model="formInline.pay_type" placeholder="选择支付方式">
            <el-option label="全部" value="0"></el-option>
            <el-option label="余额支付" value="10"></el-option>
            <el-option label="微信支付" value="20"></el-option>
            <el-option label="线下支付" value="40"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="支付状态">
          <el-select v-model="formInline.pay_status" placeholder="选择支付状态">
            <el-option label="全部" value="-1"></el-option>
            <el-option label="已支付" value="20"></el-option>
            <el-option label="未支付" value="10"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="订单状态">
          <el-select v-model="formInline.order_status" placeholder="选择订单状态">
            <el-option label="全部" value="-1"></el-option>
            <el-option label="进行中" value="10"></el-option>
            <el-option label="已完成" value="30"></el-option>
            <el-option label="已取消" value="20"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="需求用户id"><el-input v-model="formInline.demand_user_id" placeholder="请输入需求用户ID"></el-input></el-form-item>
        <el-form-item label="供应用户id"><el-input v-model="formInline.supply_user_id" placeholder="请输入供应用户ID"></el-input></el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onSubmit">查询</el-button>
        </el-form-item>
        <!-- <el-form-item>
          <el-button size="small" type="success" @click="onExport">导出</el-button>
        </el-form-item> -->
      </el-form>
    </div>
    <!--内容-->
    <div class="product-content">
      <div class="table-wrap">
        <!-- <el-tabs v-model="activeName" @tab-click="handleClick">
          <el-tab-pane label="全部订单" name="status0"></el-tab-pane>
          <el-tab-pane :label="'待确认支付'" name="status1">
            <span slot="label">待确认支付 <el-tag size="mini">{{order_count.status1}}</el-tag></span>
          </el-tab-pane>
          <el-tab-pane label="服务中" name="status6">
            <span slot="label">服务中 <el-tag size="mini">{{order_count.status6}}</el-tag></span>
          </el-tab-pane>
          <el-tab-pane label="待评价" name="status8">
             <span slot="label">待评价 <el-tag size="mini">{{order_count.status8}}</el-tag></span>
          </el-tab-pane>
          <el-tab-pane label="已完成" name="status9">
             <span slot="label">已完成 <el-tag size="mini">{{order_count.status9}}</el-tag></span>
          </el-tab-pane>
          <el-tab-pane label="已取消" name="status10">
             <span slot="label">已取消 <el-tag size="mini">{{order_count.status10}}</el-tag></span>
          </el-tab-pane>
        </el-tabs> -->
        <el-table :data="tableData" size="small" border style="width: 100%" v-loading="loading">
          <el-table-column prop="nickName" label="供应会员" width="200">
            <template slot-scope="scope">
              <img class="radius" v-img-url="scope.row.supplyuser.avatarUrl" width="30" height="30" />
              <div>ID:{{scope.row.supplyuser.user_id}}</div>
              <div>{{scope.row.supplyuser.nickName}}</div>
            </template>
          </el-table-column>
          <el-table-column prop="nickName" label="需求会员" width="200">
            <template slot-scope="scope">
              <img class="radius" v-img-url="scope.row.demanduser.avatarUrl" width="30" height="30" />
              <div>ID:{{scope.row.demanduser.user_id}}</div>
              <div>{{scope.row.demanduser.nickName}}</div>
            </template>
          </el-table-column>
          <el-table-column prop="project_name" label="标题"></el-table-column>
          <el-table-column prop="pay_price" label="支付金额" width="100"></el-table-column>
          <el-table-column prop="money" label="项目佣金" width="80"></el-table-column>
          <el-table-column prop="pay_type.text" label="支付方式" width="80">
            <template slot-scope="scope">
              <span class="gray9" v-if="scope.row.pay_status == 20">已支付<br />{{ scope.row.pay_type.text }}</span>
              <span v-else>未支付</span>
            </template>
          </el-table-column>
          <el-table-column prop="create_time" label="下单时间" width="140">
            <template slot-scope="scope">
              <div>{{ scope.row.create_time }}</div>
            </template>
          </el-table-column>
          <!-- <el-table-column prop="evaluate_content" label="需求方评价">
            <template slot-scope="scope" v-if="scope.row.is_settled == 2">
              <div v-if="scope.row.server_score > 0">{{scope.row.server_score}}星</div>
              <div>
                <span v-if="scope.row.score == 10">好评</span>
                <span v-else-if="scope.row.score == 20">中评</span>
                <span v-else-if="scope.row.score == 30">差评</span>
                <span v-else>好评</span>
              </div>
              <div>{{ scope.row.evaluate_content }}</div>
            </template>
          </el-table-column> -->
          <el-table-column prop="is_settled" label="订单状态" width="120">
            <template slot-scope="scope">
              <div class="red" v-if="scope.row.order_status == 20">{{scope.row.state_text}}</div>
              <div class="green" v-else>{{scope.row.state_text}}</div>
            </template>
          </el-table-column>
          <el-table-column fixed="right" label="操作" width="100">
            <template slot-scope="scope">
              <div>
                <el-button v-if="scope.row.order_status ==10 && scope.row.pay_status == 20" @click="editClick(scope.row)" type="text" size="small" v-auth="'/plus/release/order/edit'">查看详情</el-button>
                <el-button v-if="scope.row.order_status ==10 && scope.row.pay_status == 10" @click="editClick(scope.row)" type="text" size="small"
                     >确认支付</el-button>
                <!-- <el-button v-if="scope.row.order_status ==21 && scope.row.pay_status == 20" @click="editClick(scope.row)" type="text" size="small"
                     >审核取消订单</el-button> -->
              </div>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <!--分页-->
      <div class="pagination">
        <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          background
          :current-page="curPage"
          :page-size="pageSize"
          layout="total, prev, pager, next, jumper"
          :total="totalDataNumber"
        ></el-pagination>
      </div>
    </div>
    <!--编辑-->
    <Edit :open_edit="open_edit" :userModel="userModel" @close="closeEditFunc"></Edit>
  </div>
</template>
<script>
import PlusApi from '@/api/plus/release.js';
import Edit from './dialog/Edit.vue';
import qs from 'qs';
export default {
  components: {
    /*编辑组件*/
    Edit,
  },
  data() {
    return {
      /*是否加载完成*/
      loading: true,
      /*列表数据*/
      tableData: [],
      /*一页多少条*/
      pageSize: 20,
      /*一共多少条数据*/
      totalDataNumber: 0,
      /*当前是第几页*/
      curPage: 1,
      formInline: {
        /*ID*/
        demand_user_id: 0,
        supply_user_id: 0,
        pay_type:'0',
        pay_status:'-1',
        order_status:'-1',
        create_time: '',
      },
      /*是否打开编辑弹窗*/
      open_edit: false,
      /*当前编辑的对象*/
      userModel: {},
    };
  },
  props: {},
  watch: {
    $route(to, from) {
      if (to.query.supply_user_id != null) {
        this.formInline.supply_user_id = to.query.supply_user_id;
      }
      this.curPage = 1;
      this.getData();
    }
  },
  created() {
    if (this.$route.query.supply_user_id != null) {
      this.formInline.supply_user_id = this.$route.query.supply_user_id;
    }
    /*获取列表*/
    this.getData();
  },
  methods: {
    /*选择第几页*/
    handleCurrentChange(val) {
      let self = this;
      self.curPage = val;
      self.loading = true;
      self.getData();
    },
    /*获取数据*/
    getData() {
      let self = this;
      let Params = {
        demand_user_id: self.formInline.demand_user_id,
        supply_user_id: self.formInline.supply_user_id,
        pay_status:self.formInline.pay_status,
        pay_type:self.formInline.pay_type,
        order_status:self.formInline.order_status,
        create_time:self.formInline.create_time,
        page: self.curPage,
        list_rows: self.pageSize,
      };
      PlusApi.releaseOrder(Params, true)
        .then(data => {
          self.loading = false;
          self.tableData = data.data.list.data;
          self.totalDataNumber = data.data.list.total;
        })
        .catch(error => {
          self.loading = false;
        });
    },
    //搜索
    onSubmit() {
      let self = this;
      self.loading = true;
      self.curPage = 1;
      self.getData();
    },
    /*每页多少条*/
    handleSizeChange(val) {
      this.curPage = 1;
      this.pageSize = val;
      this.getData();
    },
    onExport: function() {
      let baseUrl = window.location.protocol + '//' + window.location.host;
      this.formInline.dataType = self.dataType;
      window.location.href = baseUrl + '/index.php/shop/plus.release.Order/export?' + qs.stringify(this.formInline);
    },
    /*打开弹出层编辑*/
    editClick(item) {
      this.userModel = item;
      this.open_edit = true;
    },
    /*关闭弹窗*/
    closeEditFunc(e){
      this.open_edit=false;
      if(e.type=='success'){
        this.getData();
      }
    }
  }
};
</script>
<style scoped="">
  .referee-name {
    width: 33.333333%;
  }
</style>
shop_vue/src/views/plus/release/order/dialog/Edit.vue
New file
@@ -0,0 +1,182 @@
<template>
  <!--
          作者:yj
      -->
  <el-dialog title="详情" :visible.sync="dialogVisible" @close="cancelFunc" :close-on-click-modal="false" :close-on-press-escape="false" width="60%">
    <el-form class="repair-form" :model="formData">
      <el-form-item label="供应用户:" :label-width="formLabelWidth">
        <div class="d-s-c" style="margin-bottom: 10px;">
           <span><img v-img-url="formData.supplyuser.avatarUrl" width="40" height="40" /></span>
           <span>{{formData.supplyuser.nickName}}</span>
        </div>
      </el-form-item>
      <el-form-item label="需求用户:" :label-width="formLabelWidth">
        <div class="d-s-c">
           <span><img v-img-url="formData.demanduser.avatarUrl" width="40" height="40" /></span>
           <span>{{formData.demanduser.nickName}}</span>
        </div>
      </el-form-item>
      <el-form-item label="标题:" :label-width="formLabelWidth">
        <span class="mr10">{{formData.project_name}}</span> <span class="ml20">支付金额:¥{{formData.pay_price}}</span> <span class="ml20">佣金:¥{{formData.money}}</span>
      </el-form-item>
      <!-- <el-form-item label="图片" :label-width="formLabelWidth">
        <div>
          <div v-for="(item, index) in formData.image" :key="index"><a target="_blank" :href="item.file_path"><img style="max-width: 50px; height: 50px;" v-img-url="item.file_path" /></a></div>
        </div>
      </el-form-item>
      <el-form-item label="备注" :label-width="formLabelWidth" prop="message">
        <el-input v-model="formData.message" autocomplete="off"></el-input>
      </el-form-item>-->
      <el-form-item label="服务星级" :label-width="formLabelWidth" v-if="formData.server_score">
        {{formData.server_score}}星
      </el-form-item>
      <el-form-item label="评分" :label-width="formLabelWidth" v-if="formData.score">
        <div v-if="formData.score == 10">好评</div>
        <div v-if="formData.score == 20">中评</div>
        <div v-if="formData.score == 30">差评</div>
      </el-form-item>
      <el-form-item label="评语" :label-width="formLabelWidth" v-if="formData.evaluate_content">
        {{formData.evaluate_content}}
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button type="warning" @click="onCancel(20)" v-if="formData.pay_status == 10 && formData.order_status == 10">取消订单</el-button>
      <el-button @click="cancelFunc">返 回</el-button>
      <el-button type="primary" @click="onCash" v-if="formData.order_status == 10 && formData.pay_status == 10">确定已付款</el-button>
      <el-button type="primary" @click="onFinish" v-if="formData.order_status == 10 && formData.pay_status == 20">确定已完成</el-button>
      <!-- <el-button type="warning" @click="onCancel(20)" v-if="formData.order_status == 21">确定取消订单</el-button>
      <el-button type="danger" @click="onCancel(10)" v-if="formData.order_status == 21">撤销申请</el-button> -->
    </div>
  </el-dialog>
</template>
<script>
import PlusApi from '@/api/plus/release.js';
import UserApi from '@/api/user.js';
export default {
  data() {
    return {
      /*左边长度*/
      formLabelWidth: '100px',
      /*是否显示*/
      dialogVisible: false,
      /*表单数据模型*/
      formData: {},
    };
  },
  props: {
    open_edit: Boolean,
    userModel: Object,
  },
  watch: {
    open_edit: function(n, o) {
      if (n != o) {
        this.dialogVisible = this.open_edit;
        if (n) {
          this.formData = this.userModel;
        }
      }
    }
  },
  created() {
    /*获取列表*/
   // this.getData();
  },
  methods: {
    /*获取数据*/
    // getData() {
    //   let self = this;
    //   PlusApi.toOrderEdit()
    //     .then(data => {
    //       self.loading = false;
    //       self.user = data.data.user;
    //     })
    //     .catch(error => {
    //       self.loading = false;
    //     });
    // },
    /*关闭弹窗*/
    cancelFunc(e) {
      let type='cancel';
      if(e){
        type='success';
      }
      this.$emit('close', {
        type:type
      });
    },
    /*线下支付*/
    onCash(row) {
      let self = this;
      let id = this.formData.id;
      self
        .$confirm('确认后不可恢复,确认已收到款了吗?', '提示', {
          type: 'warning'
        })
        .then(() => {
          PlusApi.onCash({
            id: id
          }).then(data => {
            self.$message({
              message: '操作成功',
              type: 'success'
            });
            self.cancelFunc(true);
          });
        });
    },
    onFinish(row) {
      let self = this;
      let id = this.formData.id;
      self
        .$confirm('确认后马上发放佣金,确认已完成了吗?', '提示', {
          type: 'warning'
        })
        .then(() => {
          PlusApi.onFinish({
            id: id
          }).then(data => {
            self.$message({
              message: '操作成功',
              type: 'success'
            });
            self.cancelFunc(true);
          });
        });
    },
    onCancel(order_status) {
      let self = this;
      let id = this.formData.id;
      self
        .$confirm('此操作不可恢复,确定吗?', '提示', {
          type: 'warning'
        })
        .then(() => {
          PlusApi.onCancel({
            id: id,
            order_status: order_status
          }).then(data => {
            self.$message({
              message: '操作成功',
              type: 'success'
            });
            self.cancelFunc(true);
          });
        });
    },
  }
};
</script>
<style scoped>
  .repair-img image{
    height: 100px;
  }
  .repair-form .el-form-item {
     margin-bottom: 0px;
  }
</style>
shop_vue/src/views/plus/release/releasecategory/Add.vue
New file
@@ -0,0 +1,103 @@
<template>
  <!--
        作者:wangxw
    -->
  <el-dialog title="添加分类" :visible.sync="dialogVisible" @close="dialogFormVisible" :close-on-click-modal="false"
    :close-on-press-escape="false">
    <el-form size="small" :model="form" :rules="formRules" ref="form">
      <el-form-item label="分类名称" prop="name" :label-width="formLabelWidth">
        <el-input v-model="form.name" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="分类排序" prop="sort" :label-width="formLabelWidth">
        <el-input v-model.number="form.sort" autocomplete="off"></el-input>
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="dialogFormVisible">取 消</el-button>
      <el-button type="primary" @click="addUser" :loading="loading">确 定</el-button>
    </div>
  </el-dialog>
</template>
<script>
  import PlusApi from '@/api/plus/release.js';
  export default {
    components: {
    },
    data() {
      return {
        form: {
          name: '',
          sort: 100,
        },
        formRules: {
          name: [{
            required: true,
            message: '请输入分类名称',
            trigger: 'blur'
          }],
          sort: [{
            required: true,
            message: '分类排序不能为空'
          }, {
            type: 'number',
            message: '分类排序必须为数字'
          }]
        },
        /*左边长度*/
        formLabelWidth: '120px',
        /*是否显示*/
        dialogVisible: false,
        loading: false,
      };
    },
    props: ['open_add', 'addform'],
    created() {
      this.dialogVisible = this.open_add;
    },
    methods: {
      /*添加*/
      addUser() {
        let self = this;
        let params = self.form;
        self.$refs.form.validate((valid) => {
          if (valid) {
            self.loading = true;
            PlusApi.catAdd(params).then(data => {
              self.loading = false;
              self.$message({
                message: '添加成功',
                type: 'success'
              });
              self.dialogFormVisible(true);
            }).catch(error => {
              self.loading = false;
            });
          }
        });
      },
      /*关闭弹窗*/
      dialogFormVisible(e) {
        if (e) {
          this.$emit('closeDialog', {
            type: 'success',
            openDialog: false
          })
        } else {
          this.$emit('closeDialog', {
            type: 'error',
            openDialog: false
          })
        }
      },
    }
  };
</script>
<style>
 .img {
    margin-top: 10px;
  }
</style>
shop_vue/src/views/plus/release/releasecategory/Edit.vue
New file
@@ -0,0 +1,106 @@
<template>
  <!--
        作者:wangxw
    -->
  <el-dialog title="修改分类" :visible.sync="dialogVisible" @close="dialogFormVisible" :close-on-click-modal="false"
    :close-on-press-escape="false">
    <el-form size="small" :model="form" :rules="formRules" ref="form">
      <el-form-item label="分类名称" prop="name" :label-width="formLabelWidth">
        <el-input v-model="form.name" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="分类排序" prop="sort" :label-width="formLabelWidth">
        <el-input v-model.number="form.sort" autocomplete="off"></el-input>
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="dialogFormVisible">取 消</el-button>
      <el-button type="primary" @click="addUser" :loading="loading">确 定</el-button>
    </div>
  </el-dialog>
</template>
<script>
  import PlusApi from '@/api/plus/release.js';
  export default {
    components: {
    },
    data() {
      return {
        form: {
          category_id: 0,
          name: '',
          sort: '',
        },
        formRules: {
          name: [{
            required: true,
            message: '请输入分类名称',
            trigger: 'blur'
          }],
          sort: [{
            required: true,
            message: '分类排序不能为空'
          }, {
            type: 'number',
            message: '分类排序必须为数字'
          }]
        },
        /*左边长度*/
        formLabelWidth: '120px',
        /*是否显示*/
        dialogVisible: false,
        loading: false,
      };
    },
    props: ['open_edit', 'editform'],
    created() {
      this.dialogVisible = this.open_edit;
      this.form.category_id = this.editform.model.category_id;
      this.form.name = this.editform.model.name;
      this.form.sort = this.editform.model.sort;
    },
    methods: {
      /*修改用户*/
      addUser() {
        let self = this;
        let params = self.form;
        self.$refs.form.validate((valid) => {
          if (valid) {
            self.loading = true;
            PlusApi.catEdit(params, true).then(data => {
              self.loading = false;
              self.$message({
                message: '修改成功',
                type: 'success'
              });
              self.dialogFormVisible(true);
            }).catch(error => {
              self.loading = false;
            });
          }
        });
      },
      /*关闭弹窗*/
      dialogFormVisible(e) {
        if (e) {
          this.$emit('closeDialog', {
            type: 'success',
            openDialog: false
          })
        } else {
          this.$emit('closeDialog', {
            type: 'error',
            openDialog: false
          })
        }
      },
    }
  };
</script>
<style>
  .img {
    margin-top: 10px;
  }
</style>
shop_vue/src/views/plus/release/releasecategory/index.vue
New file
@@ -0,0 +1,130 @@
<template>
  <!--
        作者:wangxw
        时间:2019-10-26
        描述:产品分类管理
    -->
  <div class="product">
    <!--添加产品分类-->
    <div class="common-level-rail">
      <el-button size="small" type="primary" @click="addClick" icon="el-icon-plus" v-auth="'/plus/release/releasecategory/add'">添加分类</el-button>
    </div>
    <!--内容-->
    <div class="product-content">
      <div class="table-wrap">
        <el-table size="small" :data="tableData"  border style="width: 100%" v-loading="loading">
          <el-table-column prop="name" label="分类名称" width="180"></el-table-column>
          <el-table-column prop="sort" label="分类排序"></el-table-column>
          <el-table-column prop="create_time" label="添加时间"></el-table-column>
          <el-table-column fixed="right" label="操作" width="100">
            <template slot-scope="scope">
              <el-button @click="editClick(scope.row)" type="text" size="small" v-auth="'/plus/release/releasecategory/edit'">编辑</el-button>
              <el-button @click="deleteClick(scope.row)" type="text" size="small" v-auth="'/plus/release/releasecategory/delete'">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </div>
    <!--添加-->
    <Add v-if="open_add" :open_add="open_add" :addform="categoryModel" @closeDialog="closeDialogFunc($event, 'add')"></Add>
    <!--修改-->
    <Edit v-if="open_edit" :open_edit="open_edit" :editform="categoryModel" @closeDialog="closeDialogFunc($event, 'edit')"></Edit>
  </div>
</template>
<script>
  import PlusApi from '@/api/plus/release.js';
  import Add from './Add.vue';
  import Edit from './Edit.vue';
  export default {
    components: {
      Add,
      Edit
    },
    data() {
      return {
        /*是否加载完成*/
        loading: true,
        /*列表数据*/
        tableData: [],
        /*是否打开添加弹窗*/
        open_add: false,
        /*是否打开编辑弹窗*/
        open_edit: false,
        /*当前编辑的对象*/
        categoryModel: {
          catList: [],
          model: {}
        }
      };
    },
    created() {
      /*获取列表*/
      this.getData();
    },
    methods: {
      /*获取列表*/
      getData() {
        let self = this;
        PlusApi.catList({}, true)
          .then(data => {
            self.loading = false;
            self.tableData = data.data.list;
            self.categoryModel.catList = self.tableData;
          })
          .catch(error => {
            self.loading = false;
          });
      },
      /*打开添加*/
      addClick() {
        this.open_add = true;
      },
      /*打开编辑*/
      editClick(item) {
        this.categoryModel.model = item;
        this.open_edit = true;
      },
      /*关闭弹窗*/
      closeDialogFunc(e, f) {
        if (f == 'add') {
          this.open_add = e.openDialog;
          if (e.type == 'success') {
            this.getData();
          }
        }
        if (f == 'edit') {
          this.open_edit = e.openDialog;
          if (e.type == 'success') {
            this.getData();
          }
        }
      },
      /*删除分类*/
      deleteClick(row) {
        let self = this;
        self.$confirm('删除后不可恢复,确认删除该记录吗?', '提示', {
          type: 'warning'
        }).then(() => {
          PlusApi.catDel({
            category_id: row.category_id
          }).then(data => {
            self.$message({
              message: '删除成功',
              type: 'success'
            });
            self.getData();
          });
        });
      },
    }
  };
</script>
<style></style>
shop_vue/src/views/plus/release/setting/Setting.vue
New file
@@ -0,0 +1,58 @@
<template>
  <div v-loading="loading">
    <el-tabs size="small" v-model="activeName" type="card" @tab-click="handleClick">
      <el-tab-pane label="结算" name="settlement"></el-tab-pane>
    </el-tabs>
    <!--结算-->
    <Settlement v-if="activeName == 'settlement'" :settingData="settingData"></Settlement>
  </div>
</template>
<script>
import PlusApi from '@/api/plus/release.js';
import Settlement from './part/Settlement';
export default {
  components: {
    /*编辑组件*/
    Settlement,
  },
  data() {
    return {
      /*是否正在加载*/
      loading:true,
      /*当前选中*/
      activeName: '',
      /*数据对象*/
      settingData:{}
    };
  },
  created() {
    if (this.$route.query.type != null) {
      this.activeName = this.$route.query.type;
    }
    this.getData();
  },
  methods: {
    /*获取数据*/
    getData() {
      let self = this;
      PlusApi.releaseSet({}, true)
        .then(res => {
          self.settingData = res.data;
          self.loading=false;
          self.activeName='settlement';
        })
        .catch(error => {});
    },
    handleClick(e) {
      this.activeName = e.name;
    }
  }
};
</script>
shop_vue/src/views/plus/release/setting/part/Settlement.vue
New file
@@ -0,0 +1,104 @@
<template>
  <!--
          作者:yj
      -->
  <div class="mt30">
    <!--form表单-->
    <el-form size="small" ref="form" :model="form" label-width="200px">
      <el-form-item label="提现方式">
        <el-checkbox-group v-model="form.pay_type">
          <el-checkbox v-for="(item,index) in list" :label="item.id" :key="index">{{item.name}}</el-checkbox>
        </el-checkbox-group>
        <div class="tips">注:如使用微信支付,则需申请微信支付企业付款到零钱功能</div>
      </el-form-item>
      <el-form-item label="订单抽成" prop="order_rate" :rules="[{required: true,message: ' '}]">
        <el-input v-model="form.order_rate" type="number" class="max-w460">
           <template slot="append">%</template>
        </el-input>
      </el-form-item>
      <el-form-item label="佣金提现手续费" prop="fee_rate" :rules="[{required: true,message: ' '}]">
        <el-input v-model="form.fee_rate" type="number" class="max-w460">
           <template slot="append">%</template>
        </el-input>
      </el-form-item>
      <el-form-item label="最低提现额度" prop="min_money" :rules="[{required: true,message: ' '}]">
        <el-input v-model="form.min_money" type="number" class="max-w460"></el-input>
      </el-form-item>
      <el-form-item label="提现说明">
        <el-input v-model="form.explain" type="textarea" rows="5" class="max-w460"></el-input>
      </el-form-item>
      <!--提交-->
      <div class="common-button-wrapper">
        <el-button size="small" type="primary" @click="onSubmit" :loading="loading">提交</el-button>
      </div>
    </el-form>
  </div>
</template>
<script>
  import PlusApi from '@/api/plus/release.js';
  export default {
    data() {
      return {
        /*form表单数据*/
        form: {
          pay_type: [
            10
          ],
          explain:'',
        },
        list: [],
        selectlist: [
          10
        ],
        loading: false,
      };
    },
    props: {
      settingData: Object
    },
    created() {
      this.form=this.settingData.data.settlement.values;
      this.list = this.settingData.pay_type;
    },
    methods: {
      /*提交表单*/
      onSubmit() {
        let self = this;
        let params = self.form;
        self.$refs.form.validate((valid) => {
          if (valid) {
            self.loading = true;
            PlusApi.settlement({
                form: params
              }, true)
              .then(data => {
                self.loading = false;
                self.$message({
                  message: '恭喜你,设置成功',
                  type: 'success'
                });
              })
              .catch(error => {
                self.loading = false;
              });
          }
        });
      },
    }
  };
</script>
<style>
</style>
shop_vue/src/views/plus/release/supply/apply/Apply.vue
New file
@@ -0,0 +1,168 @@
<template>
  <!--
          作者:yj
          时间:2025-11-9
      -->
  <div class="user">
    <div class="common-seach-wrap">
      <el-form size="small" :inline="true" :model="formInline" class="demo-form-inline">
        <el-form-item label=""><el-input v-model="formInline.nick_name" placeholder="请输入昵称/姓名/手机号"></el-input></el-form-item>
        <el-form-item><el-button type="primary" @click="onSubmit">查询</el-button></el-form-item>
      </el-form>
    </div>
    <!--内容-->
    <div class="product-content">
      <div class="table-wrap">
        <el-table :data="tableData" size="small" border style="width: 100%" v-loading="loading">
          <el-table-column prop="user_id" label="用户ID" width="60"></el-table-column>
          <el-table-column prop="nickName" label="微信头像" width="70">
            <template slot-scope="scope">
              <img class="radius" v-img-url="scope.row.avatarUrl" width="30" height="30" />
            </template>
          </el-table-column>
          <el-table-column prop="nickName" label="    微信昵称" width="250"></el-table-column>
          <el-table-column prop="real_name" label="姓名" width="100"></el-table-column>
          <el-table-column prop="mobile" label="手机号">
            <template slot-scope="scope">
              <p class="text-ellipsis">{{ scope.row.mobile }}</p>
            </template>
          </el-table-column>
          <!-- <el-table-column prop="detail" label="地址"></el-table-column> -->
          <el-table-column prop="apply_status" label="审核状态" width="100">
            <template slot-scope="scope">
              <span :class="{
                red: scope.row.apply_status.value == 10,
                green: scope.row.apply_status.value == 20,
                gray: scope.row.apply_status.value == 30 }">
                {{ scope.row.apply_status.text }}
              </span>
            </template>
          </el-table-column>
          <el-table-column prop="apply_time" label="申请时间" width="135"></el-table-column>
          <el-table-column fixed="right" label="操作" width="50">
            <template slot-scope="scope">
              <div>
                <el-button v-if="scope.row.apply_status.value == 10" @click="editClick(scope.row)" type="text" size="small">
                  审核
                </el-button>
                <el-button v-if="scope.row.apply_status.value == 30" @click="editClick(scope.row)" type="text" size="small">查看</el-button>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <!--分页-->
      <div class="pagination">
        <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          background
          :current-page="curPage"
          :page-size="pageSize"
          layout="total, prev, pager, next, jumper"
          :total="totalDataNumber"
        ></el-pagination>
      </div>
    </div>
    <Edit v-if="open_edit" :open_edit="open_edit" :form="userModel" @closeDialog="closeDialogFunc($event, 'edit')"></Edit>
  </div>
</template>
<script>
import PlusApi from '@/api/plus/release.js';
import Edit from './dialog/Edit.vue';
export default {
  components: {
    /*编辑组件*/
    Edit
  },
  data() {
    return {
      /*是否加载完成*/
      loading: true,
      /*列表数据*/
      tableData: [],
      /*一页多少条*/
      pageSize: 20,
      /*一共多少条数据*/
      totalDataNumber: 0,
      /*当前是第几页*/
      curPage: 1,
      formInline: {
        nick_name: ''
      },
      /*是否打开编辑弹窗*/
      open_edit: false,
      /*当前编辑的对象*/
      userModel: {}
    };
  },
  created() {
    /*获取列表*/
    this.getData();
  },
  methods: {
    /*选择第几页*/
    handleCurrentChange(val) {
      let self = this;
      self.curPage = val;
      self.loading = true;
      self.getData();
    },
    /*获取数据*/
    getData() {
      let self = this;
      let Params = {};
      Params.page = self.curPage;
      Params.list_rows = self.pageSize;
      Params.nick_name = this.formInline.nick_name;
      PlusApi.supplyApplyList(Params, true)
        .then(data => {
          self.loading = false;
          self.tableData = data.data.apply_list.data;
          self.totalDataNumber = data.data.apply_list.total;
        })
        .catch(error => {});
    },
    //搜索
    onSubmit() {
      this.curPage = 1;
      this.getData();
    },
    /*每页多少条*/
    handleSizeChange(val) {
      this.curPage = 1;
      this.getData();
    },
    /*打开弹出层编辑*/
    editClick(item) {
      this.userModel = item;
      this.open_edit = true;
    },
    /*关闭弹窗*/
    closeDialogFunc(e, f) {
      if (f == 'add') {
        this.open_add = e.openDialog;
        if (e.type == 'success') {
          this.getData();
        }
      }
      if (f == 'edit') {
        this.open_edit = e.openDialog;
        if (e.type == 'success') {
          this.getData();
        }
      }
    }
  }
};
</script>
<style></style>
shop_vue/src/views/plus/release/supply/apply/dialog/Edit.vue
New file
@@ -0,0 +1,88 @@
<template>
  <!--
          作者:yj
          时间:2025-11-9
      -->
  <div v-if="status != 30">
    <el-dialog title="入驻审核" :visible.sync="dialogVisible" @close="dialogFormVisible" :close-on-click-modal="false" :close-on-press-escape="false">
      <el-form :model="form">
        <el-form-item label="审核状态" :label-width="formLabelWidth">
          <div>
            <el-radio v-model="form.apply_status" label="20">审核通过</el-radio>
            <el-radio v-model="form.apply_status" label="30">驳回</el-radio>
          </div>
        </el-form-item>
        <div v-if="form.apply_status == 30">
          <el-form-item label="驳回原因" :label-width="formLabelWidth"><el-input v-model="form.reject_reason" autocomplete="off"></el-input></el-form-item>
        </div>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible">取 消</el-button>
        <el-button type="primary" @click="editApplyStatus">确 定</el-button>
      </div>
    </el-dialog>
  </div>
  <div v-else>
    <el-dialog title="驳回原因" :visible.sync="dialogVisible" @close="dialogFormVisible" :close-on-click-modal="false" :close-on-press-escape="false">
      <p>{{ reject_reason }}</p>
    </el-dialog>
  </div>
</template>
<script>
import PlusApi from '@/api/plus/release.js';
export default {
  data() {
    return {
      status: '',
      reject_reason: '',
      /*左边长度*/
      formLabelWidth: '120px',
      /*是否显示*/
      dialogVisible: false
    };
  },
  props: ['open_edit', 'form'],
  created() {
    this.dialogVisible = this.open_edit;
    this.status = this.form.apply_status.value;
    if (this.status == 30) {
      this.reject_reason = this.form.reject_reason;
    }
  },
  methods: {
    /*修改用户*/
    editApplyStatus() {
      let self = this;
      let params = this.form;
      PlusApi.editSupplyApplyStatus(params, true)
        .then(data => {
          self.$message({
            message: '恭喜你,修改成功',
            type: 'success'
          });
          self.dialogFormVisible(true);
        })
        .catch(error => {});
    },
    /*关闭弹窗*/
    dialogFormVisible(e) {
      if (e) {
        this.$emit('closeDialog', {
          type: 'success',
          openDialog: false
        });
      } else {
        this.$emit('closeDialog', {
          type: 'error',
          openDialog: false
        });
      }
    }
  }
};
</script>
<style></style>
shop_vue/src/views/plus/release/supply/user/User.vue
New file
@@ -0,0 +1,205 @@
<template>
  <!--
          作者:yj
          时间:2025-11-9
      -->
  <div class="user">
    <div class="common-seach-wrap">
      <el-form size="small" :inline="true" :model="formInline" class="demo-form-inline">
        <el-form-item label=""><el-input v-model="formInline.nick_name" placeholder="请输入昵称/姓名/手机号"></el-input></el-form-item>
        <el-form-item><el-button type="primary" @click="onSubmit">查询</el-button></el-form-item>
      </el-form>
    </div>
    <!--内容-->
    <div class="product-content">
      <div class="table-wrap">
        <el-table size="small" :data="tableData" border style="width: 100%" v-loading="loading">
          <el-table-column prop="user_id" label="用户ID" width="70"></el-table-column>
          <el-table-column prop="nickName" label="微信头像" width="70">
            <template slot-scope="scope">
              <img class="radius" v-img-url="scope.row.avatarUrl" width="30" height="30" />
            </template>
          </el-table-column>
          <el-table-column prop="nickName" label="微信昵称" width="250"></el-table-column>
          <el-table-column prop="real_name" label="姓名" width="100"></el-table-column>
          <el-table-column prop="mobile" label="手机号"></el-table-column>
         <!-- <el-table-column prop="detail" label="地址"></el-table-column> -->
          <el-table-column prop="create_time" label="成为时间" width="140"></el-table-column>
          <el-table-column fixed="right" label="操作" width="160">
            <template slot-scope="scope">
              <div>
                <el-button @click="saleClick(scope.row)" type="text" size="small">供应订单</el-button>
                <el-button @click="EditClick(scope.row)" type="text" size="small">修改</el-button>
                <el-button @click="delClick(scope.row)" type="text" size="small">删除</el-button>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <!--分页-->
      <div class="pagination">
        <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          background
          :current-page="curPage"
          :page-size="pageSize"
          layout="total, prev, pager, next, jumper"
          :total="totalDataNumber"
        ></el-pagination>
      </div>
    </div>
    <!--编辑-->
    <Edit :open_edit="open_edit" :userModel="userModel" @close="closeEditFunc"></Edit>
  </div>
</template>
<script>
import { deepClone } from '@/utils/base.js'
import PlusApi from '@/api/plus/release.js';
import Edit from './dialog/Edit.vue';
export default {
  components: {
    Edit,
  },
  data() {
    return {
      /*是否加载完成*/
      loading: true,
      /*列表数据*/
      tableData: [],
      /*一页多少条*/
      pageSize: 20,
      /*一共多少条数据*/
      totalDataNumber: 0,
      /*当前是第几页*/
      curPage: 1,
      /*搜索对象*/
      formInline: {
        nick_name: ''
      },
      /*是否打开弹窗*/
      open_dialog: false,
      /*选中的用户*/
      userModel:{},
      /*是否打开修改*/
      open_edit:false,
    };
  },
  created() {
    /*获取列表*/
    this.getData();
  },
  methods: {
    /*选择第几页*/
    handleCurrentChange(val) {
      let self = this;
      self.curPage = val;
      self.loading = true;
      self.getData();
    },
    /*获取数据*/
    getData() {
      let self = this;
      let Params = {};
      Params.page = self.curPage;
      Params.list_rows = self.pageSize;
      if(self.formInline.nick_name!=''){
        Params.nick_name=self.formInline.nick_name;
      }
      PlusApi.supplyUserList(Params, true)
        .then(data => {
          self.loading = false;
          self.tableData = data.data.list.data;
          self.totalDataNumber = data.data.list.total;
        })
        .catch(error => {
          self.loading = false;
        });
    },
    //搜索
    onSubmit() {
      this.curPage = 1;
      this.getData();
    },
    /*每页多少条*/
    handleSizeChange(val) {
      this.curPage = 1;
      this.pageSize = val;
      this.getData();
    },
    /*维修订单*/
    saleClick(item) {
      this.$router.push({
        path:'/plus/release/index',
        query:{
          type:'supplyorder',
          repair_user_id:item.user_id
        }
      })
    },
    /*删除*/
    delClick(row) {
      let self = this;
      self
        .$confirm('此操作将永久删除该记录, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
        .then(() => {
          self.loading = true;
          PlusApi.deleteSupplyUser(
            {
              user_id: row.user_id
            },
            true
          )
            .then(data => {
              self.loading = false;
              self.$message({
                message: data.msg,
                type: 'success'
              });
              self.getData();
            })
            .catch(error => {
              self.loading = false;
            });
        })
        .catch(() => {
          self.loading = false;
        });
    },
     /*打开编辑用户弹窗*/
    EditClick(e){
      this.userModel=deepClone(e);
      this.open_edit=true;
    },
    /*关闭编辑用户弹窗*/
    closeEditFunc(e){
      this.open_edit=false;
      if(e.type=='success'){
        this.getData();
      }
    }
  }
};
</script>
<style scoped="scoped">
  .el-button{margin-left: 0; margin-right: 10px;}
</style>
shop_vue/src/views/plus/release/supply/user/dialog/Edit.vue
New file
@@ -0,0 +1,92 @@
<template>
  <!--
          作者:yj
          时间:2023-04-11
          描述:售后维修-维修师傅-编辑
      -->
  <el-dialog title="编辑" :visible.sync="dialogVisible" @close="cancelFunc" :close-on-click-modal="false" :close-on-press-escape="false" width="60%">
    <el-form :model="formData">
      <el-form-item label="微信昵称" :label-width="formLabelWidth">
        <el-input type="text" v-model="formData.nickName" autocomplete="off" :disabled="true"></el-input>
      </el-form-item>
      <el-form-item label="微信头像" :label-width="formLabelWidth">
        <img v-img-url="formData.avatarUrl" width="50" height="50" />
      </el-form-item>
      <el-form-item label="姓名" :label-width="formLabelWidth">
        <el-input type="text" v-model="formData.real_name" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="手机号" :label-width="formLabelWidth">
        <el-input type="text" v-model="formData.mobile" autocomplete="off"></el-input>
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="cancelFunc">取 消</el-button>
      <el-button type="primary" @click="confirmFunc">确 定</el-button>
    </div>
  </el-dialog>
</template>
<script>
import PlusApi from '@/api/plus/release.js';
import UserApi from '@/api/user.js';
export default {
  data() {
    return {
      /*左边长度*/
      formLabelWidth: '100px',
      /*是否显示*/
      dialogVisible: false,
      /*表单数据模型*/
      formData: {},
    };
  },
  props: {
    open_edit: Boolean,
    userModel: Object
  },
  watch: {
    open_edit: function(n, o) {
      if (n != o) {
        this.dialogVisible = this.open_edit;
        if (n) {
          this.formData = this.userModel;
        }
      }
    }
  },
  created() {
  },
  methods: {
    /*修改用户*/
    confirmFunc() {
      let self = this;
      let params ={};
      params.user_id= this.formData.user_id;
      params.real_name=this.formData.real_name;
      params.mobile=this.formData.mobile;
      PlusApi.supplyUserEdit(params, true)
        .then(data => {
          self.$message({
            message: '恭喜你,修改成功',
            type: 'success'
          });
          self.cancelFunc(true);
        })
        .catch(error => {});
    },
    /*关闭弹窗*/
    cancelFunc(e) {
      let type='cancel';
      if(e){
        type='success';
      }
      this.$emit('close', {
        type:type
      });
    }
  }
};
</script>
<style></style>
shop_vue/src/views/plus/release/supplyproject/Edit.vue
New file
@@ -0,0 +1,78 @@
<template>
  <!--
      作者:yj
  -->
  <el-dialog title="详情" :visible.sync="dialogVisible" @close='dialogFormVisible' :close-on-click-modal="false"
    :close-on-press-escape="false" width="600px">
    <el-form size="small" :model="form" ref="form">
      <el-form-item label="标题:" :label-width="formLabelWidth">
        {{form.name}}
      </el-form-item>
      <el-form-item label="分类:" :label-width="formLabelWidth">
        {{form.category.name}}
      </el-form-item>
      <el-form-item label="价格:" :label-width="formLabelWidth">
        ¥{{form.price}}
      </el-form-item>
      <el-form-item label="详细描述:" :label-width="formLabelWidth" >
        {{form.content}}
      </el-form-item>
      <el-form-item label="图片:" :label-width="formLabelWidth">
         <div v-if="form.image_list" v-for="(item,index) in form.image_list">
          <a target="_blank" :href="item.file_path"><img style="max-width: 50px; height: 50px;" v-img-url="item.file_path" />
          </a>
        </div>
      </el-form-item>
      <el-form-item label="交付时间:" :label-width="formLabelWidth" >
        {{form.finish_time}}
      </el-form-item>
      <el-form-item label="服务地点:" :label-width="formLabelWidth">
        {{form.detail}}
      </el-form-item>
      <el-form-item label="标签:" :label-width="formLabelWidth">
        <span v-if="form.tag_list" v-for="(item,index) in form.tag_list">{{item.name}};</span>
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="dialogFormVisible">返回</el-button>
    </div>
  </el-dialog>
</template>
<script>
  import PlusApi from '@/api/plus.js';
  export default {
    data() {
      return {
        /*左边长度*/
        formLabelWidth: '120px',
        /*是否显示*/
        dialogVisible: false,
      };
    },
    props: ['open_edit', 'form'],
    created() {
      this.dialogVisible = this.open_edit;
    },
    methods: {
      /*关闭弹窗*/
      dialogFormVisible(e) {
        if (e) {
          this.$emit('closeDialog', {
            type: 'success',
            openDialog: false
          })
        } else {
          this.$emit('closeDialog', {
            type: 'error',
            openDialog: false
          })
        }
      }
    }
  };
</script>
<style></style>
shop_vue/src/views/plus/release/supplyproject/dialog/Edit.vue
New file
@@ -0,0 +1,92 @@
<template>
  <!--
          作者:yj
      -->
  <div v-if="status != 2">
    <el-dialog title="审核" :visible.sync="dialogVisible" @close="dialogFormVisible" :close-on-click-modal="false" :close-on-press-escape="false">
      <el-form :model="form">
        <el-form-item label="审核状态" :label-width="formLabelWidth">
          <div>
            <el-radio v-model="form.status" label="1">审核通过</el-radio>
            <el-radio v-model="form.status" label="2">驳回</el-radio>
          </div>
        </el-form-item>
        <div v-if="form.apply_status == 2">
          <el-form-item label="驳回原因" :label-width="formLabelWidth"><el-input v-model="form.reject_reason" autocomplete="off"></el-input></el-form-item>
        </div>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible">取 消</el-button>
        <el-button type="primary" @click="editApplyStatus">确 定</el-button>
      </div>
    </el-dialog>
  </div>
  <div v-else>
    <el-dialog title="驳回原因" :visible.sync="dialogVisible" @close="dialogFormVisible" :close-on-click-modal="false" :close-on-press-escape="false">
      <p>{{ reject_reason }}</p>
      <!-- <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible">取 消</el-button>
        <el-button type="primary" @click="dialogFormVisible">确 定</el-button>
      </div> -->
    </el-dialog>
  </div>
</template>
<script>
import PlusApi from '@/api/plus/release.js';
export default {
  data() {
    return {
      status: '',
      reject_reason: '',
      /*左边长度*/
      formLabelWidth: '120px',
      /*是否显示*/
      dialogVisible: false
    };
  },
  props: ['open_edit', 'form'],
  created() {
    this.dialogVisible = this.open_edit;
    this.status = this.form.status.value;
    if (this.status == 30) {
      this.reject_reason = this.form.reject_reason;
    }
  },
  methods: {
    /*修改*/
    editApplyStatus() {
      let self = this;
      let params = this.form;
      PlusApi.supplyProjectSubmit(params, true)
        .then(data => {
          self.$message({
            message: '恭喜你,修改成功',
            type: 'success'
          });
          self.dialogFormVisible(true);
        })
        .catch(error => {});
    },
    /*关闭弹窗*/
    dialogFormVisible(e) {
      if (e) {
        this.$emit('closeDialog', {
          type: 'success',
          openDialog: false
        });
      } else {
        this.$emit('closeDialog', {
          type: 'error',
          openDialog: false
        });
      }
    }
  }
};
</script>
<style></style>
shop_vue/src/views/plus/release/supplyproject/index.vue
New file
@@ -0,0 +1,215 @@
<template>
  <!--
          作者:yj
      -->
  <div class="user">
    <!--搜索表单-->
    <div class="common-seach-wrap">
      <el-form size="small" :inline="true" :model="searchForm" class="demo-form-inline">
        <!-- <el-form-item label="类目">
          <el-select size="small" v-model="searchForm.category_id" placeholder="所有分类">
            <el-option label="全部" value="0"></el-option>
            <el-option v-for="(item, index) in categoryList" :key="index" :label="item.name" :value="item.category_id">
            </el-option>
          </el-select>
        </el-form-item> -->
        <el-form-item label="标题">
          <el-input size="small" v-model="searchForm.name" placeholder="请输入标题"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button size="small" type="primary" icon="el-icon-search" @click="onSubmit">查询</el-button>
        </el-form-item>
      </el-form>
    </div>
    <!--内容-->
    <div class="product-content">
      <div class="table-wrap">
        <el-table size="small" :data="tableData" border style="width: 100%" v-loading="loading">
          <el-table-column prop="project_id" label="ID" width="100"></el-table-column>
          <el-table-column prop="name" label="标题"></el-table-column>
          <el-table-column prop="category.name" label="分类" width="200"></el-table-column>
          <el-table-column prop="price" label="价格" width="200"></el-table-column>
          <el-table-column prop="status" label="状态"  width="200">
            <template slot-scope="scope">
              <span v-if="scope.row.status == 0">未审核</span>
              <span v-if="scope.row.status == 1" class="green">已通过</span>
              <span v-if="scope.row.status == 2" class="green">已驳回</span>
            </template>
          </el-table-column>
          <el-table-column fixed="right" label="操作" width="150">
            <template slot-scope="scope">
              <el-button v-if="scope.row.status == 0" @click="shClick(scope.row)" type="text" size="small">审核</el-button>
              <el-button @click="editClick(scope.row)" type="text" size="small" >详情</el-button>
              <el-button @click="deleteClick(scope.row)" type="text" size="small">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <!--分页-->
      <div class="pagination">
        <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" background
          :current-page="curPage" :page-size="pageSize" layout="total, prev, pager, next, jumper"
          :total="totalDataNumber"></el-pagination>
      </div>
    </div>
    <!--编辑-->
    <Edit v-if="open_edit" :open_edit="open_edit" :form="userModel" @closeDialog="closeDialogFunc($event, 'edit')"></Edit>
    <Editsh v-if="open_sh" :open_edit="open_sh" :form="userModel" @closeDialog="closeDialogFunc($event, 'editsh')"></Editsh>
  </div>
</template>
<script>
  import PlusApi from '@/api/plus/release.js';
  import Edit from './Edit.vue';
  import Editsh from './dialog/Edit.vue';
  import {deepClone} from '@/utils/base.js';
  export default {
    components: {
      /*编辑组件*/
      Edit,
      Editsh,
    },
    data() {
      return {
        /*是否加载完成*/
        loading: true,
        /*一页多少条*/
        pageSize: 10,
        /*一共多少条数据*/
        totalDataNumber: 0,
        /*当前是第几页*/
        curPage: 1,
        /*列表数据*/
        tableData: [],
        /*横向表单数据模型*/
        /*搜索参数*/
        searchForm: {
          name: '',
          category_id: ''
        },
        /*是否打开编辑弹窗*/
        open_edit: false,
        /*当前编辑的对象*/
        userModel: {},
        open_sh:false,
      };
    },
    created() {
      /*获取列表*/
      this.getTableList();
    },
    methods: {
      /*选择第几页*/
      handleCurrentChange(val) {
        let self = this;
        self.loading = true;
        self.curPage = val;
        self.getTableList();
      },
      /*每页多少条*/
      handleSizeChange(val) {
        this.pageSize = val;
        this.getTableList();
      },
      /*获取列表*/
      getTableList() {
        let self = this;
        let Params = self.searchForm;
        Params.page = self.curPage;
        Params.list_rows = self.pageSize;
        PlusApi.supplyProject(Params, true)
          .then(data => {
            self.loading = false;
            self.tableData = data.data.list.data;
            self.totalDataNumber = data.data.list.total;
          })
          .catch(error => {
          });
      },
      /*搜索查询*/
      onSubmit() {
        this.curPage = 1;
        this.getTableList();
      },
      /*打开编辑*/
      editClick(item) {
        this.userModel = deepClone(item);
        this.open_edit = true;
      },
      /*打开弹出层审核*/
      shClick(item) {
        this.userModel = item;
        this.open_sh = true;
      },
      /*关闭弹窗*/
      closeDialogFunc(e, f) {
        if (f == 'add') {
          this.open_add = e.openDialog;
          if (e.type == 'success') {
            this.getTableList();
          }
        }
        if (f == 'edit') {
          this.open_edit = e.openDialog;
          if (e.type == 'success') {
            this.getTableList();
          }
        }
        if (f == 'editsh') {
          this.open_sh = e.openDialog;
          if (e.type == 'success') {
            this.getTableList();
          }
        }
      },
      /*删除*/
      deleteClick(row) {
        let self = this;
        self.$confirm('此操作将永久删除该记录, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          self.loading = true;
          PlusApi.supplyDel({
              project_id: row.project_id
            }, true)
            .then(data => {
              self.loading = false;
              if (data.code == 1) {
                self.$message({
                  message: data.msg,
                  type: 'success'
                });
                self.getTableList();
              } else {
                self.$message.error('错了哦,这是一条错误消息');
              }
            })
            .catch(error => {
              self.loading = false;
            });
        }).catch(() => {
        });
      }
    }
  };
</script>
<style></style>
shop_vue/src/views/plus/release/tag/Add.vue
New file
@@ -0,0 +1,86 @@
<template>
  <!--
      作者:yj
  -->
  <el-dialog title="添加" :visible.sync="dialogVisible" @close='dialogFormVisible' :close-on-click-modal="false"
    :close-on-press-escape="false" width="600px">
    <el-form size="small" :model="form" ref="form">
      <el-form-item label="名称" :label-width="formLabelWidth" prop="name" :rules="[{required: true,message: '请输入名称'}]">
        <el-input v-model="form.name" placeholder="请输入名称"></el-input>
      </el-form-item>
      <el-form-item label="排序" :label-width="formLabelWidth" prop="sort" :rules="[{required: true,message: '请输入排序'}]">
        <el-input v-model="form.sort" type="number" placeholder="请输入排序"></el-input>
        <div class="gray9">数字越大,越排前</div>
      </el-form-item>
   </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="dialogFormVisible">取 消</el-button>
      <el-button type="primary" @click="add()" :disabled="submit_loading">确 定</el-button>
    </div>
  </el-dialog>
</template>
<script>
  import PlusApi from '@/api/plus/release.js';
  export default {
    data() {
      return {
        form: {
          name: '',
          sort: 100,
        },
        /*左边长度*/
        formLabelWidth: '120px',
        /*是否显示*/
        dialogVisible: false,
        /*是否正在提交*/
        submit_loading: false,
      };
    },
    props: ['open_add'],
    created() {
      this.dialogVisible = this.open_add;
    },
    methods: {
      /*添加*/
      add() {
        let self = this;
        let params = this.form;
        self.$refs.form.validate((valid) => {
          if (valid) {
            self.submit_loading = true;
            PlusApi.addTag(params, true).then(data => {
                self.submit_loading = false;
                self.$message({
                  message: data.msg,
                  type: 'success'
                });
                self.dialogFormVisible(true);
              })
              .catch(error => {
                self.submit_loading = false;
              });
          }
        });
      },
      /*关闭弹窗*/
      dialogFormVisible(e) {
        if (e) {
          this.$emit('closeDialog', {
            type: 'success',
            openDialog: false
          })
        } else {
          this.$emit('closeDialog', {
            type: 'error',
            openDialog: false
          })
        }
      }
    }
  };
</script>
<style></style>
shop_vue/src/views/plus/release/tag/Edit.vue
New file
@@ -0,0 +1,85 @@
<template>
  <!--
      作者:yj
  -->
  <el-dialog title="编辑" :visible.sync="dialogVisible" @close='dialogFormVisible' :close-on-click-modal="false"
    :close-on-press-escape="false" width="600px">
    <el-form size="small" :model="form" ref="form">
      <el-form-item label="名称" :label-width="formLabelWidth" prop="name" :rules="[{required: true,message: ' '}]">
        <el-input v-model="form.name" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="排序" :label-width="formLabelWidth" prop="sort" :rules="[{required: true,message: '请输入排序'}]">
          <el-input v-model="form.sort" type="number" placeholder="请输入排序"></el-input>
          <div class="gray9">数字越大,越排前</div>
        </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="dialogFormVisible">取 消</el-button>
      <el-button type="primary" @click="edit" :disabled="submit_loading">确 定</el-button>
    </div>
  </el-dialog>
</template>
<script>
  import PlusApi from '@/api/plus/release.js';
  export default {
    data() {
      return {
        /*左边长度*/
        formLabelWidth: '120px',
        /*是否显示*/
        dialogVisible: false,
        /*是否正在提交*/
        submit_loading: false,
      };
    },
    props: ['open_edit', 'form'],
    created() {
      this.dialogVisible = this.open_edit;
    },
    methods: {
      /*修改*/
      edit() {
        let self = this;
        let params = this.form;
        self.$refs.form.validate((valid) => {
          if (valid) {
            self.submit_loading = true;
            PlusApi.editTag(params, true)
              .then(data => {
                self.submit_loading = false;
                self.$message({
                  message: '恭喜你,修改成功',
                  type: 'success'
                });
                self.dialogFormVisible(true);
              })
              .catch(error => {
                self.submit_loading = false;
              });
          }
        });
      },
      /*关闭弹窗*/
      dialogFormVisible(e) {
        if (e) {
          this.$emit('closeDialog', {
            type: 'success',
            openDialog: false
          })
        } else {
          this.$emit('closeDialog', {
            type: 'error',
            openDialog: false
          })
        }
      }
    }
  };
</script>
<style></style>
shop_vue/src/views/plus/release/tag/index.vue
New file
@@ -0,0 +1,147 @@
<template>
  <!--
          作者:yj
      -->
  <div class="user">
    <!--添加-->
    <div class="common-level-rail">
      <el-button size="small" type="primary" @click="addClick" icon="el-icon-plus" v-auth="'/plus/release/tag/add'">添加标签</el-button>
    </div>
    <!--内容-->
    <div class="product-content">
      <div class="table-wrap">
        <el-table size="small" :data="tableData" border style="width: 100%" v-loading="loading">
          <el-table-column prop="tag_id" label="标签ID" width="100"></el-table-column>
          <el-table-column prop="name" label="名称"></el-table-column>
          <el-table-column prop="sort" label="排序" width="200"></el-table-column>
          <el-table-column fixed="right" label="操作" width="90">
            <template slot-scope="scope">
              <el-button @click="editClick(scope.row)" type="text" size="small" v-auth="'/plus/release/tag/edit'" >编辑</el-button>
              <el-button @click="deleteClick(scope.row)" type="text" size="small" v-auth="'/plus/release/tag/delete'">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </div>
    <!--添加-->
    <Add v-if="open_add" :open_add="open_add" @closeDialog="closeDialogFunc($event, 'add')"></Add>
    <!--编辑-->
    <Edit v-if="open_edit" :open_edit="open_edit" :form="userModel" @closeDialog="closeDialogFunc($event, 'edit')"></Edit>
  </div>
</template>
<script>
  import PlusApi from '@/api/plus/release.js';
  import Edit from './Edit.vue';
  import Add from './Add.vue';
  import {deepClone} from '@/utils/base.js';
  export default {
    components: {
      /*编辑组件*/
      Edit,
      Add
    },
    data() {
      return {
        /*是否加载完成*/
        loading: true,
        /*列表数据*/
        tableData: [],
        /*横向表单数据模型*/
        form: {
          become: '0'
        },
        /*是否打开添加弹窗*/
        open_add: false,
        /*是否打开编辑弹窗*/
        open_edit: false,
        /*当前编辑的对象*/
        userModel: {}
      };
    },
    created() {
      /*获取列表*/
      this.getTableList();
    },
    methods: {
      /*获取列表*/
      getTableList() {
        let self = this;
        let Params = {};
        PlusApi.Tag(Params, true)
          .then(data => {
            self.loading = false;
            self.tableData = data.data.list;
          })
          .catch(error => {
          });
      },
      /*打开添加*/
      addClick() {
        this.open_add = true;
      },
      /*打开编辑*/
      editClick(item) {
        this.userModel = deepClone(item);
        this.open_edit = true;
      },
      /*关闭弹窗*/
      closeDialogFunc(e, f) {
        if (f == 'add') {
          this.open_add = e.openDialog;
          if (e.type == 'success') {
            this.getTableList();
          }
        }
        if (f == 'edit') {
          this.open_edit = e.openDialog;
          if (e.type == 'success') {
            this.getTableList();
          }
        }
      },
      /*删除*/
      deleteClick(row) {
        let self = this;
        self.$confirm('此操作将永久删除该记录, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          self.loading = true;
          PlusApi.deleteTag({
              tag_id: row.tag_id
            }, true)
            .then(data => {
              self.loading = false;
              if (data.code == 1) {
                self.$message({
                  message: data.msg,
                  type: 'success'
                });
                self.getTableList();
              } else {
                self.$message.error('错了哦,这是一条错误消息');
              }
            })
            .catch(error => {
              self.loading = false;
            });
        }).catch(() => {
        });
      }
    }
  };
</script>
<style></style>
shop_vue/src/views/plus/shareholder/setting/part/Basic.vue
@@ -18,7 +18,7 @@
            <template slot="append">%</template>
          </el-input>
          <div class="tips">订单总分红比例 * 订单实付金额 = 可被所有股东瓜分的分红总金额</div>
        </el-form-item>
      </el-form-item>
     <el-form-item label="是否开启平级分红">
       <div>
         <el-radio v-model="form.pjaward" label="1">开启</el-radio>
@@ -38,6 +38,20 @@
          <el-radio v-model="form.bonus_type" label="30">按年</el-radio>
        </div>
      </el-form-item>
      <el-form-item label="红比发放条件">
        <div>
          <label class="el-form-item__label" style="width: 140px;">消费金额</label>
          <el-input v-model="form.consumption_amount" type="number" class="max-w460">
            <template slot="append">元</template>
          </el-input>
       </div>
       <div>
         <label class="el-form-item__label" style="width: 140px;">购买次数VIP专区商品</label>
          <el-input v-model="form.condition_purchase_count" type="number" class="max-w460">
            <template slot="append">次</template>
          </el-input>
       </div>
      </el-form-item>
      <el-form-item label="成为股东条件">
        <div>
          <el-radio v-model="form.become" label="10">申请</el-radio>
@@ -49,6 +63,7 @@
          <!-- <el-radio v-model="form.become" label="60">已提现佣金</el-radio> -->
          <el-radio v-model="form.become" label="70">累计团队业绩</el-radio>
          <el-radio v-model="form.become" label="80">团队总人数</el-radio>
          <el-radio v-model="form.become" label="110">团队推荐指定会员等级和商家</el-radio>
          <!-- <el-radio v-model="form.become" label="90">一次性消费金额</el-radio> -->
        </div>
      </el-form-item>
@@ -115,6 +130,35 @@
          </el-row>
        </div>
      </el-form-item>
      <el-form-item label="团队推荐商户入驻人数需达到" v-if="form.become==110">
        <el-input v-model="form.totalsh_down" type="number" class="max-w460">
          <template slot="append">人</template>
        </el-input>
        <div class="tips"></div>
      </el-form-item>
      <el-form-item label="团队推荐指定会员等级达到" v-if="form.become==110">
        <div  class="max-w460">
          <el-select v-model="form.referee_grade_ids" multiple>
            <el-option
              v-for="item in userGradeList"
              :key="item.grade_id"
              :label="item.name"
              :value="item.grade_id">
            </el-option>
          </el-select>
        </div>
        <br/>
        <el-input v-model="form.totalvip_down" type="number" class="max-w460">
          <template slot="append">人</template>
        </el-input>
        <div class="tips"></div>
      </el-form-item>
      <el-form-item label="VIP专区购买商品次数" v-if="form.become==110">
        <el-input v-model="form.purchase_count" type="number" class="max-w460">
          <template slot="append">次</template>
        </el-input>
        <div class="tips"></div>
      </el-form-item>
      <!--提交-->
      <div class="common-button-wrapper">
        <el-button size="small" type="primary" @click="onSubmit" :loading="loading">提交</el-button>
@@ -128,8 +172,12 @@
<script>
import PlusApi from '@/api/plus/shareholder.js';
import Product from '@/components/product/Product';
import Test from "../../../../help/test.vue";
import Spec from "../../../../product/product/part/Spec.vue";
export default {
  components: {
    Spec,
    Test,
    /*产品列表组件*/
    Product: Product
  },
@@ -145,7 +193,8 @@
      /*是否打开产品弹出层*/
      isproduct: false,
      /*是否正在加载*/
      loading: false
      loading: false,
      userGradeList:[]
    };
  },
  props:{
@@ -153,6 +202,10 @@
  },
  created() {
    this.form=this.settingData.data.basic.values;
    this.userGradeList=this.settingData.userGradeList;
    for (let i = 0; i < this.form.referee_grade_ids.length; i++) {
      this.form.referee_grade_ids[i] = parseInt(this.form.referee_grade_ids[i]);
    }
    if (!this.form.product_image) {
      this.form.product_image = [];
    }
shop_vue/src/views/plus/team/setting/part/Basic.vue
@@ -71,12 +71,28 @@
          <el-input v-model="form.totalsh_down" type="number" class="max-w460">
            <template slot="append">人</template>
          </el-input>
          <div class="tips"></div>
        </el-form-item>
        <el-form-item label="下级指定会员等级达到" v-if="form.become==70">
          <div  class="max-w460">
            <el-select v-model="form.referee_grade_ids" multiple>
              <el-option
                v-for="item in userGradeList"
                :key="item.grade_id"
                :label="item.name"
                :value="item.grade_id">
              </el-option>
            </el-select>
          </div>
          <br/>
          <el-input v-model="form.totalvip_down" type="number" class="max-w460">
            <template slot="append">人</template>
          </el-input>
          <div class="tips"></div>
        </el-form-item>
        <el-form-item label="下级VIP会员达到" v-if="form.become==70">
          <el-input v-model="form.totalvip_down" type="number" class="max-w460">
            <template slot="append">人</template>
        <el-form-item label="VIP专区购买商品次数" v-if="form.become==70">
          <el-input v-model="form.purchase_count" type="number" class="max-w460">
            <template slot="append">次</template>
          </el-input>
          <div class="tips"></div>
        </el-form-item>
@@ -102,18 +118,22 @@
        self_buy: ''
      },
      /*是否正在加载*/
      loading: false
      loading: false,
      /*用户等级列表*/
      userGradeList:[]
    };
  },
  props:{
    settingData:Object
  },
  created() {
    this.form=this.settingData.data.basic.values;
    this.userGradeList=this.settingData.userGradeList;
    for (let i = 0; i < this.form.referee_grade_ids.length; i++) {
      this.form.referee_grade_ids[i] = parseInt(this.form.referee_grade_ids[i]);
    }
  },
  methods: {
    /*提交表单*/
    onSubmit() {
      let self = this;
shop_vue/src/views/plus/vip/grade/part/Log.vue
@@ -25,28 +25,28 @@
    <div class="table-wrap">
      <el-table :data="tableData" style="width: 100%" v-loading="loading">
        <el-table-column prop="log_id" label="ID" width="80"></el-table-column>
        <el-table-column prop="user.nickName" label="用户信息">
        <el-table-column prop="vipUser.nickName" label="用户信息">
          <template slot-scope="scope">
            <div class="d-s-c">
              <div class="head-img mr10">
                <img :src="scope.row.user.avatarUrl" alt="" />
                <img :src="scope.row.vipUser.avatarUrl" alt="" />
              </div>
              <div>
                <p>{{ scope.row.user.nickName }}</p>
                <p>{{ scope.row.vipUser.nickName }}</p>
                <p class="gray9">ID: {{ scope.row.user_id }}</p>
              </div>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="old_grade.name" label="变更前等级">
        <el-table-column prop="oldGrade.name" label="变更前等级">
          <template slot-scope="scope">
            <span v-if="scope.row.old_grade">{{ scope.row.old_grade.name }}</span>
            <span v-if="scope.row.oldGrade">{{ scope.row.oldGrade.name }}</span>
            <span v-else class="gray9">无</span>
          </template>
        </el-table-column>
        <el-table-column prop="new_grade.name" label="变更后等级">
        <el-table-column prop="grade.name" label="变更后等级">
          <template slot-scope="scope">
            <span v-if="scope.row.new_grade">{{ scope.row.new_grade.name }}</span>
            <span v-if="scope.row.grade">{{ scope.row.grade.name }}</span>
            <span v-else class="gray9">无</span>
          </template>
        </el-table-column>
@@ -57,7 +57,7 @@
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="remark" label="备注"">
        <el-table-column prop="remark" label="备注">
          <template slot-scope="scope">
            <span>{{ scope.row.remark || '无' }}</span>
          </template>
@@ -133,4 +133,4 @@
};
</script>
<style></style>
<style></style>