浏览代码

红娘系统

linwu 10 月之前
父节点
当前提交
2f249bac69
共有 39 个文件被更改,包括 4285 次插入19 次删除
  1. 13 12
      app/common/Constant.php
  2. 125 0
      app/matchmaker/controller/AdminMatchmakerController.php
  3. 87 0
      app/matchmaker/controller/AdminMatchmakerUserController.php
  4. 47 0
      app/matchmaker/controller/IndexController.php
  5. 51 0
      app/matchmaker/controller/LoginController.php
  6. 44 0
      app/matchmaker/controller/MatchmakerBaseController.php
  7. 41 0
      app/matchmaker/controller/MyController.php
  8. 568 0
      app/matchmaker/controller/UserController.php
  9. 19 0
      app/matchmaker/model/MatchmakerModel.php
  10. 21 0
      app/matchmaker/model/MatchmakerUserFollowModel.php
  11. 19 0
      app/matchmaker/model/MatchmakerUserMatingModel.php
  12. 31 0
      app/matchmaker/model/MatchmakerUserModel.php
  13. 0 2
      data/runtime/.gitignore
  14. 81 0
      public/themes/admin_simpleboot3/matchmaker/admin_matchmaker/add.html
  15. 90 0
      public/themes/admin_simpleboot3/matchmaker/admin_matchmaker/edit.html
  16. 53 0
      public/themes/admin_simpleboot3/matchmaker/admin_matchmaker/index.html
  17. 68 0
      public/themes/admin_simpleboot3/matchmaker/admin_matchmaker_user/index.html
  18. 163 0
      public/themes/admin_simpleboot3/matchmaker/admin_matchmaker_user/show.html
  19. 0 1
      public/themes/simpleboot3/love/my/index.html
  20. 167 0
      public/themes/simpleboot3/matchmaker/index/index.html
  21. 160 0
      public/themes/simpleboot3/matchmaker/login/index.html
  22. 113 0
      public/themes/simpleboot3/matchmaker/my/index.html
  23. 101 0
      public/themes/simpleboot3/matchmaker/my/info.html
  24. 14 0
      public/themes/simpleboot3/matchmaker/public/base.html
  25. 13 0
      public/themes/simpleboot3/matchmaker/public/meta_header.html
  26. 116 0
      public/themes/simpleboot3/matchmaker/user/follow.html
  27. 540 0
      public/themes/simpleboot3/matchmaker/user/info_add.html
  28. 512 0
      public/themes/simpleboot3/matchmaker/user/info_edit.html
  29. 236 0
      public/themes/simpleboot3/matchmaker/user/match.html
  30. 392 0
      public/themes/simpleboot3/matchmaker/user/mating_add.html
  31. 394 0
      public/themes/simpleboot3/matchmaker/user/mating_edit.html
  32. 二进制
      public/themes/simpleboot3/public/assets/images/default_avatar.png
  33. 二进制
      public/themes/simpleboot3/public/assets/images/matchmaker/avatar1.png
  34. 二进制
      public/themes/simpleboot3/public/assets/images/matchmaker/avatar2.png
  35. 二进制
      public/themes/simpleboot3/public/assets/images/matchmaker/myBG.png
  36. 二进制
      public/themes/simpleboot3/public/assets/images/matchmaker/myIcon.png
  37. 二进制
      public/themes/simpleboot3/public/assets/images/matchmaker/myIcon2.png
  38. 二进制
      public/themes/simpleboot3/public/assets/images/matchmaker/myIcon3.png
  39. 6 4
      vendor/thinkcmf/cmf/src/lib/Upload.php

+ 13 - 12
app/common/Constant.php

@@ -4,24 +4,25 @@ namespace app\common;
 
 class Constant
 {
-    const SEX          = ['保密', '男', '女'];
-    const MARRY        = ['未婚', '离婚', '丧偶'];
-    const TYPE         = ['交朋友', '找知己', '谈恋爱', '结婚'];
-    const EDUCATION    = ['本科以下', '本科', '硕士', '博士'];
-    const TINYINT      = ['保密', '是', '否'];
-    const COND_TINYINT = ['不限', '是', '否'];
+    const SEX            = ['保密', '男', '女'];
+    const SEX_MATCHMAKER = [1 => '男', 2 => '女'];
+    const MARRY          = ['未婚', '离婚', '丧偶'];
+    const TYPE           = ['交朋友', '找知己', '谈恋爱', '结婚'];
+    const EDUCATION      = ['本科以下', '本科', '硕士', '博士'];
+    const TINYINT        = ['保密', '是', '否'];
+    const COND_TINYINT   = ['不限', '是', '否'];
 //    const JOB = ['销售','IT工程师','教授','在校学生','产品经理','总经理','副总/总监','部门经理','中层管理','企业家','个体老板','高级干部','公务员','律师','医生','护士','专家学者','工程师','设计师','艺术家','演员','模特','离/退休','技术员','服务员','普通员工','自由职业','无业'];
-    const INCOME = ['保密', '5万以下', '5-10万', '10-20万', '20-30万', '30-50万', '50-100万', '100万以上'];
+    const INCOME      = ['保密', '5万以下', '5-10万', '10-20万', '20-30万', '30-50万', '50-100万', '100万以上'];
     const COND_INCOME = ['不限', '5万以下', '5-10万', '10-20万', '20-30万', '30-50万', '50-100万', '100万以上'];
-    const NATION = ['汉族', '藏族', '朝鲜族', '蒙古族', '回族', '满族', '维吾尔族', '壮族', '彝族', '苗族', '其他民族'];
-    const FAITH  = ['无宗教信仰', '大乘佛教显宗', '大乘佛教密宗', '小乘佛教', '道教', '儒教', '基督教天主教派', '基督教东正教派', '基督教新教派', '犹太教', '伊斯兰教什叶派', '伊斯兰教逊尼派', '印度教', '神道教', '萨满教', '其他宗教信仰'];
-    const SMOKE  = ['不吸,很反感', '不吸烟,但不反感', '社交时偶尔吸烟', '烟不离手'];
-    const DRINK  = ['不喝酒', '社交需要喝', '兴致时小酌', '酒不离口'];
+    const NATION      = ['汉族', '藏族', '朝鲜族', '蒙古族', '回族', '满族', '维吾尔族', '壮族', '彝族', '苗族', '其他民族'];
+    const FAITH       = ['无宗教信仰', '大乘佛教显宗', '大乘佛教密宗', '小乘佛教', '道教', '儒教', '基督教天主教派', '基督教东正教派', '基督教新教派', '犹太教', '伊斯兰教什叶派', '伊斯兰教逊尼派', '印度教', '神道教', '萨满教', '其他宗教信仰'];
+    const SMOKE       = ['不吸,很反感', '不吸烟,但不反感', '社交时偶尔吸烟', '烟不离手'];
+    const DRINK       = ['不喝酒', '社交需要喝', '兴致时小酌', '酒不离口'];
 //    const COMPANY_NATURE = ['政府机关','事业单位','外企企业','世界500强','上市公司','国有企业','私营企业','自有公司'];
 //    const TOPHOME = ['独生子女','老大','老二','老三','老四','老五','其他'];
 //    const WANTCHILD = ['愿意','不愿意','视情况而定'];
 //    const LIVEPARENT = ['愿意','不愿意','视情况而定'];
-    const ID_TYPE = ['公务员', '事业干部', '编外人员', '国企高管','职工'];
+    const ID_TYPE = ['公务员', '事业干部', '编外人员', '国企高管', '职工'];
     const FAMILY  = ['爷爷', '奶奶', '外公', '外婆', '父亲', '母亲', '哥哥', '弟弟', '姐姐', '妹妹'];
 //    const TALENT_LEVEL = ['第一层次', '第二层次', '第三层次', '第四层次', '第五层次', '第六层次', '第七层次', '其他人才', '不是人才'];
     const NATIVE = ['晋江籍', '非晋江籍', '无要求'];

+ 125 - 0
app/matchmaker/controller/AdminMatchmakerController.php

@@ -0,0 +1,125 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 小夏 < 449134904@qq.com>
+// +----------------------------------------------------------------------
+namespace app\matchmaker\controller;
+
+use app\matchmaker\model\MatchmakerModel;
+use app\matchmaker\model\MatchmakerUserModel;
+use cmf\controller\AdminBaseController;
+use think\db\Query;
+
+class AdminMatchmakerController extends AdminBaseController
+{
+
+    /**
+     *  红娘管理
+     */
+    public function index()
+    {
+        $name = $this->request->param('name');
+        $mobile = $this->request->param('mobile');
+        $list = MatchmakerModel::where(function (Query $query) use ($name, $mobile) {
+                if ($name) {
+                    $query->where('name', 'like', "%$name%");
+                }
+
+                if ($mobile) {
+                    $query->where('mobile', 'like', "%$mobile%");
+                }
+            })
+            ->order("id DESC")
+            ->paginate(10);
+        $list->appends(['name' => $name, 'mobile' => $mobile]);
+        // 获取分页显示
+        $page = $list->render();
+
+        $this->assign("page", $page);
+        $this->assign("list", $list);
+        return $this->fetch();
+    }
+
+    /**
+     * 添加
+     */
+    public function add()
+    {
+        return $this->fetch();
+    }
+
+    /**
+     * 添加提交
+     */
+    public function addPost()
+    {
+        if ($this->request->isPost()) {
+            $data = $this->request->param();
+            $post = $data['post'];
+            $post['password'] = trim($post['password']);
+
+            MatchmakerModel::create($post);
+
+            $this->success('添加成功!', url('index'));
+        }
+
+    }
+
+    /**
+     * 编辑
+     */
+    public function edit()
+    {
+        $id   = $this->request->param('id', 0, 'intval');
+        $post = MatchmakerModel::get($id);
+
+        $this->assign('post', $post);
+        return $this->fetch();
+    }
+
+    /**
+     * 编辑提交
+     */
+    public function editPost()
+    {
+
+        if ($this->request->isPost()) {
+            $data = $this->request->param();
+            $post = $data['post'];
+            $post['password'] = trim($post['password']);
+
+            if (empty($post['password'])) {
+                unset($post['password']);
+            }
+
+            MatchmakerModel::update($post, ['id' => $post['id']]);
+
+            $this->success('编辑成功!', url('index'));
+        }
+    }
+
+    /**
+     * 删除
+     */
+    public function delete()
+    {
+        $id = $this->request->param('id');
+        if (empty($id)) {
+            $this->error('参数错误');
+        }
+
+        $check = MatchmakerUserModel::where('matchmaker_id',$id)->find();
+        if (!empty($check)) {
+            $this->error('该红娘下还有人员,无法删除');
+        }
+
+        MatchmakerModel::destroy($id);
+
+        $this->success('删除成功!');
+    }
+}

+ 87 - 0
app/matchmaker/controller/AdminMatchmakerUserController.php

@@ -0,0 +1,87 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: Powerless < wzxaini9@gmail.com>
+// +----------------------------------------------------------------------
+
+namespace app\matchmaker\controller;
+
+use app\common\Constant;
+use app\matchmaker\model\MatchmakerUserMatingModel;
+use app\matchmaker\model\MatchmakerUserModel;
+use cmf\controller\AdminBaseController;
+use think\facade\Request;
+
+class AdminMatchmakerUserController extends AdminBaseController
+{
+
+    public function index()
+    {
+        $data  = $this->request->param();
+        $where = [];
+
+        if (!empty($data['realname'])) {
+            $where[] = ['realname', 'like', "%{$data['realname']}%"];
+        }
+
+        if (!empty($data['mobile'])) {
+            $where[] = ['mobile', 'like', "%{$data['mobile']}%"];
+        }
+
+        $count = MatchmakerUserModel::with('matchmaker')
+            ->where($where)
+            ->count();
+        $this->assign('total', $count);
+
+        $list = MatchmakerUserModel::with('matchmaker')
+            ->where($where)
+            ->order("id DESC")
+            ->paginate(10, false, [
+                'query' => Request::param(),//不丢失已存在的url参数
+            ]);
+
+        // 获取分页显示
+        $page = $list->render();
+        $this->assign('list', $list);
+        $this->assign('page', $page);
+        // 渲染模板输出
+        return $this->fetch();
+    }
+
+    /**
+     * 详情
+     */
+    public function show()
+    {
+        //获取id
+        $id = input('param.id');
+        if (empty($id)) {
+            $this->error(lang('信息不存在或已删除'));
+        }
+
+        //获取信息
+        $info                     = MatchmakerUserModel::get($id, ['matchmaker']);
+        $info['family_text']           = $info['family'] ? implode(',', $info['family']) : '未填写';
+        $info['have_house']       = Constant::COND_TINYINT[$info['have_house']];
+        $info['have_car']         = Constant::COND_TINYINT[$info['have_car']];
+        $info['with_parent_live'] = Constant::COND_TINYINT[$info['with_parent_live']];
+        if (empty($info)) {
+            $this->error(lang('信息不存在或已删除'));
+        }
+        $this->assign('info', $info);
+
+        $mating                     = MatchmakerUserMatingModel::get(['user_id' => $id]);
+        $mating['have_house']       = Constant::COND_TINYINT[$mating['have_house']];
+        $mating['have_car']         = Constant::COND_TINYINT[$mating['have_car']];
+        $mating['with_parent_live'] = Constant::COND_TINYINT[$mating['with_parent_live']];
+        $this->assign('mating', $mating);
+
+        return $this->fetch();
+    }
+
+}

+ 47 - 0
app/matchmaker/controller/IndexController.php

@@ -0,0 +1,47 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 老猫 <thinkcmf@126.com>
+// +----------------------------------------------------------------------
+namespace app\matchmaker\controller;
+
+use app\common\Constant;
+use app\common\Fun;
+use app\matchmaker\model\MatchmakerUserModel;
+
+class IndexController extends MatchmakerBaseController
+{
+    public function index()
+    {
+        return $this->fetch();
+    }
+
+    public function listUser()
+    {
+        $param = $this->request->post();
+
+        $where = [
+            ['matchmaker_id', '=', $this->matchmaker['id']],
+        ];
+        if (!empty($param['keyword'])) {
+            $where[] = ['realname|mobile', 'like', "%{$param['keyword']}%"];
+        }
+
+        $list = MatchmakerUserModel::where($where)
+            ->order('id desc')
+            ->limit(6)
+            ->page($param['page'])
+            ->select();
+        foreach ($list as $v) {
+            $v['age'] = Fun::getAgeByBirth($v['birthday']);
+            $v['sex_text'] = Constant::SEX[$v['sex']];
+        }
+
+        $this->result($list, 1);
+    }
+}

+ 51 - 0
app/matchmaker/controller/LoginController.php

@@ -0,0 +1,51 @@
+<?php
+
+namespace app\matchmaker\controller;
+
+use app\matchmaker\model\MatchmakerModel;
+use cmf\controller\HomeBaseController;
+
+class LoginController extends HomeBaseController
+{
+    /**
+     * 登录
+     */
+    public function index()
+    {
+        return $this->fetch();
+    }
+
+    public function login()
+    {
+        $param = $this->request->param();
+
+        if (empty($param['mobile']) || empty($param['password'])) {
+            $this->error('请输入手机号或密码');
+        }
+
+        $matchmaker = MatchmakerModel::where('mobile',$param['mobile'])->find();
+        if (empty($matchmaker)) {
+            $this->error('手机号错误');
+        }
+
+        if ($matchmaker['status'] != 1) {
+            $this->error('该账号已经被封禁');
+        }
+
+        if ($matchmaker['password'] != $param['password']) {
+            $this->error('密码错误');
+        }
+
+        session('matchmaker.id',$matchmaker['id']);
+        $this->success('登录成功');
+    }
+
+    /**
+     * 退出登录
+     */
+    public function logout()
+    {
+        session("matchmaker", null);//只有前台用户退出
+        return redirect(cmf_url("matchmaker/Login/index"));
+    }
+}

+ 44 - 0
app/matchmaker/controller/MatchmakerBaseController.php

@@ -0,0 +1,44 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +---------------------------------------------------------------------
+// | Author: Dean <zxxjjforever@163.com>
+// +----------------------------------------------------------------------
+namespace app\matchmaker\controller;
+
+use app\matchmaker\model\MatchmakerModel;
+use cmf\controller\HomeBaseController;
+use think\facade\Session;
+
+class MatchmakerBaseController extends HomeBaseController
+{
+    protected $matchmaker = null;
+
+    public function initialize()
+    {
+        parent::initialize();
+        $matchmaker_id = session('matchmaker.id');
+
+        //记录回调
+        $domain = $this->request->url(true);
+        Session::set('domain', $domain);
+
+        if (empty($matchmaker_id)) {
+            if ($this->request->isAjax()) {
+                $this->error("您尚未登录", cmf_url("matchmaker/Login/index"));
+            } else {
+                $this->redirect(cmf_url("matchmaker/Login/index"));
+            }
+        }
+
+        $this->matchmaker = MatchmakerModel::get($matchmaker_id);
+        if (empty($this->matchmaker)) {
+            Session::destroy();
+            $this->redirect(cmf_url("matchmaker/Login/index"));
+        }
+    }
+}

+ 41 - 0
app/matchmaker/controller/MyController.php

@@ -0,0 +1,41 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 老猫 <thinkcmf@126.com>
+// +----------------------------------------------------------------------
+namespace app\matchmaker\controller;
+
+use app\matchmaker\model\MatchmakerModel;
+
+class MyController extends MatchmakerBaseController
+{
+    public function index()
+    {
+        $data['matchmaker'] = $this->matchmaker;
+        $data['matchmaker']['avatar'] = cmf_get_image_url($data['matchmaker']['avatar']);
+
+        return $this->fetch('',$data);
+    }
+
+    public function info()
+    {
+        $data['matchmaker'] = $this->matchmaker;
+        $data['matchmaker']['avatar'] = cmf_get_image_url($data['matchmaker']['avatar']);
+
+        return $this->fetch('',$data);
+    }
+
+    public function infoPost()
+    {
+        $data = $this->request->post();
+
+        MatchmakerModel::update($data);
+
+        $this->success();
+    }
+}

+ 568 - 0
app/matchmaker/controller/UserController.php

@@ -0,0 +1,568 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 老猫 <thinkcmf@126.com>
+// +----------------------------------------------------------------------
+namespace app\matchmaker\controller;
+
+use app\common\Constant;
+use app\common\Fun;
+use app\love\model\UserModel;
+use app\matchmaker\model\MatchmakerUserFollowModel;
+use app\matchmaker\model\MatchmakerUserMatingModel;
+use app\matchmaker\model\MatchmakerUserModel;
+
+class UserController extends MatchmakerBaseController
+{
+    public function infoAdd()
+    {
+        $data = [
+            'sex'       => Constant::SEX_MATCHMAKER,
+            'marry'     => Constant::MARRY,
+            'high'      => Constant::HIGH,
+            'weight'    => Constant::WEIGHT,
+            'education' => Constant::EDUCATION,
+            'income'    => Constant::INCOME,
+            'nation'    => Constant::NATION,
+            'smoke'     => Constant::SMOKE,
+            'drink'     => Constant::DRINK,
+            'family'    => Constant::FAMILY,
+            'tinyint'   => Constant::TINYINT,
+        ];
+        foreach ($data as &$v) {
+            $v = json_encode($v);
+            unset($v);
+        }
+
+        return $this->fetch('', $data);
+    }
+
+    public function infoAddPost()
+    {
+        $value                  = $this->request->post();
+        $value['birthday']      = strtotime($value['birthday']);
+        $value['matchmaker_id'] = $this->matchmaker['id'];
+        $user                   = MatchmakerUserModel::create($value);
+        MatchmakerUserMatingModel::create(['user_id' => $user['id']]);
+        $this->success('', '', ['id' => $user['id']]);
+    }
+
+    public function matingAdd()
+    {
+        $id = $this->request->param('id');
+        if (empty($id)) {
+            $this->error('参数错误');
+        }
+        $mating = MatchmakerUserMatingModel::get(['user_id' => $id]);
+        $this->assign('mating', $mating);
+
+        $education   = Constant::EDUCATION;
+        $education[] = '无要求';
+        $data        = [
+            'min_age'    => Constant::MIN_AGE,
+            'max_age'    => Constant::MAX_AGE,
+            'min_high'   => Constant::MIN_HIGH,
+            'max_high'   => Constant::MAX_HIGH,
+            'min_weight' => Constant::MIN_WEIGHT,
+            'max_weight' => Constant::MAX_WEIGHT,
+            'native'     => Constant::NATIVE,
+            'education'  => $education,
+            'income'     => Constant::COND_INCOME,
+            'smoke'      => Constant::SMOKE,
+            'drink'      => Constant::DRINK,
+            'tinyint'    => Constant::COND_TINYINT,
+        ];
+        foreach ($data as &$v) {
+            $v = json_encode($v);
+            unset($v);
+        }
+
+        return $this->fetch('', $data);
+    }
+
+    public function matingAddPost()
+    {
+        $param = $this->request->post();
+        MatchmakerUserMatingModel::update($param);
+        $this->success('操作成功');
+    }
+
+    public function infoEdit()
+    {
+        $id = $this->request->param('id');
+        if (empty($id)) {
+            $this->error('参数错误');
+        }
+
+        $user = MatchmakerUserModel::get($id);
+        if (empty($user)) {
+            $this->error('该用户不存在或已删除');
+        }
+        $user['birthday'] = date('Y-m-d', $user['birthday']);
+        $this->assign('user', json_encode($user));
+
+        $data = [
+            'sex'       => Constant::SEX_MATCHMAKER,
+            'marry'     => Constant::MARRY,
+            'high'      => Constant::HIGH,
+            'weight'    => Constant::WEIGHT,
+            'education' => Constant::EDUCATION,
+            'income'    => Constant::INCOME,
+            'nation'    => Constant::NATION,
+            'smoke'     => Constant::SMOKE,
+            'drink'     => Constant::DRINK,
+            'family'    => Constant::FAMILY,
+            'tinyint'   => Constant::TINYINT,
+        ];
+        foreach ($data as &$v) {
+            $v = json_encode($v);
+            unset($v);
+        }
+
+        return $this->fetch('', $data);
+    }
+
+    public function infoEditPost()
+    {
+        $value             = $this->request->post();
+        $value['birthday'] = strtotime($value['birthday']);
+        MatchmakerUserModel::update($value);
+
+        $this->success();
+    }
+
+    public function matingEdit()
+    {
+        $id = $this->request->param('id');
+        if (empty($id)) {
+            $this->error('参数错误');
+        }
+        $mating = MatchmakerUserMatingModel::get(['user_id' => $id]);
+        $this->assign('mating', $mating);
+
+        $education   = Constant::EDUCATION;
+        $education[] = '无要求';
+        $data        = [
+            'min_age'    => Constant::MIN_AGE,
+            'max_age'    => Constant::MAX_AGE,
+            'min_high'   => Constant::MIN_HIGH,
+            'max_high'   => Constant::MAX_HIGH,
+            'min_weight' => Constant::MIN_WEIGHT,
+            'max_weight' => Constant::MAX_WEIGHT,
+            'native'     => Constant::NATIVE,
+            'education'  => $education,
+            'income'     => Constant::COND_INCOME,
+            'smoke'      => Constant::SMOKE,
+            'drink'      => Constant::DRINK,
+            'tinyint'    => Constant::COND_TINYINT,
+        ];
+        foreach ($data as &$v) {
+            $v = json_encode($v);
+            unset($v);
+        }
+
+        return $this->fetch('', $data);
+    }
+
+    public function matingEditPost()
+    {
+        $param = $this->request->post();
+        MatchmakerUserMatingModel::update($param);
+        $this->success('操作成功');
+    }
+
+    /**
+     * 图片上传
+     */
+    public function imageUpload()
+    {
+        $file = $this->request->post('file');
+        $ext  = pathinfo($this->request->post('name'))['extension'];
+        if (!in_array($ext, ['jpg', 'jpeg', 'png'])) {
+            $this->error('文件后缀必须为jpg,jpeg,png');
+        }
+
+        if ($file) {
+            //创建目录
+            $upload_dir = WEB_ROOT . 'upload/image';
+            if (!is_dir($upload_dir)) {
+                @mkdir($upload_dir);
+            }
+            $upload_dir = $upload_dir . '/' . date('Ymd');
+            if (!is_dir($upload_dir)) {
+                @mkdir($upload_dir);
+            }
+
+            //保存文件
+            $file_name = $this->_file_name($ext);
+            $file_path = $upload_dir . '/' . $file_name;
+            $is_upload = $this->_base64_image_content($file, $file_path);
+            if (!$is_upload) {
+                $this->error('上传失败,请重新上传');
+            }
+
+            $avatar = cmf_get_user_avatar_url('image' . '/' . date('Ymd') . '/' . $file_name);
+
+            $this->result([
+                'avatar' => $avatar,
+            ], 1);
+        } else {
+            $this->error('请上传文件');
+        }
+    }
+
+    /**
+     * 跟进
+     */
+    public function follow()
+    {
+        $id               = $this->request->get('id');
+        $list             = MatchmakerUserFollowModel::where('user_id', $id)->append(['create_time_text'])->order('create_time desc')->select();
+        $info             = MatchmakerUserModel::get($id);
+        $info['age']      = Fun::getAgeByBirth($info['birthday']);
+        $info['sex_text'] = Constant::SEX[$info['sex']];
+
+        return $this->fetch('', ['list' => $list, 'id' => $id, 'info' => $info]);
+    }
+
+    /**
+     * 跟进提交
+     */
+    public function followPost()
+    {
+        $data = $this->request->param();
+        if (empty($data['user_id'])) {
+            $this->error('数据异常,请刷新重试');
+        }
+        if (empty($data['content'])) {
+            $this->error('请输入内容');
+        }
+
+        $data['create_time'] = time();
+        MatchmakerUserFollowModel::create($data);
+
+        $this->success('操作成功');
+    }
+
+    /**
+     * 匹配
+     */
+    public function match()
+    {
+        $id   = $this->request->param('id');
+        $type = $this->request->param('type', 0);
+        if (empty($id)) {
+            $this->error('该用户不存在');
+        }
+        $user = MatchmakerUserModel::get($id);
+        if (empty($user)) {
+            $this->error('该用户不存在');
+        }
+
+        if ($type == 0) {
+            //自有库
+            $list = MatchmakerUserModel::where('matchmaker_id', $this->matchmaker->id)
+                ->where('id', '<>', $id)
+                ->where('sex', '<>', $user['sex'] == 1 ? 2 : 1)
+                ->append(['sex_text'])
+                ->select();
+        } elseif ($type == 1) {
+            //其他红娘库
+            $list = MatchmakerUserModel::with('matchmaker')
+                ->where('matchmaker_id', '<>', $this->matchmaker->id)
+                ->where('sex', '<>', $user['sex'] == 1 ? 2 : 1)
+                ->append(['sex_text'])
+                ->select();
+        } else {
+            //系统库
+            $list = UserModel::where('user_type', 2)
+                ->where('user_status', 1)
+                ->where('sex', '=', $user['sex'] == 1 ? 2 : 1)
+                ->append(['sex_text'])
+                ->select();
+        }
+
+
+        $mating = MatchmakerUserMatingModel::where('user_id', $id)->find();
+        $res    = $this->_orderMatchUser($list->toArray(), $mating);
+
+        return $this->fetch('', [
+            'list'         => json_encode($res),
+            'type'         => $type,
+            'user'         => $user,
+            'id'           => $id,
+            'mating'       => $mating,
+            'tinyint'      => json_encode(Constant::TINYINT),
+            'cond_tinyint' => json_encode(Constant::COND_TINYINT),
+        ]);
+    }
+
+    private function _file_name($ext)
+    {
+        //生成随机文件名
+        //定义一个包含大小写字母数字的字符串
+        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+        //把字符串分割成数组
+        $newchars = str_split($chars);
+        //打乱数组
+        shuffle($newchars);
+        //从数组中随机取出15个字符
+        $chars_key = array_rand($newchars, 15);
+        //把取出的字符重新组成字符串
+        $fnstr = '';
+        for ($i = 0; $i < 15; $i++) {
+            $fnstr .= $newchars[$chars_key[$i]];
+        }
+        //输出文件名并做MD5加密
+        return md5($fnstr . microtime(true) * 1000) . '.' . $ext;
+    }
+
+    private function _base64_image_content($base64_image_content, $file_path)
+    {
+        //匹配出图片的格式
+        if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)) {
+            if (file_put_contents($file_path, base64_decode(str_replace($result[1], '', $base64_image_content)))) {
+                return true;
+            } else {
+                return false;
+            }
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * 排序
+     */
+    private function _orderMatchUser($list, $mating)
+    {
+        //匹配
+        foreach ($list as $k => $v) {
+            $match_arr   = [];
+            $match_count = 0;
+
+            //年龄匹配
+            $age = Fun::getAgeByBirth($v['birthday']);
+            if (empty($mating['min_age']) && empty($mating['max_age'])) {
+                $match_arr[] = 'age';
+                $match_count++;
+            } elseif (empty($mating['min_age'])) {
+                if ($age <= $mating['max_age']) {
+                    $match_arr[] = 'age';
+                    $match_count++;
+                }
+            } elseif (empty($mating['max_age'])) {
+                if ($age >= $mating['min_age']) {
+                    $match_arr[] = 'age';
+                    $match_count++;
+                }
+            } elseif ($age >= $mating['min_age'] && $age <= $mating['max_age']) {
+                $match_arr[] = 'age';
+                $match_count++;
+            }
+
+            //身高
+            if (empty($mating['min_high']) && empty($mating['max_high'])) {
+                $match_arr[] = 'high';
+                $match_count++;
+            } elseif (empty($mating['min_high'])) {
+                if ($v['high'] <= $mating['max_high']) {
+                    $match_arr[] = 'high';
+                    $match_count++;
+                }
+            } elseif (empty($mating['max_high'])) {
+                if ($v['high'] >= $mating['min_high']) {
+                    $match_arr[] = 'high';
+                    $match_count++;
+                }
+            } elseif ($v['high'] >= $mating['min_high'] && $v['high'] <= $mating['max_high']) {
+                $match_arr[] = 'high';
+                $match_count++;
+            }
+
+            //体重
+            if (empty($mating['min_weight']) && empty($mating['max_weight'])) {
+                $match_arr[] = 'weight';
+                $match_count++;
+            } elseif (empty($mating['min_weight'])) {
+                if ($v['weight'] <= $mating['max_weight']) {
+                    $match_arr[] = 'weight';
+                    $match_count++;
+                }
+            } elseif (empty($mating['max_weight'])) {
+                if ($v['weight'] >= $mating['min_weight']) {
+                    $match_arr[] = 'weight';
+                    $match_count++;
+                }
+            } elseif ($v['weight'] >= $mating['min_weight'] && $v['weight'] <= $mating['max_weight']) {
+                $match_arr[] = 'weight';
+                $match_count++;
+            }
+
+            //籍贯 ['晋江籍','非晋江籍','无要求']
+            if ($mating['native'] == '无要求') {
+                $match_arr[] = 'native';
+                $match_count++;
+            } elseif ($mating['native'] == '晋江籍') {
+                if (strpos($v['native'], '晋江') !== false) {
+                    $match_arr[] = 'native';
+                    $match_count++;
+                }
+            } else {
+                if (strpos($v['native'], '晋江') === false) {
+                    $match_arr[] = 'native';
+                    $match_count++;
+                }
+            }
+
+            //学历 ['本科以下','本科','硕士','博士','无要求']
+            if ($mating['education'] == '无要求' || $mating['education'] == '本科以下') {
+                $match_arr[] = 'education';
+                $match_count++;
+            } elseif ($mating['education'] == '本科') {
+                if (in_array($v['education'], ['本科', '硕士', '博士'])) {
+                    $match_arr[] = 'education';
+                    $match_count++;
+                }
+            } elseif ($mating['education'] == '硕士') {
+                if (in_array($v['education'], ['硕士', '博士'])) {
+                    $match_arr[] = 'education';
+                    $match_count++;
+                }
+            } elseif ($mating['education'] == '博士') {
+                if ($v['education'] == '博士') {
+                    $match_arr[] = 'education';
+                    $match_count++;
+                }
+            }
+
+            //年收入 ['不限', '5万以下', '5-10万', '10-20万', '20-30万', '30-50万', '50-100万', '100万以上']
+            if ($mating['income'] == '不限' || $mating['income'] == '5万以下') {
+                $match_arr[] = 'income';
+                $match_count++;
+            } elseif ($mating['income'] == '5-10万') {
+                if (in_array($v['income'], ['5-10万', '10-20万', '20-30万', '30-50万', '50-100万', '100万以上'])) {
+                    $match_arr[] = 'income';
+                    $match_count++;
+                }
+            } elseif ($mating['income'] == '10-20万') {
+                if (in_array($v['income'], ['10-20万', '20-30万', '30-50万', '50-100万', '100万以上'])) {
+                    $match_arr[] = 'income';
+                    $match_count++;
+                }
+            } elseif ($mating['income'] == '20-30万') {
+                if (in_array($v['income'], ['20-30万', '30-50万', '50-100万', '100万以上'])) {
+                    $match_arr[] = 'income';
+                    $match_count++;
+                }
+            } elseif ($mating['income'] == '30-50万') {
+                if (in_array($v['income'], ['30-50万', '50-100万', '100万以上'])) {
+                    $match_arr[] = 'income';
+                    $match_count++;
+                }
+            } elseif ($mating['income'] == '50-100万') {
+                if (in_array($v['income'], ['50-100万', '100万以上'])) {
+                    $match_arr[] = 'income';
+                    $match_count++;
+                }
+            } elseif ($mating['income'] == '100万以上') {
+                if (in_array($v['income'], ['100万以上'])) {
+                    $match_arr[] = 'income';
+                    $match_count++;
+                }
+            }
+
+            //是否有房 ['不限', '是', '否']
+            if ($mating['have_house'] == 1) {
+                if ($v['have_house'] == 1) {
+                    $match_arr[] = 'have_house';
+                    $match_count++;
+                }
+            } else {
+                $match_arr[] = 'have_house';
+                $match_count++;
+            }
+
+            //是否有车 ['不限', '是', '否']
+            if ($mating['have_car'] == 1) {
+                if ($v['have_car'] == 1) {
+                    $match_arr[] = 'have_car';
+                    $match_count++;
+                }
+            } else {
+                $match_arr[] = 'have_car';
+                $match_count++;
+            }
+
+            //是否婚后愿意与父母同住 ['不限', '是', '否']
+            if ($mating['with_parent_live'] == 2) {
+                if ($v['with_parent_live'] == 2) {
+                    $match_arr[] = 'with_parent_live';
+                    $match_count++;
+                }
+            } else {
+                $match_arr[] = 'with_parent_live';
+                $match_count++;
+            }
+
+            //是否吸烟 ['不吸,很反感', '不吸烟,但不反感', '社交时偶尔吸烟','烟不离手']
+            if ($mating['smoke'] == '烟不离手' || $mating['smoke'] == '' || $mating['smoke'] == '不吸烟,但不反感') {
+                $match_arr[] = 'smoke';
+                $match_count++;
+            } elseif ($mating['smoke'] == '社交时偶尔吸烟') {
+                if (in_array($v['smoke'], ['社交时偶尔吸烟', '不吸烟,但不反感', '不吸,很反感'])) {
+                    $match_arr[] = 'smoke';
+                    $match_count++;
+                }
+            } elseif ($mating['smoke'] == '不吸,很反感') {
+                if (in_array($v['smoke'], ['不吸,很反感', '不吸烟,但不反感'])) {
+                    $match_arr[] = 'smoke';
+                    $match_count++;
+                }
+            }
+
+            //是否喝酒 ['不喝酒', '社交需要喝', '兴致时小酌', '酒不离口']
+            if ($mating['drink'] == '酒不离口' || $mating['drink'] == '') {
+                $match_arr[] = 'drink';
+                $match_count++;
+            } elseif ($mating['drink'] == '兴致时小酌' || $mating['drink'] == '社交需要喝') {
+                if ($v['drink'] == '兴致时小酌' || $v['drink'] == '社交需要喝') {
+                    $match_arr[] = 'drink';
+                    $match_count++;
+                }
+            } elseif ($mating['drink'] == '不喝酒') {
+                if ($v['drink'] == '不喝酒') {
+                    $match_arr[] = 'drink';
+                    $match_count++;
+                }
+            }
+
+            $list[$k]['age']         = $age;
+            $list[$k]['match_arr']   = $match_arr;
+            $list[$k]['match_count'] = $match_count;
+        }
+
+        //排序
+        usort($list, function ($a, $b) {
+            if ($a['match_count'] < $b['match_count']) {
+                return 1;
+            } elseif ($a['match_count'] > $b['match_count']) {
+                return -1;
+            } else {
+                return 0;
+            }
+        });
+
+        //获取前10
+        if (count($list) > 10) {
+            return array_slice($list, 0, 10);
+        } else {
+            return $list;
+        }
+    }
+}

+ 19 - 0
app/matchmaker/model/MatchmakerModel.php

@@ -0,0 +1,19 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 老猫 <thinkcmf@126.com>
+// +----------------------------------------------------------------------
+namespace app\matchmaker\model;
+
+use think\Model;
+
+class MatchmakerModel extends Model
+{
+
+
+}

+ 21 - 0
app/matchmaker/model/MatchmakerUserFollowModel.php

@@ -0,0 +1,21 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 老猫 <thinkcmf@126.com>
+// +----------------------------------------------------------------------
+namespace app\matchmaker\model;
+
+use think\Model;
+
+class MatchmakerUserFollowModel extends Model
+{
+    public function getCreateTimeTextAttr($value, $data)
+    {
+        return date('Y-m-d H:i:s', $data['create_time']);
+    }
+}

+ 19 - 0
app/matchmaker/model/MatchmakerUserMatingModel.php

@@ -0,0 +1,19 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 老猫 <thinkcmf@126.com>
+// +----------------------------------------------------------------------
+namespace app\matchmaker\model;
+
+use think\Model;
+
+class MatchmakerUserMatingModel extends Model
+{
+
+
+}

+ 31 - 0
app/matchmaker/model/MatchmakerUserModel.php

@@ -0,0 +1,31 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 老猫 <thinkcmf@126.com>
+// +----------------------------------------------------------------------
+namespace app\matchmaker\model;
+
+use think\Model;
+
+class MatchmakerUserModel extends Model
+{
+    protected $type = [
+        'family' => 'array',
+    ];
+
+    public function matchmaker()
+    {
+        return $this->hasOne(MatchmakerModel::class,'id','matchmaker_id');
+    }
+
+    public function getSexTextAttr($value, $data)
+    {
+        $sex = ['保密', '男', '女'];
+        return $sex[$data['sex']];
+    }
+}

+ 0 - 2
data/runtime/.gitignore

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

+ 81 - 0
public/themes/admin_simpleboot3/matchmaker/admin_matchmaker/add.html

@@ -0,0 +1,81 @@
+<include file="public@header"/>
+<style type="text/css">
+    .pic-list li{
+        margin-bottom:5px;
+    }
+</style>
+</head>
+<body>
+<div class="wrap js-check-wrap">
+    <ul class="nav nav-tabs">
+        <li><a href="{:url('AdminMatchmaker/index')}">红娘管理</a></li>
+        <li class="active"><a href="javascript:;">添加红娘</a></li>
+    </ul>
+    <form action="{:url('AdminMatchmaker/addPost')}" method="post" class="form-horizontal js-ajax-form margin-top-20">
+        <div class="row">
+            <div class="col-md-9">
+                <table class="table table-bordered">
+                    <tr>
+                        <th>姓名<span class="form-required">*</span></th>
+                        <td>
+                            <input class="form-control" type="text" name="post[name]"
+                                   id="name" required value="" placeholder="请输入姓名"/>
+                        </td>
+                    </tr>
+                    <tr>
+                        <th>手机号<span class="form-required">*</span></th>
+                        <td>
+                            <input class="form-control" type="text" name="post[mobile]"
+                                   id="mobile" required value="" placeholder="请输入手机号"/>
+                        </td>
+                    </tr>
+                    <tr>
+                        <th>密码<span class="form-required">*</span></th>
+                        <td>
+                            <input class="form-control" type="text" name="post[password]"
+                                   id="password" required value="" placeholder="请输入密码"/>
+                        </td>
+                    </tr>
+                </table>
+                <div class="form-group">
+                    <div class="col-sm-offset-2 col-sm-10">
+                        <button type="submit" class="btn btn-primary js-ajax-submit">{:lang('ADD')}</button>
+                        <a class="btn btn-default" href="{:url('AdminMatchmaker/index')}">{:lang('BACK')}</a>
+                    </div>
+                </div>
+            </div>
+            <div class="col-md-3">
+                <table class="table table-bordered">
+                    <tr>
+                        <th><b>主图</b></th>
+                    </tr>
+                    <tr>
+                        <td>
+                            <div style="text-align: center;">
+                                <input type="hidden" name="post[avatar]" id="thumbnail" value="">
+                                <a href="javascript:uploadOneImage('图片上传','#thumbnail');">
+                                    <img src="__TMPL__/public/assets/images/default-thumbnail.png"
+                                         id="thumbnail-preview"
+                                         width="135" style="cursor: pointer"/>
+                                </a>
+                                <input type="button" class="btn btn-sm btn-cancel-thumbnail" value="取消图片">
+                            </div>
+                        </td>
+                    </tr>
+                </table>
+            </div>
+        </div>
+    </form>
+</div>
+<script type="text/javascript" src="__STATIC__/js/admin.js"></script>
+<script type="text/javascript">
+    $(function () {
+        $('.btn-cancel-thumbnail').click(function () {
+            $('#thumbnail-preview').attr('src', '__TMPL__/public/assets/images/default-thumbnail.png');
+            $('#thumbnail').val('');
+        });
+
+    });
+</script>
+</body>
+</html>

+ 90 - 0
public/themes/admin_simpleboot3/matchmaker/admin_matchmaker/edit.html

@@ -0,0 +1,90 @@
+<include file="public@header"/>
+<style type="text/css">
+    .pic-list li{
+        margin-bottom:5px;
+    }
+</style>
+</head>
+<body>
+<div class="wrap js-check-wrap">
+    <ul class="nav nav-tabs">
+        <li><a href="{:url('AdminMatchmaker/index')}">红娘管理</a></li>
+        <li><a href="{:url('AdminMatchmaker/add')}">添加红娘</a></li>
+        <li class="active"><a href="javascript:void(0)">编辑红娘</a></li>
+    </ul>
+    <form action="{:url('AdminMatchmaker/editPost')}" method="post" class="form-horizontal js-ajax-form margin-top-20">
+        <input type="hidden" name="post[id]" value="{$post.id}">
+        <div class="row">
+            <div class="col-md-9">
+                <table class="table table-bordered">
+                    <tr>
+                        <th>姓名<span class="form-required">*</span></th>
+                        <td>
+                            <input class="form-control" type="text" name="post[name]"
+                                   id="name" required value="{$post.name}" placeholder="请输入姓名"/>
+                        </td>
+                    </tr>
+                    <tr>
+                        <th>手机号<span class="form-required">*</span></th>
+                        <td>
+                            <input class="form-control" type="text" name="post[mobile]"
+                                   id="mobile" required value="{$post.mobile}" placeholder="请输入手机号"/>
+                        </td>
+                    </tr>
+                    <tr>
+                        <th>密码<span class="form-required">*</span></th>
+                        <td>
+                            <input class="form-control" type="text" name="post[password]"
+                                   id="password" required value="{$post.password}" placeholder="请输入密码"/>
+                        </td>
+                    </tr>
+                </table>
+                <div class="form-group">
+                    <div class="col-sm-offset-2 col-sm-10">
+                        <button type="submit" class="btn btn-primary js-ajax-submit">{:lang('EDIT')}</button>
+                        <a class="btn btn-default" href="{:url('AdminMatchmaker/index')}">{:lang('BACK')}</a>
+                    </div>
+                </div>
+            </div>
+            <div class="col-md-3">
+                <table class="table table-bordered">
+                    <tr>
+                        <th><b>主图</b></th>
+                    </tr>
+                    <tr>
+                        <td>
+                            <div style="text-align: center;">
+                                <input type="hidden" name="post[avatar]" id="thumbnail"
+                                       value="{$post.avatar|default=''}">
+                                <a href="javascript:uploadOneImage('图片上传','#thumbnail');">
+                                    <if condition="empty($post.avatar)">
+                                        <img src="__TMPL__/public/assets/images/default-thumbnail.png"
+                                             id="thumbnail-preview"
+                                             width="135" style="cursor: pointer"/>
+                                        <else/>
+                                        <img src="{:cmf_get_image_preview_url($post.avatar)}"
+                                             id="thumbnail-preview"
+                                             width="135" style="cursor: pointer"/>
+                                    </if>
+                                </a>
+                                <input type="button" class="btn btn-sm btn-cancel-thumbnail" value="取消图片">
+                            </div>
+                        </td>
+                    </tr>
+                </table>
+            </div>
+        </div>
+    </form>
+</div>
+<script type="text/javascript" src="__STATIC__/js/admin.js"></script>
+<script type="text/javascript">
+    $(function () {
+        $('.btn-cancel-thumbnail').click(function () {
+            $('#thumbnail-preview').attr('src', '__TMPL__/public/assets/images/default-thumbnail.png');
+            $('#thumbnail').val('');
+        });
+
+    });
+</script>
+</body>
+</html>

+ 53 - 0
public/themes/admin_simpleboot3/matchmaker/admin_matchmaker/index.html

@@ -0,0 +1,53 @@
+<include file="public@header"/>
+</head>
+<body>
+<div class="wrap js-check-wrap">
+    <ul class="nav nav-tabs">
+        <li class="active"><a href="javascript:;">所有红娘</a></li>
+        <li><a href="{:url('AdminMatchmaker/add')}">添加红娘</a></li>
+    </ul>
+    <form class="js-ajax-form" action="" method="post">
+        <table class="table table-hover table-bordered table-list">
+            <thead>
+            <tr>
+                <th width="50">ID</th>
+                <th>姓名</th>
+                <th width="160">头像</th>
+                <th width="160">手机号</th>
+                <th width="250">操作</th>
+            </tr>
+            </thead>
+            <foreach name="list" item="vo">
+                <tr>
+                    <td><b>{$vo.id}</b></td>
+                    <td>{$vo.name}</td>
+                    <td>
+                        <notempty name="vo.avatar">
+                            <a href="javascript:parent.imagePreviewDialog('{:cmf_get_image_preview_url($vo.avatar)}');">
+                                <i class="fa fa-photo fa-fw"></i>
+                            </a>
+                            <else/>
+                            <i class="fa fa-close fa-fw"></i>
+                        </notempty>
+                    </td>
+                    <td>{$vo.mobile}</td>
+                    <td>
+                        <a class="btn btn-xs btn-primary" href="{:url('AdminMatchmaker/edit',array('id'=>$vo['id']))}">{:lang('EDIT')}</a>
+                        <a class="btn btn-xs btn-danger js-ajax-delete" href="{:url('AdminMatchmaker/delete',array('id'=>$vo['id']))}">{:lang('DELETE')}</a>
+                    </td>
+                </tr>
+            </foreach>
+        </table>
+        <ul class="pagination">{$page|default=''}</ul>
+    </form>
+</div>
+<script src="__STATIC__/js/admin.js"></script>
+<script>
+
+    function reloadPage(win) {
+        win.location.reload();
+    }
+
+</script>
+</body>
+</html>

+ 68 - 0
public/themes/admin_simpleboot3/matchmaker/admin_matchmaker_user/index.html

@@ -0,0 +1,68 @@
+<include file="public@header"/>
+</head>
+<body>
+<div class="wrap">
+    <ul class="nav nav-tabs">
+        <li class="active"><a>红娘简历库</a></li>
+    </ul>
+    <form class="well form-inline margin-top-20" method="post" action="{:url('matchmaker/adminMatchmakerUser/index')}">
+        真实姓名:
+        <input class="form-control" type="text" name="realname" style="width: 200px;" value="{:input('request.realname')}"
+               placeholder="请输入真实姓名">
+        手机号:
+        <input class="form-control" type="text" name="mobile" style="width: 200px;" value="{:input('request.mobile')}"
+               placeholder="请输入手机号">
+        <input type="submit" class="btn btn-primary" value="搜索"/>
+        <a class="btn btn-danger" href="{:url('matchmaker/adminMatchmakerUser/index')}">清空</a>
+    </form>
+    <form method="post" class="js-ajax-form">
+        <table class="table table-hover table-bordered">
+            <thead>
+            <tr>
+                <th>ID</th>
+                <th>真实姓名</th>
+                <th>电话号码</th>
+                <th>所属红娘</th>
+                <th>性别</th>
+                <th>生日</th>
+                <th>身高CM</th>
+                <th>体重KG</th>
+                <th>{:lang('ACTIONS')}</th>
+            </tr>
+            </thead>
+            <tbody>
+            <foreach name="list" item="vo">
+                <tr>
+                    <td>{$vo.id}</td>
+                    <td>{$vo['realname']}</td>
+                    <td>{$vo['mobile']}</td>
+                    <td>{$vo['matchmaker']['name']}</td>
+                    <td>{$vo['sex'] == 1 ? '男' : '女'}</td>
+                    <td>{:date('Y-m-d',$vo['birthday'])}</td>
+                    <td>{$vo['high'] == 0 ? '未知' : $vo['high']}</td>
+                    <td>{$vo['weight'] == 0 ? '未知' : $vo['high']}</td>
+                    <td>
+                        <a class="btn btn-xs btn-primary" href="javascript:detail({$vo.id})">详情</a>
+                    </td>
+                </tr>
+            </foreach>
+            </tbody>
+        </table>
+        <div class="pagination">
+            {$page}
+            <li class="page-item"><span>共{$total}条</span></li>
+        </div>
+    </form>
+</div>
+<script src="__STATIC__/js/admin.js"></script>
+<script>
+    function reloadPage(win) {
+        win.location.reload();
+    }
+
+    function detail(id) {
+        parent.openIframeLayer("/matchmaker/admin_matchmaker_user/show/id/"+id+".html",'详情',{});
+    }
+</script>
+</body>
+</html>

+ 163 - 0
public/themes/admin_simpleboot3/matchmaker/admin_matchmaker_user/show.html

@@ -0,0 +1,163 @@
+<include file="public@header"/>
+<style>
+    .input-text{width:100%;padding:6px 14px;line-height: 1.42857143;color:#555;min-height:32px;}
+    .text-area{white-space: pre;word-wrap: break-word;}
+</style>
+</head>
+<body>
+<div class="row">
+    <div class="col-md-offset-2 col-md-8">
+        <div class="tab-content" style="margin-top:30px;">
+            <form action="{:url('addPost')}" class="js-ajax-form" method="post">
+                <div class="panel panel-default">
+                    <div class="panel-heading">基本资料</div>
+                    <div class="panel-body">
+                        <div class="form-horizontal">
+                            <div class="form-group">
+                                <label class="control-label col-md-2">真实姓名</label>
+                                <div class="col-md-4">
+                                    <div class="input-text">{$info.realname}</div>
+                                </div>
+                                <label class="control-label col-md-2">电话号码</label>
+                                <div class="col-md-4">
+                                    <div class="input-text">{$info.mobile}</div>
+                                </div>
+                                <label class="control-label col-md-2">性别</label>
+                                <div class="col-md-4">
+                                    <div class="input-text">
+                                        <switch name="info.sex">
+                                            <case value="0">未填写</case>
+                                            <case value="1">男</case>
+                                            <case value="2">女</case>
+                                        </switch>
+                                    </div>
+                                </div>
+                                <label class="control-label col-md-2">生日</label>
+                                <div class="col-md-4">
+                                    <div class="input-text">{:date('Y-m-d',$info['birthday'])}</div>
+                                </div>
+                                <label class="control-label col-md-2">身高</label>
+                                <div class="col-md-4">
+                                    <div class='input-group date'>
+                                        <div class="input-text">{$info['high'] ? $info['high'].'CM' : '保密'}</div>
+                                    </div>
+                                </div>
+                                <label class="control-label col-md-2">体重</label>
+                                <div class="col-md-4">
+                                    <div class="input-text">{$info['weight'] ? $info['weight'].'KG' : '保密'}</div>
+                                </div>
+                                <label class="control-label col-md-2">婚姻状况</label>
+                                <div class="col-md-4">
+                                    <div class="input-text">{$info.marry}</div>
+                                </div>
+                                <label class="control-label col-md-2">学历</label>
+                                <div class="col-md-4">
+                                    <div class="input-text">{$info.education}</div>
+                                </div>
+                                <label class="control-label col-md-2">年收入</label>
+                                <div class="col-md-4">
+                                    <div class="input-text">{$info.income}</div>
+                                </div>
+                                <label class="control-label col-md-2">工作单位</label>
+                                <div class="col-md-4">
+                                    <div class="input-text">{$info.company}</div>
+                                </div>
+                                <label class="control-label col-md-2">职务</label>
+                                <div class="col-md-4">
+                                    <div class="input-text">{$info.job}</div>
+                                </div>
+                                <label class="control-label col-md-2">家庭成员</label>
+                                <div class="col-md-4">
+                                    <div class="input-text">{$info.family_text}</div>
+                                </div>
+                                <label class="control-label col-md-2">籍贯</label>
+                                <div class="col-md-4">
+                                    <div class="input-text">{$info.native}</div>
+                                </div>
+                                <label class="control-label col-md-2">民族</label>
+                                <div class="col-md-4">
+                                    <div class="input-text">{$info.nation}</div>
+                                </div>
+                                <label class="col-md-12">兴趣爱好</label>
+                                <div class="col-md-10 col-md-offset-2">
+                                    <div class="input-text text-area">{$info.hobby}</div>
+                                </div>
+
+                                <label class="col-md-12">头像</label>
+                                <div class="col-md-10 col-md-offset-2">
+                                    <notempty name="info.avatar">
+                                        <img src="{$info.avatar}" style="max-width:100%;">
+                                    </notempty>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="panel panel-default">
+                    <div class="panel-heading">工作生活</div>
+                    <div class="panel-body">
+                        <div class="form-horizontal">
+                            <div class="form-group">
+                                <label class="col-md-2">是否有房</label>
+                                <div class="col-md-4">
+                                    <div class="input-text">{$info.have_house}</div>
+                                </div>
+                                <label class="col-md-2">是否有车</label>
+                                <div class="col-md-4">
+                                    <div class="input-text">{$info.have_car}</div>
+                                </div>
+                                <label class="col-md-2">是否吸烟</label>
+                                <div class="col-md-4">
+                                    <div class="input-text">{$info.smoke}</div>
+                                </div>
+                                <label class="col-md-2">是否喝酒</label>
+                                <div class="col-md-4">
+                                    <div class="input-text">{$info.drink}</div>
+                                </div>
+                                <label class="col-md-2">婚后是否愿意与父母同住</label>
+                                <div class="col-md-4">
+                                    <div class="input-text">{$info.with_parent_live}</div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="panel panel-default">
+                    <div class="panel-heading">择偶要求</div>
+                    <div class="panel-body">
+                        <div class="form-horizontal">
+                            <div class="form-group">
+                                <label class="control-label col-md-2">年龄</label>
+                                <div class="col-md-4">
+                                    <div class='input-group'>
+                                        <div class="input-text">{$mating['min_age'] ? $mating['min_age'].'岁' : '不限'} - {$mating['max_age'] ? $mating['max_age'].'岁' : '不限'}</div>
+                                    </div>
+                                </div>
+                                <label class="control-label col-md-2">身高</label>
+                                <div class="col-md-4">
+                                    <div class='input-group'>
+                                        <div class="input-text">{$mating['min_high'] ? $mating['min_high'].'CM' : '不限'} - {$mating['max_high'] ? $mating['max_high'].'CM' : '不限'}</div>
+                                    </div>
+                                </div>
+                                <label class="control-label col-md-2">体重</label>
+                                <div class="col-md-4">
+                                    <div class="input-text">{$mating['min_weight'] ? $mating['min_weight'].'KG' : '不限'} - {$mating['max_weight'] ? $mating['max_weight'].'KG' : '不限'}</div>
+                                </div>
+                                <label class="control-label col-md-2">籍贯</label>
+                                <div class="col-md-4">
+                                    <div class="input-text">{$mating.native}</div>
+                                </div>
+                                <label class="control-label col-md-2">学历</label>
+                                <div class="col-md-4">
+                                    <div class="input-text">{$mating.education}</div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </form>
+        </div>
+    </div>
+</div>
+</body>
+</html>

+ 0 - 1
public/themes/simpleboot3/love/my/index.html

@@ -151,7 +151,6 @@
                 uploadAvatar(file) {
                     let self = this;
                     $.post("{:url('avatarUpload')}",{file:file.content,name:file.file.name},function(json){
-                        console.log(json);
                         if (json.code) {
                             self.user.avatar = json.data;
                             self.$forceUpdate();

+ 167 - 0
public/themes/simpleboot3/matchmaker/index/index.html

@@ -0,0 +1,167 @@
+<extend name="public/base"/>
+<block name="css">
+    <style>
+        .add {width:50px;height:50px;line-height:50px;background:#FF589B;border-radius:50%;position:fixed;bottom:70px;right:20px;color:white;text-align:center;}
+        .lw-list .list-item{padding:5px 10px;margin-top:10px;background:white;}
+        .lw-list .list-content {display:flex;align-items:center;}
+        .lw-list .list-content .list-left {width:50px;height:50px;}
+        .lw-list .list-content .list-left img {width:50px;height:50px;}
+        .lw-list .list-content .list-right {margin-left:20px;}
+        .lw-list .list-content .list-right .name {color:black;height:30px;line-height:30px;}
+        .lw-list .list-content .list-right .name .mobile {font-size:14px;color:var(--blue);}
+        .lw-list .list-content .list-right .desc {color:#666;font-size:14px;height:20px;line-height:20px;}
+        .lw-list .list-tool {border-top:1px solid #f8f9fb;margin-top:5px;display:flex;justify-content:flex-end;align-items:center;padding-top:5px;}
+        .lw-list .list-tool .tool-btn {margin-left:5px;font-size:14px;border:1px solid #ccc;padding:5px 10px;border-radius:20px;color:#555;}
+        .lw-list .list-tool .tool-btn.delete {border-color:var(--pink);color:var(--pink);}
+        .lw-list .list-tool .tool-btn.match {border-color:var(--blue);color:var(--blue);}
+    </style>
+</block>
+<block name="body">
+    <van-nav-bar class="bg-pink">
+        <template #title>
+            <span style="color:white;">信息库</span>
+        </template>
+    </van-nav-bar>
+
+    <form action="/">
+        <van-search
+                v-model="form.keyword"
+                placeholder="请输入姓名或电话"
+                @search="onRefresh"
+        ></van-search>
+    </form>
+
+    <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
+        <van-list
+                v-model="loading"
+                :finished="finished"
+                finished-text="没有更多了"
+                @load="onLoad"
+        >
+            <div class="lw-list">
+                <div class="list-item" v-for="item in list">
+                    <div class="list-content">
+                        <div class="list-left">
+                            <img :src="dealAvatar(item.avatar,item.sex)" alt="">
+                        </div>
+                        <div class="list-right">
+                            <div class="name">{{item.realname}} <span class="mobile" v-if="item.mobile">({{item.mobile}})</span></div>
+                            <div class="desc">{{item.sex_text}} • {{item.age}}岁 • {{dealHigh(item.high)}}</div>
+                        </div>
+                    </div>
+                    <div class="list-tool">
+                        <div class="tool-btn" @click="toInfo(item.id)">基本资料</div>
+                        <div class="tool-btn" @click="toMating(item.id)">择偶要求</div>
+                        <div class="tool-btn match" @click="toMatch(item.id)">智能匹配</div>
+                        <div class="tool-btn" @click="toFollow(item.id)">跟进</div>
+                        <div class="tool-btn delete">删除</div>
+                    </div>
+                </div>
+            </div>
+        </van-list>
+    </van-pull-refresh>
+
+    <div class="add" @click="toAdd">添加</div>
+
+    <van-tabbar v-model="active" active-color="#FF589B" :before-change="tabbarChange">
+        <van-tabbar-item>
+            <span>信息库</span>
+            <template #icon>
+                <van-icon name="home-o" size="25px"></van-icon>
+            </template>
+        </van-tabbar-item>
+        <van-tabbar-item url="{:url('matchmaker/my/index')}">
+            <span>个人中心</span>
+            <template #icon>
+                <van-icon name="contact" size="25px"></van-icon>
+            </template>
+        </van-tabbar-item>
+    </van-tabbar>
+</block>
+<block name="script">
+    <script>
+        new Vue({
+            el: '#app',
+            data() {
+                return {
+                    active: 0,
+                    form: {
+                        keyword: '',
+                    },
+
+                    list: [],
+                    page: 1,
+                    loading: false,
+                    finished: false,
+                    refreshing: false,
+                };
+            },
+            methods: {
+                tabbarChange() {
+                    return false;
+                },
+                dealAvatar(avatar,sex) {
+                    if (avatar == '') {
+                        return '__TMPL__/public/assets/images/matchmaker/avatar' + sex + '.png'
+                    } else {
+                        return avatar;
+                    }
+                },
+                dealHigh(high) {
+                    return high ? high + 'CM' : '保密';
+                },
+                toAdd() {
+                    location.href = '{:url("matchmaker/user/infoAdd")}';
+                },
+                toInfo(id) {
+                    location.href = '{:url("matchmaker/user/infoEdit")}?id=' + id;
+                },
+                toMating(id) {
+                    location.href = '{:url("matchmaker/user/matingEdit")}?id=' + id;
+                },
+                toMatch(id) {
+                    location.href = '{:url("matchmaker/user/match")}?id=' + id;
+                },
+                toFollow(id) {
+                    location.href = '{:url("matchmaker/user/follow")}?id=' + id;
+                },
+                onLoad() {
+                    //参数
+                    let self = this;
+                    let param = this.form;
+                    param.page = this.page;
+                    this.page++;
+
+                    $.post("{:url('listUser')}", this.form, function (json) {
+                        //下拉刷新
+                        if (self.refreshing) {
+                            self.refreshing = false;
+                        }
+
+                        // 加载状态结束
+                        self.loading = false;
+
+                        if (json.data.length == 0) {
+                            // 数据全部加载完成
+                            self.finished = true;
+                        } else {
+                            // 增加数据
+                            for (let i = 0; i < json.data.length; i++) {
+                                self.list.push(json.data[i]);
+                            }
+                        }
+                    }, 'json');
+                },
+                onRefresh() {
+                    // 清空列表数据
+                    this.list = [];
+                    this.page = 1;
+                    this.loading = true;
+                    this.finished = false;
+
+                    this.onLoad();
+                },
+            },
+        });
+    </script>
+</block>

+ 160 - 0
public/themes/simpleboot3/matchmaker/login/index.html

@@ -0,0 +1,160 @@
+<extend name="public/base"/>
+<block name="css">
+    <style>
+        .content{
+            height: 100vh;
+            background: url("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F202005%2F10%2F20200510005139_JR8fL.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1714820289&t=e835cde99a094cbd98f9c318f25160ec") no-repeat;
+            background-size: 100% 100%;
+        }
+        .loginBox{
+            position: absolute;
+            top: 50%;
+            left: 50%;
+            transform: translate(-50%,-60%);
+            width: 90%;
+            background-color: #fff;
+            border-radius: 10px;
+            padding: 30px;
+            box-sizing: border-box;
+        }
+        h3{
+            color: rgb(247,120,172);
+            font-size: 20px;
+            letter-spacing: 5px;
+            margin-bottom: 20px;
+        }
+        .ipt{
+            height: 43px;
+            display: flex;
+            justify-content: flex-start;
+            align-items: center;
+            margin-bottom: 10px;
+            background-color: #f5f5f5;
+            border-radius: 5px;
+            padding-left: 5px;
+        }
+        .ipt input{
+            margin-left: 10px;
+            font-size: 14px;
+            width:80%;
+            border:none;
+            background:none;
+        }
+        .forgetPwd{
+            font-size: 13px;
+            color: #b5b5b5;
+            text-align: end;
+            padding:0 5px;
+            display: flex;
+            justify-content: space-between;
+        }
+        .tip{
+            text-align: center;
+            font-size: 14px;
+            position: fixed;
+            bottom: 25px;
+            left: 50%;
+            transform: translate(-50%,-50%);
+            color: #f4f4f4;
+        }
+        .van-button--normal {
+            font-size:16px;
+        }
+        .tipbox {
+            text-align: center;
+            margin-top: 50px;
+        }
+
+        .otherUser {
+            margin-top: 15px;
+            display: flex;
+            justify-content: center;
+        }
+
+        .txt {
+            font-size: 14px;
+            color: #cbcbcb;
+        }
+
+        .otherUser .uni-icons {
+            margin-left: 10px;
+        }
+    </style>
+</block>
+<block name="body">
+    <div class="content">
+        <div class="loginBox">
+            <h3>登录</h3>
+            <div class="inputBox">
+                <div class="ipt">
+                    <van-icon name="phone-circle-o" color="#f778ac" size="25"></van-icon>
+                    <input type="text" required v-model="form.mobile" placeholder="请输入手机号"/>
+                </div>
+                <div class="ipt">
+                    <van-icon name="eye-o" color="#f778ac" size="25"></van-icon>
+                    <input type="password" required v-model="form.password" placeholder="请输入密码"/>
+                </div>
+                <div class="forgetPwd">
+                    <span @click="forget">忘记密码</span>
+                </div>
+                <div class="btn-submit" style="margin-top: 16px;">
+                    <van-button @click="login" round block color="linear-gradient(to right,rgb(255, 170, 127),rgb(247,120,172))">登录</van-button>
+                </div>
+            </div>
+            <!--<div class="tipbox">
+                <div class="txt">
+                    —— 其他账号登录 ——
+                </div>
+                <div class="otherUser">
+
+                </div>
+            </div>-->
+        </div>
+
+        <div class="tip">
+            晋江妇联红娘系统
+        </div>
+    </div>
+</block>
+<block name="script">
+    <script>
+        new Vue({
+            el: '#app',
+            data() {
+                return {
+                    form: {
+                        mobile: '',
+                        password: '',
+                    },
+                };
+            },
+            methods: {
+                forget() {
+                    vant.Toast({
+                        message: '请联系晋江妇联重置密码',
+                        position: 'top',
+                    });
+                },
+                login() {
+                    if (this.form.mobile === '') {
+                        vant.Toast('请输入手机号');
+                        return false;
+                    }
+                    if (this.form.password === '') {
+                        vant.Toast('请输入密码');
+                        return false;
+                    }
+
+                    $.post("{:url('login')}", this.form, function (json) {
+                        if (json.code === 0) {
+                            vant.Toast(json.msg);
+                            return false;
+                        }
+
+                        location.href = "{:url('index/index')}";
+                    }, 'json');
+                },
+            },
+        });
+    </script>
+</block>

+ 113 - 0
public/themes/simpleboot3/matchmaker/my/index.html

@@ -0,0 +1,113 @@
+<extend name="public/base"/>
+<block name="css">
+    <style>
+        .bg-box{
+            height: 200px;
+            background: url("__TMPL__/public/assets/images/matchmaker/myBG.png");
+            background-size: cover;
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+        }
+        .bg-box h1{
+            margin-top: 12px;
+            font-size: 20px;
+            color: #333;
+        }
+        ul li{
+            background-color:#fff;
+            display:flex;
+            align-items:center;
+            height:48px;
+            margin-bottom:2px;
+        }
+        ul li h2{
+            margin-left: 12px;
+            font-size: 16px;
+            font-weight: normal;
+        }
+        ul li img{
+            width: 35px;
+            margin-left: 22px;
+        }
+    </style>
+</block>
+<block name="body">
+    <van-nav-bar class="bg-pink">
+        <template #title>
+            <span style="color:white;">个人中心</span>
+        </template>
+    </van-nav-bar>
+
+    <div class="bg-box">
+        <img style="margin-top:32px;width: 94px;height: 94px;object-fit: cover;border-radius:50%;" :src="head_image" alt="">
+        <h1>{{matchmaker.name}}</h1>
+        <p class="mobile" v-if="matchmaker.mobile">{{matchmaker.mobile}}</p>
+    </div>
+    <ul>
+        <li @click="toIndex">
+            <img src="__TMPL__/public/assets/images/matchmaker/myIcon.png" alt="">
+            <h2>我的信息库</h2>
+            <van-icon style="margin-left: 200px" name="arrow" />
+        </li>
+        <li @click="toInfo">
+            <img src="__TMPL__/public/assets/images/matchmaker/myIcon3.png" alt="">
+            <h2>我的资料</h2>
+            <van-icon style="margin-left: 216px" name="arrow" />
+        </li>
+        <li @click="callPhone('0595-88150395')">
+            <img src="__TMPL__/public/assets/images/matchmaker/myIcon2.png" alt="">
+            <h2>联系我们</h2>
+            <van-icon style="margin-left: 216px" name="arrow" />
+        </li>
+    </ul>
+
+    <van-tabbar v-model="active" active-color="#FF589B" :before-change="tabbarChange">
+        <van-tabbar-item url="{:url('matchmaker/index/index')}">
+            <span>信息库</span>
+            <template #icon>
+                <van-icon name="home-o" size="25px"></van-icon>
+            </template>
+        </van-tabbar-item>
+        <van-tabbar-item>
+            <span>个人中心</span>
+            <template #icon>
+                <van-icon name="contact" size="25px"></van-icon>
+            </template>
+        </van-tabbar-item>
+    </van-tabbar>
+</block>
+<block name="script">
+    <script>
+        new Vue({
+            el: '#app',
+            data() {
+                return {
+                    active: 1,
+                    keyword: '',
+                    matchmaker: {$matchmaker},
+                };
+            },
+            methods: {
+                tabbarChange() {
+                    return false;
+                },
+                callPhone(phone) {
+                    window.location.href = `tel://${phone}`;
+                },
+                toIndex() {
+                    location.href = '{:url("matchmaker/index/index")}';
+                },
+                toInfo() {
+                    location.href = '{:url("matchmaker/my/info")}';
+                },
+            },
+            computed: {
+                head_image() {
+                    return this.matchmaker.avatar ? this.matchmaker.avatar : '__TMPL__/public/assets/images/matchmaker/avatar2.png';
+                }
+            },
+
+        });
+    </script>
+</block>

+ 101 - 0
public/themes/simpleboot3/matchmaker/my/info.html

@@ -0,0 +1,101 @@
+<extend name="public/base"/>
+<block name="css">
+    <style>
+        .van-nav-bar--fixed {z-index:100;}
+        .van-nav-bar .van-icon,.van-nav-bar__text {color:white;}
+        .van-step--horizontal .van-step__title {font-size:16px;}
+        .van-step--horizontal .van-step__icon {font-size:16px;}
+        .van-step__circle {width:10px;height:10px;}
+
+        .van-row {width:100%;}
+        .btn_search_item{background:#f2f6ff;display:inline-block;border-radius:5px;line-height:35px;height:35px;text-align:center;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;position:relative;font-size:13px;width:100%;color:#666;margin-bottom:10px;}
+        .btn_search_item.active{color:var(--pink);background:#fff7fa;}
+        .btn_search_icon{position:absolute;bottom:-3px;right:-3px;font-size:30px;}
+        .van-uploader__input-wrapper {width:100%;}
+    </style>
+</block>
+<block name="body">
+    <!--头部-->
+    <van-nav-bar
+            class="bg-pink"
+            left-text="返回"
+            left-arrow
+            @click-left="onBack"
+            fixed="true"
+    >
+        <template #title>
+            <span style="color:white;">我的资料</span>
+        </template>
+    </van-nav-bar>
+    <div style="width:100%;height:46px;"></div>
+
+    <!--头图-->
+    <van-uploader :max-count="1" :after-read="uploadHead" style="padding:20px 0;width:100%;">
+        <van-image width="30%" style="display:block;margin:0 auto;" :src="head_image"></van-image>
+        <div style="text-align:center;font-size:14px;color:#999;">点击上传头像</div>
+    </van-uploader>
+    <!--增空-->
+    <van-field
+            v-model="form.name"
+            label="真实姓名"
+            placeholder="请输入真实姓名"
+            required
+    ></van-field>
+    <van-field
+            v-model="form.mobile"
+            label="电话"
+            placeholder="请输入电话号码"
+            required
+    ></van-field>
+
+    <div style="padding:16px;">
+        <van-button block class="bg-pink" @click="onSubmit">提交</van-button>
+    </div>
+</block>
+<block name="script">
+    <script>
+        new Vue({
+            el: '#app',
+            data() {
+                return {
+                    form: {$matchmaker},
+                };
+            },
+            methods: {
+                onBack() {
+                    history.back();
+                },
+                onSubmit() {
+                    if (this.form.realname == '') {
+                        this.$toast('请输入真实姓名');
+                        return false;
+                    }
+                    if (this.form.mobile == '') {
+                        this.$toast('请选择性别');
+                        return false;
+                    }
+
+                    $.post("{:url('infoPost')}", this.form, function (json) {
+                        location.href = "{:url('index')}";
+                    }, 'json');
+                },
+                uploadHead(file) {
+                    let self = this;
+                    $.post("{:url('imageUpload')}",{file:file.content,name:file.file.name},function(json){
+                        if (json.code) {
+                            self.form.avatar = json.data.avatar;
+                            self.$forceUpdate();
+                        } else {
+                            self.$toast(json.msg);
+                        }
+                    },'json')
+                },
+            },
+            computed: {
+                head_image() {
+                    return this.form.avatar ? this.form.avatar : '__TMPL__/public/assets/images/matchmaker/avatar2.png';
+                }
+            },
+        });
+    </script>
+</block>

+ 14 - 0
public/themes/simpleboot3/matchmaker/public/base.html

@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html lang="zh-cn">
+<head>
+    <include file="public/meta_header"/>
+    <block name="meta"></block>
+    <block name="css"></block>
+</head>
+<body class="{$page_class|default=''}">
+<div id="app">
+    <block name="body"></block>
+</div>
+<block name="script"></block>
+</body>
+</html>

+ 13 - 0
public/themes/simpleboot3/matchmaker/public/meta_header.html

@@ -0,0 +1,13 @@
+<meta charset="utf-8">
+<title>红娘管理系统</title>
+<link rel="shortcut icon" href="__TMPL__/public/assets/images/favicon.ico" />
+<meta name="renderer" content="webkit">
+<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<meta name="apple-mobile-web-app-status-bar-style" content="black" />
+<link rel="stylesheet" href="__TMPL__/public/assets/css/vant.css">
+<link rel="stylesheet" href="__TMPL__/public/assets/css/icon.css">
+<link rel="stylesheet" href="__TMPL__/public/assets/css/style.css">
+<script src="__TMPL__/public/assets/js/vue.min.js"></script>
+<script src="__TMPL__/public/assets/js/vant.min.js"></script>
+<script src="__TMPL__/public/assets/js/jquery-1.10.2.min.js"></script>

+ 116 - 0
public/themes/simpleboot3/matchmaker/user/follow.html

@@ -0,0 +1,116 @@
+<extend name="public/base"/>
+<block name="css">
+    <style>
+        .van-nav-bar--fixed {z-index:100;}
+        .van-nav-bar .van-icon,.van-nav-bar__text {color:white;}
+        .van-step--horizontal .van-step__title {font-size:16px;}
+        .van-step--horizontal .van-step__icon {font-size:16px;}
+        .van-step__circle {width:10px;height:10px;}
+
+        .lw-list .list-item{padding:5px 10px;background:white;}
+        .lw-list .list-content {display:flex;align-items:center;}
+        .lw-list .list-content .list-left {width:50px;height:50px;}
+        .lw-list .list-content .list-left img {width:50px;height:50px;}
+        .lw-list .list-content .list-right {margin-left:20px;}
+        .lw-list .list-content .list-right .name {color:black;height:30px;line-height:30px;}
+        .lw-list .list-content .list-right .name .mobile {font-size:14px;color:var(--blue);}
+        .lw-list .list-content .list-right .desc {color:#666;font-size:14px;height:20px;line-height:20px;}
+        .lw-list .list-tool {border-top:1px solid #f8f9fb;margin-top:5px;display:flex;justify-content:flex-end;align-items:center;padding-top:5px;}
+        .lw-list .list-tool .tool-btn {margin-left:5px;font-size:14px;border:1px solid #ccc;padding:5px 10px;border-radius:20px;color:#555;}
+        .lw-list .list-tool .tool-btn.delete {border-color:var(--pink);color:var(--pink);}
+        .lw-list .list-tool .tool-btn.match {border-color:var(--blue);color:var(--blue);}
+    </style>
+</block>
+<block name="body">
+    <!--头部-->
+    <van-nav-bar
+            class="bg-pink"
+            fixed="true"
+            left-text="返回"
+            @click-left="onBack"
+            left-arrow
+    >
+        <template #title>
+            <span style="color:white;">跟进记录</span>
+        </template>
+    </van-nav-bar>
+    <div style="width:100%;height:46px;"></div>
+
+    <div class="lw-list">
+        <div class="list-item">
+            <div class="list-content">
+                <div class="list-left">
+                    <img :src="dealAvatar(info.avatar,info.sex)" alt="">
+                </div>
+                <div class="list-right">
+                    <div class="name">{{info.realname}} <span class="mobile" v-if="info.mobile">({{info.mobile}})</span></div>
+                    <div class="desc">{{info.sex_text}} • {{info.age}}岁 • {{dealHigh(info.high)}}</div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <van-field
+            v-model="form.content"
+            rows="3"
+            autosize
+            label="跟进内容"
+            type="textarea"
+            placeholder="请输入跟进内容"
+            show-word-limit
+    ></van-field>
+    <div style="padding:16px;">
+        <van-button block class="bg-pink" @click="onSubmit">提交</van-button>
+    </div>
+
+    <van-empty description="暂无跟进记录" v-if="list.length == 0"></van-empty>
+
+    <van-steps direction="vertical" :active="0">
+        <van-step v-for="item in list">
+            <h3>{{item.content}}</h3>
+            <p>{{item.create_time_text}}</p>
+        </van-step>
+    </van-steps>
+</block>
+<block name="script">
+    <script>
+        new Vue({
+            el: '#app',
+            data() {
+                return {
+                    info:{$info},
+                    form:{
+                        user_id: {$id},
+                        content: '',
+                    },
+                    list: {$list},
+                };
+            },
+            methods: {
+                onBack() {
+                    location.href = "{:url('index/index')}";
+                },
+                onSubmit() {
+                    $.post("{:url('followPost')}", this.form, function (json) {
+                        if (json.code == 0) {
+                            vant.Toast(json.msg);
+                            return false;
+                        }
+                        location.reload();
+                    }, 'json');
+                },
+                dealAvatar(avatar,sex) {
+                    if (avatar == '') {
+                        return '__TMPL__/public/assets/images/matchmaker/avatar' + sex + '.png'
+                    } else {
+                        return avatar;
+                    }
+                },
+                dealHigh(high) {
+                    return high ? high + 'CM' : '保密';
+                },
+            },
+            computed: {
+            }
+        });
+    </script>
+</block>

+ 540 - 0
public/themes/simpleboot3/matchmaker/user/info_add.html

@@ -0,0 +1,540 @@
+<extend name="public/base"/>
+<block name="css">
+    <style>
+        .van-nav-bar--fixed {z-index:100;}
+        .van-nav-bar .van-icon,.van-nav-bar__text {color:white;}
+        .van-step--horizontal .van-step__title {font-size:16px;}
+        .van-step--horizontal .van-step__icon {font-size:16px;}
+        .van-step__circle {width:10px;height:10px;}
+
+        .van-row {width:100%;}
+        .btn_search_item{background:#f2f6ff;display:inline-block;border-radius:5px;line-height:35px;height:35px;text-align:center;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;position:relative;font-size:13px;width:100%;color:#666;margin-bottom:10px;}
+        .btn_search_item.active{color:var(--pink);background:#fff7fa;}
+        .btn_search_icon{position:absolute;bottom:-3px;right:-3px;font-size:30px;}
+        .van-uploader__input-wrapper {width:100%;}
+    </style>
+</block>
+<block name="body">
+    <!--头部-->
+    <van-nav-bar
+            class="bg-pink"
+            left-text="返回"
+            left-arrow
+            @click-left="onBack"
+            fixed="true"
+    >
+        <template #title>
+            <span style="color:white;">基本资料(1/2)</span>
+        </template>
+    </van-nav-bar>
+    <div style="width:100%;height:46px;"></div>
+
+    <van-steps :active="0">
+        <van-step>基本资料</van-step>
+        <van-step>择偶要求</van-step>
+    </van-steps>
+
+
+    <!--头图-->
+    <van-uploader :max-count="1" :after-read="uploadHead" style="padding:20px 0;width:100%;">
+        <van-image width="30%" style="display:block;margin:0 auto;" :src="head_image"></van-image>
+        <div style="text-align:center;font-size:14px;color:#999;">点击上传头像</div>
+    </van-uploader>
+    <!--增空-->
+    <van-field
+            v-model="form.realname"
+            label="真实姓名"
+            placeholder="请输入真实姓名"
+            required
+    ></van-field>
+    <van-field
+            v-model="form.mobile"
+            label="电话"
+            placeholder="请输入电话号码"
+    ></van-field>
+    <van-field name="radio" label="单选框" required>
+        <template #input>
+            <van-radio-group v-model="form.sex" direction="horizontal">
+                <van-radio :name="1">男</van-radio>
+                <van-radio :name="2">女</van-radio>
+            </van-radio-group>
+        </template>
+    </van-field>
+
+    <!--生日-->
+    <van-field
+            required
+            readonly
+            clickable
+            :value="form.birthday"
+            label="生日"
+            placeholder="点击选择生日"
+            @click="showBirthday = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showBirthday">
+        <van-datetime-picker
+                title="生日"
+                :value="new Date(form.birthday)"
+                type="date"
+                :min-date="minDate"
+                @confirm="onBirthdayConfirm"
+                @cancel="showBirthday = false"
+        ></van-datetime-picker>
+    </van-popup>
+
+    <!--身高-->
+    <van-field
+            required
+            readonly
+            clickable
+            :value="form_high"
+            label="身高"
+            placeholder="请选择身高(CM)"
+            @click="showHigh = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showHigh">
+        <van-picker
+                title="身高"
+                show-toolbar
+                :columns="high"
+                @confirm="onHighConfirm"
+                @cancel="showHigh = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--体重-->
+    <van-field
+            required
+            readonly
+            clickable
+            :value="form_weight"
+            label="体重"
+            placeholder="请选择体重(KG)"
+            @click="showWeight = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showWeight">
+        <van-picker
+                title="体重"
+                show-toolbar
+                :columns="weight"
+                @confirm="onWeightConfirm"
+                @cancel="showWeight = false"
+        ></van-picker>
+    </van-popup>
+
+    <van-field
+            required
+            readonly
+            clickable
+            :value="form.marry"
+            label="婚姻状况"
+            placeholder="请选择婚姻状况"
+            @click="showMarry = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showMarry">
+        <van-picker
+                title="婚姻状况"
+                show-toolbar
+                :columns="marry"
+                @confirm="onMarryConfirm"
+                @cancel="showMarry = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--学历-->
+    <van-field
+            required
+            readonly
+            clickable
+            :value="form.education"
+            label="学历"
+            placeholder="点击选择学历"
+            @click="showEducation = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showEducation">
+        <van-picker
+                title="学历"
+                show-toolbar
+                :columns="education"
+                @confirm="onEducationConfirm"
+                @cancel="showEducation = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--年收入-->
+    <van-field
+            required
+            readonly
+            clickable
+            :value="form.income"
+            label="年收入"
+            placeholder="点击选择年收入"
+            @click="showIncome = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showIncome">
+        <van-picker
+                title="年收入"
+                show-toolbar
+                :columns="income"
+                @confirm="onIncomeConfirm"
+                @cancel="showIncome = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--工作单位和职务-->
+    <van-field
+            v-model="form.company"
+            label="工作单位"
+            placeholder="请输入工作单位"
+    ></van-field>
+    <van-field
+            v-model="form.job"
+            label="职务"
+            placeholder="请输入职务"
+    ></van-field>
+
+    <!--家庭成员-->
+    <van-field name="form.family" label="家庭成员">
+        <template #input>
+            <van-row :gutter="10">
+                <van-col span="8" v-for="(item) in family">
+                    <div :class="{btn_search_item:true,active: in_array(item,form.family)}"
+                         @click="selectFamily(item)">
+                        {{item}}
+                        <van-icon v-if="in_array(item,form.family)"
+                                  class="iconfont icon-gouxuan-youxiajiaogouxuan btn_search_icon text-pink"></van-icon>
+                    </div>
+                </van-col>
+            </van-row>
+        </template>
+    </van-field>
+
+    <!--籍贯-->
+    <van-field
+            v-model="form.native"
+            label="籍贯"
+            placeholder="请输入籍贯"
+    ></van-field>
+
+    <!--民族-->
+    <van-field
+            readonly
+            clickable
+            :value="form.nation"
+            label="民族"
+            placeholder="点击选择民族"
+            @click="showNation = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showNation">
+        <van-picker
+                title="民族"
+                show-toolbar
+                :columns="nation"
+                @confirm="onNationConfirm"
+                @cancel="showNation = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--兴趣爱好-->
+    <van-field
+            v-model="form.hobby"
+            autosize
+            label="兴趣爱好"
+            type="textarea"
+            placeholder="请输入兴趣爱好"
+    ></van-field>
+
+    <h3 class="fz16 mb10 pt20 plr12">工作生活</h3>
+
+    <!--房车,与父母同住-->
+    <van-field
+            readonly
+            clickable
+            :value="tinyint[form.have_house]"
+            label="是否有房"
+            placeholder="点击选择是否有房"
+            @click="showHaveHouse = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showHaveHouse">
+        <van-picker
+                title="是否有房"
+                show-toolbar
+                :columns="tinyint"
+                @confirm="onHaveHouseConfirm"
+                @cancel="showHaveHouse = false"
+        ></van-picker>
+    </van-popup>
+    <van-field
+            readonly
+            clickable
+            :value="tinyint[form.have_car]"
+            label="是否有车"
+            placeholder="点击选择是否有车"
+            @click="showHaveCar = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showHaveCar">
+        <van-picker
+                title="是否有车"
+                show-toolbar
+                :columns="tinyint"
+                @confirm="onHaveCarConfirm"
+                @cancel="showHaveCar = false"
+        ></van-picker>
+    </van-popup>
+    <van-field
+            readonly
+            clickable
+            :value="tinyint[form.with_parent_live]"
+            label="婚后是否愿意与父母同住"
+            placeholder="点击选择"
+            @click="showWithParentLive = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showWithParentLive">
+        <van-picker
+                title="婚后是否愿意与父母同住"
+                show-toolbar
+                :columns="tinyint"
+                @confirm="onWithParentLiveConfirm"
+                @cancel="showWithParentLive = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--是否吸烟-->
+    <van-field
+            readonly
+            clickable
+            :value="form.smoke"
+            label="是否吸烟"
+            placeholder="点击选择是否吸烟"
+            @click="showSmoke = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showSmoke">
+        <van-picker
+                title="是否吸烟"
+                show-toolbar
+                :columns="smoke"
+                @confirm="onSmokeConfirm"
+                @cancel="showSmoke = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--是否喝酒-->
+    <van-field
+            readonly
+            clickable
+            :value="form.drink"
+            label="是否喝酒"
+            placeholder="点击选择是否喝酒"
+            @click="showDrink = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showDrink">
+        <van-picker
+                title="是否喝酒"
+                show-toolbar
+                :columns="drink"
+                @confirm="onDrinkConfirm"
+                @cancel="showDrink = false"
+        ></van-picker>
+    </van-popup>
+
+    <div style="padding:16px;">
+        <van-button block class="bg-pink" @click="onSubmit">下一步</van-button>
+    </div>
+</block>
+<block name="script">
+    <script>
+        new Vue({
+            el: '#app',
+            data() {
+                return {
+                    form: {
+                        realname: '',
+                        sex: 0,
+                        mobile: '',
+                        avatar: '',
+                        birthday: '',
+                        high: 0,
+                        weight: 0,
+                        education: '',
+                        company: '',
+                        job: '',
+                        income: '',
+                        nation: '',
+                        hobby: '',
+                        smoke: '',
+                        drink: '',
+                        family: [],
+                        native: '',
+                        have_house: 0,
+                        have_car: 0,
+                        with_parent_live: 0,
+                        marry: '',
+                    },
+                    showSex: false,
+                    sex: {$sex},
+                    showBirthday: false,
+                    minDate: new Date(1970, 0, 1),
+                    showHigh: false,
+                    high: {$high},
+                    showWeight: false,
+                    weight: {$weight},
+                    showMarry: false,
+                    marry: {$marry},
+                    showEducation: false,
+                    education: {$education},
+                    showIncome: false,
+                    income: {$income},
+                    showNation: false,
+                    nation: {$nation},
+                    showTalentLevel: false,
+                    showSmoke: false,
+                    smoke: {$smoke},
+                    showDrink: false,
+                    drink: {$drink},
+                    family: {$family},
+                    showHaveHouse: false,
+                    showHaveCar: false,
+                    showWithParentLive: false,
+                    tinyint: {$tinyint},
+                };
+            },
+            methods: {
+                in_array(search,array){
+                    for(var i in array){
+                        if(array[i] == search){
+                            return true;
+                        }
+                    }
+                    return false;
+                },
+                onBack() {
+                    history.back();
+                },
+                onSubmit() {
+                    if (this.form.realname == '') {
+                        this.$toast('请输入真实姓名');
+                        return false;
+                    }
+                    if (this.form.sex == 0) {
+                        this.$toast('请选择性别');
+                        return false;
+                    }
+                    if (this.form.birthday == '') {
+                        this.$toast('请选择正确的生日');
+                        return false;
+                    }
+                    if (this.form.marry == '') {
+                        this.$toast('请选择婚姻状况');
+                        return false;
+                    }
+                    if (this.form.education == '') {
+                        this.$toast('请选择学历');
+                        return false;
+                    }
+                    if (this.form.income == '') {
+                        this.$toast('请选择年收入');
+                        return false;
+                    }
+
+                    $.post("{:url('infoAddPost')}", this.form, function (json) {
+                        location.href = "{:url('matingAdd')}?id=" + json.data.id;
+                    }, 'json');
+                },
+                onBirthdayConfirm(date) {
+                    let year = date.getFullYear();
+                    let month = date.getMonth() + 1;
+                    if (month < 10) {
+                        month = "0" + month;
+                    }
+                    let day = date.getDate();
+                    if (day < 10) {
+                        day = "0" + day;
+                    }
+                    this.form.birthday = `${year}-${month}-${day}`;
+                    this.showBirthday = false;
+                },
+                onHighConfirm(value) {
+                    this.form.high = value == '保密' ? 0 : value;
+                    this.showHigh = false;
+                },
+                onWeightConfirm(value) {
+                    this.form.weight = value == '保密' ? 0 : value;
+                    this.showWeight = false;
+                },
+                onMarryConfirm(value) {
+                    this.form.marry = value;
+                    this.showMarry = false;
+                },
+                onEducationConfirm(value) {
+                    this.form.education = value;
+                    this.showEducation = false;
+                },
+                onIncomeConfirm(value) {
+                    this.form.income = value;
+                    this.showIncome = false;
+                },
+                onNationConfirm(value) {
+                    this.form.nation = value;
+                    this.showNation = false;
+                },
+                onHaveHouseConfirm(value,index) {
+                    this.form.have_house = index;
+                    this.showHaveHouse = false;
+                },
+                onHaveCarConfirm(value,index) {
+                    this.form.have_car = index;
+                    this.showHaveCar = false;
+                },
+                onWithParentLiveConfirm(value,index) {
+                    this.form.with_parent_live = index;
+                    this.showWithParentLive = false;
+                },
+                onSmokeConfirm(value) {
+                    this.form.smoke = value;
+                    this.showSmoke = false;
+                },
+                onDrinkConfirm(value) {
+                    this.form.drink = value;
+                    this.showDrink = false;
+                },
+                removeByVal(arrylist , val) {
+                    for(var i = 0; i < arrylist .length; i++) {
+                        if(arrylist[i] == val) {
+                            arrylist .splice(i, 1);
+                            break;
+                        }
+                    }
+                },
+                selectFamily(value) {
+                    if (this.in_array(value,this.form.family)) {
+                        this.removeByVal(this.form.family,value);
+                    } else {
+                        this.form.family.push(value);
+                    }
+                },
+                uploadHead(file) {
+                    let self = this;
+                    $.post("{:url('imageUpload')}",{file:file.content,name:file.file.name},function(json){
+                        if (json.code) {
+                            self.form.avatar = json.data.avatar;
+                            self.$forceUpdate();
+                        } else {
+                            self.$toast(json.msg);
+                        }
+                    },'json')
+                },
+            },
+            computed: {
+                form_high() {
+                    return this.form.high ? this.form.high + 'CM' : '保密';
+                },
+                form_weight() {
+                    return this.form.weight ? this.form.weight + 'KG' : '保密';
+                },
+                head_image() {
+                    return this.form.avatar ? this.form.avatar : '__TMPL__/public/assets/images/matchmaker/avatar2.png';
+                }
+            },
+        });
+    </script>
+</block>

+ 512 - 0
public/themes/simpleboot3/matchmaker/user/info_edit.html

@@ -0,0 +1,512 @@
+<extend name="public/base"/>
+<block name="css">
+    <style>
+        .van-nav-bar--fixed {z-index:100;}
+        .van-nav-bar .van-icon,.van-nav-bar__text {color:white;}
+        .van-step--horizontal .van-step__title {font-size:16px;}
+        .van-step--horizontal .van-step__icon {font-size:16px;}
+        .van-step__circle {width:10px;height:10px;}
+
+        .van-row {width:100%;}
+        .btn_search_item{background:#f2f6ff;display:inline-block;border-radius:5px;line-height:35px;height:35px;text-align:center;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;position:relative;font-size:13px;width:100%;color:#666;margin-bottom:10px;}
+        .btn_search_item.active{color:var(--pink);background:#fff7fa;}
+        .btn_search_icon{position:absolute;bottom:-3px;right:-3px;font-size:30px;}
+        .van-uploader__input-wrapper {width:100%;}
+    </style>
+</block>
+<block name="body">
+    <!--头部-->
+    <van-nav-bar
+            class="bg-pink"
+            left-text="返回"
+            left-arrow
+            @click-left="onBack"
+            fixed="true"
+    >
+        <template #title>
+            <span style="color:white;">基本资料</span>
+        </template>
+    </van-nav-bar>
+    <div style="width:100%;height:46px;"></div>
+
+    <!--头图-->
+    <van-uploader :max-count="1" :after-read="uploadHead" style="padding:20px 0;width:100%;">
+        <van-image width="30%" style="display:block;margin:0 auto;" :src="head_image"></van-image>
+        <div style="text-align:center;font-size:14px;color:#999;">点击上传头像</div>
+    </van-uploader>
+    <!--增空-->
+    <van-field
+            v-model="form.realname"
+            label="真实姓名"
+            placeholder="请输入真实姓名"
+            required
+    ></van-field>
+    <van-field
+            v-model="form.mobile"
+            label="电话"
+            placeholder="请输入电话号码"
+    ></van-field>
+    <van-field name="radio" label="单选框" required>
+        <template #input>
+            <van-radio-group v-model="form.sex" direction="horizontal">
+                <van-radio :name="1">男</van-radio>
+                <van-radio :name="2">女</van-radio>
+            </van-radio-group>
+        </template>
+    </van-field>
+
+    <!--生日-->
+    <van-field
+            required
+            readonly
+            clickable
+            :value="form.birthday"
+            label="生日"
+            placeholder="点击选择生日"
+            @click="showBirthday = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showBirthday">
+        <van-datetime-picker
+                title="生日"
+                :value="new Date(form.birthday)"
+                type="date"
+                :min-date="minDate"
+                @confirm="onBirthdayConfirm"
+                @cancel="showBirthday = false"
+        ></van-datetime-picker>
+    </van-popup>
+
+    <!--身高-->
+    <van-field
+            required
+            readonly
+            clickable
+            :value="form_high"
+            label="身高"
+            placeholder="请选择身高(CM)"
+            @click="showHigh = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showHigh">
+        <van-picker
+                title="身高"
+                show-toolbar
+                :columns="high"
+                @confirm="onHighConfirm"
+                @cancel="showHigh = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--体重-->
+    <van-field
+            required
+            readonly
+            clickable
+            :value="form_weight"
+            label="体重"
+            placeholder="请选择体重(KG)"
+            @click="showWeight = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showWeight">
+        <van-picker
+                title="体重"
+                show-toolbar
+                :columns="weight"
+                @confirm="onWeightConfirm"
+                @cancel="showWeight = false"
+        ></van-picker>
+    </van-popup>
+
+    <van-field
+            required
+            readonly
+            clickable
+            :value="form.marry"
+            label="婚姻状况"
+            placeholder="请选择婚姻状况"
+            @click="showMarry = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showMarry">
+        <van-picker
+                title="婚姻状况"
+                show-toolbar
+                :columns="marry"
+                @confirm="onMarryConfirm"
+                @cancel="showMarry = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--学历-->
+    <van-field
+            required
+            readonly
+            clickable
+            :value="form.education"
+            label="学历"
+            placeholder="点击选择学历"
+            @click="showEducation = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showEducation">
+        <van-picker
+                title="学历"
+                show-toolbar
+                :columns="education"
+                @confirm="onEducationConfirm"
+                @cancel="showEducation = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--年收入-->
+    <van-field
+            required
+            readonly
+            clickable
+            :value="form.income"
+            label="年收入"
+            placeholder="点击选择年收入"
+            @click="showIncome = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showIncome">
+        <van-picker
+                title="年收入"
+                show-toolbar
+                :columns="income"
+                @confirm="onIncomeConfirm"
+                @cancel="showIncome = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--工作单位和职务-->
+    <van-field
+            v-model="form.company"
+            label="工作单位"
+            placeholder="请输入工作单位"
+    ></van-field>
+    <van-field
+            v-model="form.job"
+            label="职务"
+            placeholder="请输入职务"
+    ></van-field>
+
+    <!--家庭成员-->
+    <van-field name="form.family" label="家庭成员">
+        <template #input>
+            <van-row :gutter="10">
+                <van-col span="8" v-for="(item) in family">
+                    <div :class="{btn_search_item:true,active: in_array(item,form.family)}"
+                         @click="selectFamily(item)">
+                        {{item}}
+                        <van-icon v-if="in_array(item,form.family)"
+                                  class="iconfont icon-gouxuan-youxiajiaogouxuan btn_search_icon text-pink"></van-icon>
+                    </div>
+                </van-col>
+            </van-row>
+        </template>
+    </van-field>
+
+    <!--籍贯-->
+    <van-field
+            v-model="form.native"
+            label="籍贯"
+            placeholder="请输入籍贯"
+    ></van-field>
+
+    <!--民族-->
+    <van-field
+            readonly
+            clickable
+            :value="form.nation"
+            label="民族"
+            placeholder="点击选择民族"
+            @click="showNation = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showNation">
+        <van-picker
+                title="民族"
+                show-toolbar
+                :columns="nation"
+                @confirm="onNationConfirm"
+                @cancel="showNation = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--兴趣爱好-->
+    <van-field
+            v-model="form.hobby"
+            autosize
+            label="兴趣爱好"
+            type="textarea"
+            placeholder="请输入兴趣爱好"
+    ></van-field>
+
+    <h3 class="fz16 mb10 pt20 plr12">工作生活</h3>
+
+    <!--房车,与父母同住-->
+    <van-field
+            readonly
+            clickable
+            :value="tinyint[form.have_house]"
+            label="是否有房"
+            placeholder="点击选择是否有房"
+            @click="showHaveHouse = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showHaveHouse">
+        <van-picker
+                title="是否有房"
+                show-toolbar
+                :columns="tinyint"
+                @confirm="onHaveHouseConfirm"
+                @cancel="showHaveHouse = false"
+        ></van-picker>
+    </van-popup>
+    <van-field
+            readonly
+            clickable
+            :value="tinyint[form.have_car]"
+            label="是否有车"
+            placeholder="点击选择是否有车"
+            @click="showHaveCar = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showHaveCar">
+        <van-picker
+                title="是否有车"
+                show-toolbar
+                :columns="tinyint"
+                @confirm="onHaveCarConfirm"
+                @cancel="showHaveCar = false"
+        ></van-picker>
+    </van-popup>
+    <van-field
+            readonly
+            clickable
+            :value="tinyint[form.with_parent_live]"
+            label="婚后是否愿意与父母同住"
+            placeholder="点击选择"
+            @click="showWithParentLive = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showWithParentLive">
+        <van-picker
+                title="婚后是否愿意与父母同住"
+                show-toolbar
+                :columns="tinyint"
+                @confirm="onWithParentLiveConfirm"
+                @cancel="showWithParentLive = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--是否吸烟-->
+    <van-field
+            readonly
+            clickable
+            :value="form.smoke"
+            label="是否吸烟"
+            placeholder="点击选择是否吸烟"
+            @click="showSmoke = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showSmoke">
+        <van-picker
+                title="是否吸烟"
+                show-toolbar
+                :columns="smoke"
+                @confirm="onSmokeConfirm"
+                @cancel="showSmoke = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--是否喝酒-->
+    <van-field
+            readonly
+            clickable
+            :value="form.drink"
+            label="是否喝酒"
+            placeholder="点击选择是否喝酒"
+            @click="showDrink = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showDrink">
+        <van-picker
+                title="是否喝酒"
+                show-toolbar
+                :columns="drink"
+                @confirm="onDrinkConfirm"
+                @cancel="showDrink = false"
+        ></van-picker>
+    </van-popup>
+
+    <div style="padding:16px;">
+        <van-button block class="bg-pink" @click="onSubmit">提交</van-button>
+    </div>
+</block>
+<block name="script">
+    <script>
+        new Vue({
+            el: '#app',
+            data() {
+                return {
+                    form: {$user},
+                    showSex: false,
+                    sex: {$sex},
+                    showBirthday: false,
+                    minDate: new Date(1970, 0, 1),
+                    showHigh: false,
+                    high: {$high},
+                    showWeight: false,
+                    weight: {$weight},
+                    showMarry: false,
+                    marry: {$marry},
+                    showEducation: false,
+                    education: {$education},
+                    showIncome: false,
+                    income: {$income},
+                    showNation: false,
+                    nation: {$nation},
+                    showTalentLevel: false,
+                    showSmoke: false,
+                    smoke: {$smoke},
+                    showDrink: false,
+                    drink: {$drink},
+                    family: {$family},
+                    showHaveHouse: false,
+                    showHaveCar: false,
+                    showWithParentLive: false,
+                    tinyint: {$tinyint},
+                };
+            },
+            methods: {
+                in_array(search,array){
+                    for(var i in array){
+                        if(array[i] == search){
+                            return true;
+                        }
+                    }
+                    return false;
+                },
+                onBack() {
+                    history.back();
+                },
+                onSubmit() {
+                    if (this.form.realname == '') {
+                        this.$toast('请输入真实姓名');
+                        return false;
+                    }
+                    if (this.form.sex == 0) {
+                        this.$toast('请选择性别');
+                        return false;
+                    }
+                    if (this.form.birthday == '') {
+                        this.$toast('请选择正确的生日');
+                        return false;
+                    }
+                    if (this.form.marry == '') {
+                        this.$toast('请选择婚姻状况');
+                        return false;
+                    }
+                    if (this.form.education == '') {
+                        this.$toast('请选择学历');
+                        return false;
+                    }
+                    if (this.form.income == '') {
+                        this.$toast('请选择年收入');
+                        return false;
+                    }
+
+                    $.post("{:url('infoEditPost')}", this.form, function (json) {
+                        location.href = "{:url('matchmaker/index/index')}";
+                    }, 'json');
+                },
+                onBirthdayConfirm(date) {
+                    let year = date.getFullYear();
+                    let month = date.getMonth() + 1;
+                    if (month < 10) {
+                        month = "0" + month;
+                    }
+                    let day = date.getDate();
+                    if (day < 10) {
+                        day = "0" + day;
+                    }
+                    this.form.birthday = `${year}-${month}-${day}`;
+                    this.showBirthday = false;
+                },
+                onHighConfirm(value) {
+                    this.form.high = value == '保密' ? 0 : value;
+                    this.showHigh = false;
+                },
+                onWeightConfirm(value) {
+                    this.form.weight = value == '保密' ? 0 : value;
+                    this.showWeight = false;
+                },
+                onMarryConfirm(value) {
+                    this.form.marry = value;
+                    this.showMarry = false;
+                },
+                onEducationConfirm(value) {
+                    this.form.education = value;
+                    this.showEducation = false;
+                },
+                onIncomeConfirm(value) {
+                    this.form.income = value;
+                    this.showIncome = false;
+                },
+                onNationConfirm(value) {
+                    this.form.nation = value;
+                    this.showNation = false;
+                },
+                onHaveHouseConfirm(value,index) {
+                    this.form.have_house = index;
+                    this.showHaveHouse = false;
+                },
+                onHaveCarConfirm(value,index) {
+                    this.form.have_car = index;
+                    this.showHaveCar = false;
+                },
+                onWithParentLiveConfirm(value,index) {
+                    this.form.with_parent_live = index;
+                    this.showWithParentLive = false;
+                },
+                onSmokeConfirm(value) {
+                    this.form.smoke = value;
+                    this.showSmoke = false;
+                },
+                onDrinkConfirm(value) {
+                    this.form.drink = value;
+                    this.showDrink = false;
+                },
+                removeByVal(arrylist , val) {
+                    for(var i = 0; i < arrylist .length; i++) {
+                        if(arrylist[i] == val) {
+                            arrylist .splice(i, 1);
+                            break;
+                        }
+                    }
+                },
+                selectFamily(value) {
+                    if (this.in_array(value,this.form.family)) {
+                        this.removeByVal(this.form.family,value);
+                    } else {
+                        this.form.family.push(value);
+                    }
+                },
+                uploadHead(file) {
+                    let self = this;
+                    $.post("{:url('imageUpload')}",{file:file.content,name:file.file.name},function(json){
+                        if (json.code) {
+                            self.form.avatar = json.data.avatar;
+                            self.$forceUpdate();
+                        } else {
+                            self.$toast(json.msg);
+                        }
+                    },'json')
+                },
+            },
+            computed: {
+                form_high() {
+                    return this.form.high ? this.form.high + 'CM' : '保密';
+                },
+                form_weight() {
+                    return this.form.weight ? this.form.weight + 'KG' : '保密';
+                },
+                head_image() {
+                    return this.form.avatar ? this.form.avatar : '__TMPL__/public/assets/images/matchmaker/avatar2.png';
+                }
+            },
+        });
+    </script>
+</block>

+ 236 - 0
public/themes/simpleboot3/matchmaker/user/match.html

@@ -0,0 +1,236 @@
+<extend name="public/base"/>
+<block name="css">
+    <style>
+        .van-nav-bar--fixed {z-index:100;}
+        .van-nav-bar .van-icon,.van-nav-bar__text {color:white;}
+        .van-step--horizontal .van-step__title {font-size:16px;}
+        .van-step--horizontal .van-step__icon {font-size:16px;}
+        .van-step__circle {width:10px;height:10px;}
+
+        .lw-list .list-item{padding:5px 10px;margin-top:10px;background:white;}
+        .lw-list .list-content {display:flex;align-items:center;}
+        .lw-list .list-content .list-left {width:50px;height:50px;}
+        .lw-list .list-content .list-left img {width:50px;height:50px;}
+        .lw-list .list-content .list-right {margin-left:20px;}
+        .lw-list .list-content .list-right .name {color:black;height:30px;line-height:30px;}
+        .lw-list .list-content .list-right .name .mobile {font-size:14px;color:var(--blue);}
+        .lw-list .list-content .list-right .desc {color:#666;font-size:14px;height:20px;line-height:20px;}
+        .lw-list .list-tool {border-top:1px solid #f8f9fb;margin-top:5px;display:flex;justify-content:flex-end;align-items:center;padding-top:5px;}
+        .lw-list .list-tool .tool-btn {margin-left:5px;font-size:14px;border:1px solid #ccc;padding:5px 10px;border-radius:20px;color:#555;}
+        .lw-list .list-tool .tool-btn.delete {border-color:var(--pink);color:var(--pink);}
+        .lw-list .list-tool .tool-btn.match {border-color:var(--blue);color:var(--blue);}
+
+        .show-tips {color:#999;padding:5px 10px;font-size:14px;}
+        .show-tips .match-count {color:var(--pink);font-size:16px;font-weight:bold;}
+        .show-tips .no-match {color:red;}
+        .show-tips .match {color:var(--blue);}
+        .table {width:100%;}
+        .table td {border-bottom:1px solid #eee;height:40px;line-height:20px;padding-left:10px;}
+        .table td.match {background:#99CCFF;}
+        .table td.no-match {background:#FF9999;}
+    </style>
+</block>
+<block name="body">
+    <!--头部-->
+    <van-nav-bar
+            class="bg-pink"
+            fixed="true"
+            left-text="返回"
+            @click-left="onBack"
+            left-arrow
+    >
+        <template #title>
+            <span style="color:white;">跟进记录</span>
+        </template>
+    </van-nav-bar>
+    <div style="width:100%;height:46px;"></div>
+
+    <van-tabs v-model="active" :before-change="onTab">
+        <van-tab title="自有库"></van-tab>
+        <van-tab title="其他媒婆库"></van-tab>
+        <van-tab title="妇联库"></van-tab>
+    </van-tabs>
+
+    <div class="lw-list">
+        <div class="list-item" v-for="item in list">
+            <div class="list-content">
+                <div class="list-left">
+                    <img :src="dealAvatar(item.avatar,item.sex)" alt="">
+                </div>
+                <div class="list-right">
+                    <div class="name">{{item.realname}}
+                        <span v-if="active == 0 && item.mobile">({{item.mobile}})</span>
+                        <span class="mobile" v-if="active == 1">({{item.matchmaker.mobile}}【{{item.matchmaker.name}}】)</span>
+                        <span class="mobile" v-if="active == 2">(0595-88150395【妇联】)</span>
+                    </div>
+                    <div class="desc">匹配{{item.match_count}}项 • {{item.age}}岁 • {{dealHigh(item.high)}}</div>
+                </div>
+            </div>
+            <div class="list-tool">
+                <div class="tool-btn" @click="showInfo(item)">详情</div>
+            </div>
+        </div>
+    </div>
+
+    <van-empty description="暂无匹配记录" v-if="list.length == 0"></van-empty>
+
+    <van-popup v-model="info_show" position="bottom" :style="{ height: '80%' }">
+        <p class="show-tips">说明:共有<span class="match-count">{{info.match_count}}</span>项匹配成功,<span class="match">蓝色表示匹配成功</span>,<span class="no-match">红色表示未匹配成功</span>。</p>
+        <table class="table" border="0" cellspacing="0" cellpadding="0">
+            <tr>
+                <td style="width:20%;"></td>
+                <td style="width:30%;">配对人</td>
+                <td style="width:50%;">要求</td>
+            </tr>
+            <tr>
+                <td>姓名</td>
+                <td>{{info.realname}}</td>
+                <td>{{user.realname}}</td>
+            </tr>
+            <tr>
+                <td>年龄</td>
+                <td :class="isMatch('age')">{{info.age}}岁</td>
+                <td :class="isMatch('age')">{{showMatingRange(mating.min_age,mating.max_age,'岁')}}</td>
+            </tr>
+            <tr>
+                <td>身高</td>
+                <td :class="isMatch('high')">{{info.high}}cm</td>
+                <td :class="isMatch('high')">{{showMatingRange(mating.min_high,mating.max_high,'cm')}}</td>
+            </tr>
+            <tr>
+                <td>体重</td>
+                <td :class="isMatch('weight')">{{info.weight}}KG</td>
+                <td :class="isMatch('weight')">{{showMatingRange(mating.min_weight,mating.max_weight,'KG')}}</td>
+            </tr>
+            <tr>
+                <td>籍贯</td>
+                <td :class="isMatch('native')">{{info.native}}</td>
+                <td :class="isMatch('native')">{{mating.native}}</td>
+            </tr>
+            <tr>
+                <td>学历</td>
+                <td :class="isMatch('education')">{{info.education}}</td>
+                <td :class="isMatch('education')">{{mating.education}}</td>
+            </tr>
+            <tr>
+                <td>年收入</td>
+                <td :class="isMatch('income')">{{info.income}}</td>
+                <td :class="isMatch('income')">{{mating.income}}</td>
+            </tr>
+            <tr>
+                <td>是否有房</td>
+                <td :class="isMatch('have_house')">{{tinyint[info.have_house]}}</td>
+                <td :class="isMatch('have_house')">{{cond_tinyint[mating.have_house]}}</td>
+            </tr>
+            <tr>
+                <td>是否有车</td>
+                <td :class="isMatch('have_car')">{{tinyint[info.have_car]}}</td>
+                <td :class="isMatch('have_car')">{{cond_tinyint[mating.have_car]}}</td>
+            </tr>
+            <tr>
+                <td>婚后是否愿意与父母同住</td>
+                <td :class="isMatch('with_parent_live')">{{tinyint[info.with_parent_live]}}</td>
+                <td :class="isMatch('with_parent_live')">{{cond_tinyint[mating.with_parent_live]}}</td>
+            </tr>
+            <tr>
+                <td>是否吸烟</td>
+                <td :class="isMatch('smoke')">{{info.smoke}}</td>
+                <td :class="isMatch('smoke')">{{mating.smoke}}</td>
+            </tr>
+            <tr>
+                <td>是否喝酒</td>
+                <td :class="isMatch('drink')">{{info.drink}}</td>
+                <td :class="isMatch('drink')">{{mating.drink}}</td>
+            </tr>
+            <tr>
+                <td>婚姻状况</td>
+                <td>{{info.marry}}</td>
+                <td></td>
+            </tr>
+            <tr>
+                <td>工作单位</td>
+                <td>{{info.company}}</td>
+                <td></td>
+            </tr>
+            <tr>
+                <td>职务</td>
+                <td>{{info.job}}</td>
+                <td></td>
+            </tr>
+            <tr>
+                <td>家庭成员</td>
+                <td>{{info.family.join(',')}}</td>
+                <td></td>
+            </tr>
+            <tr>
+                <td>民族</td>
+                <td>{{info.nation}}</td>
+                <td></td>
+            </tr>
+            <tr>
+                <td>兴趣爱好</td>
+                <td>{{info.hobby}}</td>
+                <td></td>
+            </tr>
+        </table>
+    </van-popup>
+</block>
+<block name="script">
+    <script>
+        new Vue({
+            el: '#app',
+            data() {
+                return {
+                    user:{$user},
+                    mating:{$mating},
+                    list: {$list},
+                    active: {$type},
+                    info: {match_arr:[],family:[]},
+                    info_show: false,
+                    tinyint: {$tinyint},
+                    cond_tinyint: {$cond_tinyint},
+                };
+            },
+            methods: {
+                onBack() {
+                    location.href = "{:url('index/index')}";
+                },
+                onTab(index) {
+                    location.href = "{:url('match')}?id={$id}&type=" + index;
+                    return false;
+                },
+                dealAvatar(avatar,sex) {
+                    if (avatar == '') {
+                        return '__TMPL__/public/assets/images/matchmaker/avatar' + sex + '.png'
+                    } else {
+                        return avatar;
+                    }
+                },
+                dealHigh(high) {
+                    return high ? high + 'CM' : '保密';
+                },
+                showInfo(item) {
+                    this.info = item;
+                    this.info_show = true;
+                },
+                showMatingRange(min,max,unit) {
+                    if (min === 0 && max === 0) {
+                        return '不限';
+                    } else if (min === 0) {
+                        return max + unit + '以下';
+                    } else if (max === 0) {
+                        return min + unit + '以上';
+                    } else {
+                        return min + ' - ' + max + unit;
+                    }
+                },
+                isMatch(value) {
+                    const match = this.info.match_arr.includes(value)
+                    return match ? 'match' : 'no-match';
+                }
+            },
+            computed: {
+            }
+        });
+    </script>
+</block>

+ 392 - 0
public/themes/simpleboot3/matchmaker/user/mating_add.html

@@ -0,0 +1,392 @@
+<extend name="public/base"/>
+<block name="css">
+    <style>
+        .van-nav-bar--fixed {z-index:100;}
+        .van-step--horizontal .van-step__title {font-size:16px;}
+        .van-step--horizontal .van-step__icon {font-size:16px;}
+        .van-step__circle {width:10px;height:10px;}
+    </style>
+</block>
+<block name="body">
+    <!--头部-->
+    <van-nav-bar
+            class="bg-pink"
+            fixed="true"
+    >
+        <template #title>
+            <span style="color:white;">择偶要求(2/2)</span>
+        </template>
+    </van-nav-bar>
+    <div style="width:100%;height:46px;"></div>
+
+    <van-steps :active="1">
+        <van-step>基本资料</van-step>
+        <van-step>择偶要求</van-step>
+    </van-steps>
+
+    <!--年龄-->
+    <van-field
+            readonly
+            clickable
+            :value="form_age"
+            label="年龄"
+            placeholder="点击选择年龄"
+            @click="showAge = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showAge">
+        <van-picker
+                title="年龄"
+                show-toolbar
+                :columns="age"
+                @confirm="onMultiPikerConfirm('age',$event)"
+                @cancel="showAge = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--身高-->
+    <van-field
+            readonly
+            clickable
+            :value="form_high"
+            label="身高"
+            placeholder="点击选择身高"
+            @click="showHigh = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showHigh">
+        <van-picker
+                title="身高"
+                show-toolbar
+                :columns="high"
+                @confirm="onMultiPikerConfirm('high',$event)"
+                @cancel="showHigh = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--体重-->
+    <van-field
+            readonly
+            clickable
+            :value="form_weight"
+            label="体重"
+            placeholder="点击选择体重"
+            @click="showWeight = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showWeight">
+        <van-picker
+                title="体重"
+                show-toolbar
+                :columns="weight"
+                @confirm="onMultiPikerConfirm('weight',$event)"
+                @cancel="showWeight = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--籍贯-->
+    <van-field
+            readonly
+            clickable
+            :value="form.native"
+            label="籍贯"
+            placeholder="点击选择籍贯"
+            @click="showNative = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showNative">
+        <van-picker
+                title="籍贯"
+                show-toolbar
+                :columns="native"
+                @confirm="onNativeConfirm"
+                @cancel="showNative = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--学历-->
+    <van-field
+            readonly
+            clickable
+            :value="form.education"
+            label="学历"
+            placeholder="点击选择学历"
+            @click="showEducation = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showEducation">
+        <van-picker
+                title="学历"
+                show-toolbar
+                :columns="education"
+                @confirm="onEducationConfirm"
+                @cancel="showEducation = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--年收入-->
+    <van-field
+            readonly
+            clickable
+            :value="form.income"
+            label="年收入"
+            placeholder="点击选择年收入"
+            @click="showIncome = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showIncome">
+        <van-picker
+                title="年收入"
+                show-toolbar
+                :columns="income"
+                @confirm="onIncomeConfirm"
+                @cancel="showIncome = false"
+        ></van-picker>
+    </van-popup>
+
+    <van-field
+            readonly
+            clickable
+            :value="tinyint[form.have_house]"
+            label="是否有房"
+            placeholder="点击选择是否有房"
+            @click="showHaveHouse = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showHaveHouse">
+        <van-picker
+                title="是否有房"
+                show-toolbar
+                :columns="tinyint"
+                @confirm="onHaveHouseConfirm"
+                @cancel="showHaveHouse = false"
+        ></van-picker>
+    </van-popup>
+    <van-field
+            readonly
+            clickable
+            :value="tinyint[form.have_car]"
+            label="是否有车"
+            placeholder="点击选择是否有车"
+            @click="showHaveCar = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showHaveCar">
+        <van-picker
+                title="是否有车"
+                show-toolbar
+                :columns="tinyint"
+                @confirm="onHaveCarConfirm"
+                @cancel="showHaveCar = false"
+        ></van-picker>
+    </van-popup>
+    <van-field
+            readonly
+            clickable
+            :value="tinyint[form.with_parent_live]"
+            label="婚后是否愿意与父母同住"
+            placeholder="点击选择"
+            @click="showWithParentLive = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showWithParentLive">
+        <van-picker
+                title="婚后是否愿意与父母同住"
+                show-toolbar
+                :columns="tinyint"
+                @confirm="onWithParentLiveConfirm"
+                @cancel="showWithParentLive = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--是否吸烟-->
+    <van-field
+            readonly
+            clickable
+            :value="form.smoke"
+            label="是否吸烟"
+            placeholder="点击选择是否吸烟"
+            @click="showSmoke = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showSmoke">
+        <van-picker
+                title="是否吸烟"
+                show-toolbar
+                :columns="smoke"
+                @confirm="onSmokeConfirm"
+                @cancel="showSmoke = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--是否喝酒-->
+    <van-field
+            readonly
+            clickable
+            :value="form.drink"
+            label="是否喝酒"
+            placeholder="点击选择是否喝酒"
+            @click="showDrink = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showDrink">
+        <van-picker
+                title="是否喝酒"
+                show-toolbar
+                :columns="drink"
+                @confirm="onDrinkConfirm"
+                @cancel="showDrink = false"
+        ></van-picker>
+    </van-popup>
+
+    <div style="padding:16px;">
+        <van-button block class="bg-pink" @click="onSubmit">完成</van-button>
+    </div>
+</block>
+<block name="script">
+    <script>
+        new Vue({
+            el: '#app',
+            data() {
+                return {
+                    form: {$mating},
+                    showAge: false,
+                    showHigh: false,
+                    showWeight: false,
+                    showMarry: false,
+                    showEducation: false,
+                    education: {$education},
+                    showNative: false,
+                    native: {$native},
+                    showIncome: false,
+                    income: {$income},
+                    tinyint: {$tinyint},
+                    showSmoke: false,
+                    smoke: {$smoke},
+                    showDrink: false,
+                    drink: {$drink},
+                    showHaveHouse: false,
+                    showHaveCar: false,
+                    showWithParentLive: false,
+                };
+            },
+            methods: {
+                onSubmit() {
+                    $.post("{:url('matingAddPost')}", this.form, function (json) {
+                        location.href = '{:url("matchmaker/index/index")}';
+                    }, 'json');
+                },
+                onEducationConfirm(value) {
+                    this.form.education = value;
+                    this.showEducation = false;
+                },
+                onNativeConfirm(value) {
+                    this.form.native = value;
+                    this.showNative = false;
+                },
+                onPikerConfirm(key, value) {
+                    let upperKey = key.slice(0, 1).toUpperCase() + key.slice(1)
+                    this.form[key] = value;
+                    this[`show${upperKey}`] = false;
+                },
+                onMultiPikerConfirm(key, value) {
+                    if (value[1] < value[0]) {
+                        this.$toast('第二个值不能比第一个值小');
+                        return false;
+                    }
+                    this.form[`min_${key}`] = value[0] === '不限' ? 0 : value[0];
+                    this.form[`max_${key}`] = value[1] === '不限' ? 0 : value[1];
+                    let upperKey = key.slice(0, 1).toUpperCase() + key.slice(1);
+                    this[`show${upperKey}`] = false;
+                },
+
+                //多列选择器
+                getColumns(min,min_value,max,max_value){
+                    let min_default = this.findKey(min, min_value);
+                    if (min_default === undefined) {
+                        min_default = 0;
+                    }
+                    let max_default = this.findKey(max, max_value);
+                    if (max_default === undefined) {
+                        max_default = 0;
+                    }
+
+                    return [
+                        {
+                            values: min,
+                            default: min_default,
+                        },
+                        {
+                            values: max,
+                            default: max_default,
+                        },
+                    ];
+                },
+
+                //多列选择器值
+                getColumnsValue(min,max,ext) {
+                    if (min === '' || max === '') {
+                        return '';
+                    }
+
+                    if (min === 0 && max === 0) {
+                        return '不限';
+                    }
+
+                    let min_ext = min + ext;
+                    if (min === 0) {
+                        min_ext = '不限';
+                    }
+                    let max_ext = max + ext;
+                    if (max === 0) {
+                        max_ext = '不限';
+                    }
+                    return `${min_ext}-${max_ext}`;
+                },
+
+                //找键
+                findKey(obj, value, compare = (a, b) => a === b) {
+                    return Object.keys(obj).find(k => compare(obj[k], value))
+                },
+                onIncomeConfirm(value) {
+                    this.form.income = value;
+                    this.showIncome = false;
+                },
+                onHaveHouseConfirm(value,index) {
+                    this.form.have_house = index;
+                    this.showHaveHouse = false;
+                },
+                onHaveCarConfirm(value,index) {
+                    this.form.have_car = index;
+                    this.showHaveCar = false;
+                },
+                onWithParentLiveConfirm(value,index) {
+                    this.form.with_parent_live = index;
+                    this.showWithParentLive = false;
+                },
+                onSmokeConfirm(value) {
+                    this.form.smoke = value;
+                    this.showSmoke = false;
+                },
+                onDrinkConfirm(value) {
+                    this.form.drink = value;
+                    this.showDrink = false;
+                },
+            },
+            computed: {
+                //年龄
+                age() {
+                    return this.getColumns({$min_age},this.form.min_age,{$max_age},this.form.max_age);
+                },
+                form_age() {
+                    return this.getColumnsValue(this.form.min_age,this.form.max_age,'岁');
+                },
+
+                //身高
+                high() {
+                    return this.getColumns({$min_high},this.form.min_high,{$max_high},this.form.max_high);
+                },
+                form_high() {
+                    return this.getColumnsValue(this.form.min_high,this.form.max_high,'CM');
+                },
+
+                //体重
+                weight() {
+                    return this.getColumns({$min_weight},this.form.min_weight,{$max_weight},this.form.max_weight);
+                },
+                form_weight() {
+                    return this.getColumnsValue(this.form.min_weight,this.form.max_weight,'KG');
+                },
+            }
+        });
+    </script>
+</block>

+ 394 - 0
public/themes/simpleboot3/matchmaker/user/mating_edit.html

@@ -0,0 +1,394 @@
+<extend name="public/base"/>
+<block name="css">
+    <style>
+        .van-nav-bar--fixed {z-index:100;}
+        .van-step--horizontal .van-step__title {font-size:16px;}
+        .van-step--horizontal .van-step__icon {font-size:16px;}
+        .van-step__circle {width:10px;height:10px;}
+        .van-nav-bar .van-icon,.van-nav-bar__text {color:white;}
+    </style>
+</block>
+<block name="body">
+    <!--头部-->
+    <van-nav-bar
+            class="bg-pink"
+            fixed="true"
+            left-text="返回"
+            left-arrow
+            @click-left="onBack"
+    >
+        <template #title>
+            <span style="color:white;">择偶要求</span>
+        </template>
+    </van-nav-bar>
+    <div style="width:100%;height:46px;"></div>
+
+    <!--年龄-->
+    <van-field
+            readonly
+            clickable
+            :value="form_age"
+            label="年龄"
+            placeholder="点击选择年龄"
+            @click="showAge = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showAge">
+        <van-picker
+                title="年龄"
+                show-toolbar
+                :columns="age"
+                @confirm="onMultiPikerConfirm('age',$event)"
+                @cancel="showAge = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--身高-->
+    <van-field
+            readonly
+            clickable
+            :value="form_high"
+            label="身高"
+            placeholder="点击选择身高"
+            @click="showHigh = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showHigh">
+        <van-picker
+                title="身高"
+                show-toolbar
+                :columns="high"
+                @confirm="onMultiPikerConfirm('high',$event)"
+                @cancel="showHigh = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--体重-->
+    <van-field
+            readonly
+            clickable
+            :value="form_weight"
+            label="体重"
+            placeholder="点击选择体重"
+            @click="showWeight = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showWeight">
+        <van-picker
+                title="体重"
+                show-toolbar
+                :columns="weight"
+                @confirm="onMultiPikerConfirm('weight',$event)"
+                @cancel="showWeight = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--籍贯-->
+    <van-field
+            readonly
+            clickable
+            :value="form.native"
+            label="籍贯"
+            placeholder="点击选择籍贯"
+            @click="showNative = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showNative">
+        <van-picker
+                title="籍贯"
+                show-toolbar
+                :columns="native"
+                @confirm="onNativeConfirm"
+                @cancel="showNative = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--学历-->
+    <van-field
+            readonly
+            clickable
+            :value="form.education"
+            label="学历"
+            placeholder="点击选择学历"
+            @click="showEducation = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showEducation">
+        <van-picker
+                title="学历"
+                show-toolbar
+                :columns="education"
+                @confirm="onEducationConfirm"
+                @cancel="showEducation = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--年收入-->
+    <van-field
+            readonly
+            clickable
+            :value="form.income"
+            label="年收入"
+            placeholder="点击选择年收入"
+            @click="showIncome = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showIncome">
+        <van-picker
+                title="年收入"
+                show-toolbar
+                :columns="income"
+                @confirm="onIncomeConfirm"
+                @cancel="showIncome = false"
+        ></van-picker>
+    </van-popup>
+
+    <van-field
+            readonly
+            clickable
+            :value="tinyint[form.have_house]"
+            label="是否有房"
+            placeholder="点击选择是否有房"
+            @click="showHaveHouse = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showHaveHouse">
+        <van-picker
+                title="是否有房"
+                show-toolbar
+                :columns="tinyint"
+                @confirm="onHaveHouseConfirm"
+                @cancel="showHaveHouse = false"
+        ></van-picker>
+    </van-popup>
+    <van-field
+            readonly
+            clickable
+            :value="tinyint[form.have_car]"
+            label="是否有车"
+            placeholder="点击选择是否有车"
+            @click="showHaveCar = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showHaveCar">
+        <van-picker
+                title="是否有车"
+                show-toolbar
+                :columns="tinyint"
+                @confirm="onHaveCarConfirm"
+                @cancel="showHaveCar = false"
+        ></van-picker>
+    </van-popup>
+    <van-field
+            readonly
+            clickable
+            :value="tinyint[form.with_parent_live]"
+            label="婚后是否愿意与父母同住"
+            placeholder="点击选择"
+            @click="showWithParentLive = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showWithParentLive">
+        <van-picker
+                title="婚后是否愿意与父母同住"
+                show-toolbar
+                :columns="tinyint"
+                @confirm="onWithParentLiveConfirm"
+                @cancel="showWithParentLive = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--是否吸烟-->
+    <van-field
+            readonly
+            clickable
+            :value="form.smoke"
+            label="是否吸烟"
+            placeholder="点击选择是否吸烟"
+            @click="showSmoke = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showSmoke">
+        <van-picker
+                title="是否吸烟"
+                show-toolbar
+                :columns="smoke"
+                @confirm="onSmokeConfirm"
+                @cancel="showSmoke = false"
+        ></van-picker>
+    </van-popup>
+
+    <!--是否喝酒-->
+    <van-field
+            readonly
+            clickable
+            :value="form.drink"
+            label="是否喝酒"
+            placeholder="点击选择是否喝酒"
+            @click="showDrink = true"
+    ></van-field>
+    <van-popup position="bottom" v-model="showDrink">
+        <van-picker
+                title="是否喝酒"
+                show-toolbar
+                :columns="drink"
+                @confirm="onDrinkConfirm"
+                @cancel="showDrink = false"
+        ></van-picker>
+    </van-popup>
+
+    <div style="padding:16px;">
+        <van-button block class="bg-pink" @click="onSubmit">完成</van-button>
+    </div>
+</block>
+<block name="script">
+    <script>
+        new Vue({
+            el: '#app',
+            data() {
+                return {
+                    form: {$mating},
+                    showAge: false,
+                    showHigh: false,
+                    showWeight: false,
+                    showMarry: false,
+                    showEducation: false,
+                    education: {$education},
+                    showNative: false,
+                    native: {$native},
+                    showIncome: false,
+                    income: {$income},
+                    tinyint: {$tinyint},
+                    showSmoke: false,
+                    smoke: {$smoke},
+                    showDrink: false,
+                    drink: {$drink},
+                    showHaveHouse: false,
+                    showHaveCar: false,
+                    showWithParentLive: false,
+                };
+            },
+            methods: {
+                onBack() {
+                    history.back();
+                },
+                onSubmit() {
+                    $.post("{:url('matingAddPost')}", this.form, function (json) {
+                        location.href = '{:url("matchmaker/index/index")}';
+                    }, 'json');
+                },
+                onEducationConfirm(value) {
+                    this.form.education = value;
+                    this.showEducation = false;
+                },
+                onNativeConfirm(value) {
+                    this.form.native = value;
+                    this.showNative = false;
+                },
+                onPikerConfirm(key, value) {
+                    let upperKey = key.slice(0, 1).toUpperCase() + key.slice(1)
+                    this.form[key] = value;
+                    this[`show${upperKey}`] = false;
+                },
+                onMultiPikerConfirm(key, value) {
+                    if (value[1] < value[0]) {
+                        this.$toast('第二个值不能比第一个值小');
+                        return false;
+                    }
+                    this.form[`min_${key}`] = value[0] === '不限' ? 0 : value[0];
+                    this.form[`max_${key}`] = value[1] === '不限' ? 0 : value[1];
+                    let upperKey = key.slice(0, 1).toUpperCase() + key.slice(1);
+                    this[`show${upperKey}`] = false;
+                },
+
+                //多列选择器
+                getColumns(min,min_value,max,max_value){
+                    let min_default = this.findKey(min, min_value);
+                    if (min_default === undefined) {
+                        min_default = 0;
+                    }
+                    let max_default = this.findKey(max, max_value);
+                    if (max_default === undefined) {
+                        max_default = 0;
+                    }
+
+                    return [
+                        {
+                            values: min,
+                            default: min_default,
+                        },
+                        {
+                            values: max,
+                            default: max_default,
+                        },
+                    ];
+                },
+
+                //多列选择器值
+                getColumnsValue(min,max,ext) {
+                    if (min === '' || max === '') {
+                        return '';
+                    }
+
+                    if (min === 0 && max === 0) {
+                        return '不限';
+                    }
+
+                    let min_ext = min + ext;
+                    if (min === 0) {
+                        min_ext = '不限';
+                    }
+                    let max_ext = max + ext;
+                    if (max === 0) {
+                        max_ext = '不限';
+                    }
+                    return `${min_ext}-${max_ext}`;
+                },
+
+                //找键
+                findKey(obj, value, compare = (a, b) => a === b) {
+                    return Object.keys(obj).find(k => compare(obj[k], value))
+                },
+                onIncomeConfirm(value) {
+                    this.form.income = value;
+                    this.showIncome = false;
+                },
+                onHaveHouseConfirm(value,index) {
+                    this.form.have_house = index;
+                    this.showHaveHouse = false;
+                },
+                onHaveCarConfirm(value,index) {
+                    this.form.have_car = index;
+                    this.showHaveCar = false;
+                },
+                onWithParentLiveConfirm(value,index) {
+                    this.form.with_parent_live = index;
+                    this.showWithParentLive = false;
+                },
+                onSmokeConfirm(value) {
+                    this.form.smoke = value;
+                    this.showSmoke = false;
+                },
+                onDrinkConfirm(value) {
+                    this.form.drink = value;
+                    this.showDrink = false;
+                },
+            },
+            computed: {
+                //年龄
+                age() {
+                    return this.getColumns({$min_age},this.form.min_age,{$max_age},this.form.max_age);
+                },
+                form_age() {
+                    return this.getColumnsValue(this.form.min_age,this.form.max_age,'岁');
+                },
+
+                //身高
+                high() {
+                    return this.getColumns({$min_high},this.form.min_high,{$max_high},this.form.max_high);
+                },
+                form_high() {
+                    return this.getColumnsValue(this.form.min_high,this.form.max_high,'CM');
+                },
+
+                //体重
+                weight() {
+                    return this.getColumns({$min_weight},this.form.min_weight,{$max_weight},this.form.max_weight);
+                },
+                form_weight() {
+                    return this.getColumnsValue(this.form.min_weight,this.form.max_weight,'KG');
+                },
+            }
+        });
+    </script>
+</block>

二进制
public/themes/simpleboot3/public/assets/images/default_avatar.png


二进制
public/themes/simpleboot3/public/assets/images/matchmaker/avatar1.png


二进制
public/themes/simpleboot3/public/assets/images/matchmaker/avatar2.png


二进制
public/themes/simpleboot3/public/assets/images/matchmaker/myBG.png


二进制
public/themes/simpleboot3/public/assets/images/matchmaker/myIcon.png


二进制
public/themes/simpleboot3/public/assets/images/matchmaker/myIcon2.png


二进制
public/themes/simpleboot3/public/assets/images/matchmaker/myIcon3.png


+ 6 - 4
vendor/thinkcmf/cmf/src/lib/Upload.php

@@ -259,10 +259,12 @@ class Upload
 
         //  $url=$first['url'];
         $storageSetting = cmf_get_cmf_settings('storage');
-        $qiniuSetting   = $storageSetting['Qiniu']['setting'];
-        //$url=preg_replace('/^https/', $qiniu_setting['protocol'], $url);
-        //$url=preg_replace('/^http/', $qiniu_setting['protocol'], $url);
-
+        $qiniuSetting = [];
+        if (!empty($storageSetting)) {
+            $qiniuSetting   = $storageSetting['Qiniu']['setting'];
+            //$url=preg_replace('/^https/', $qiniu_setting['protocol'], $url);
+            //$url=preg_replace('/^http/', $qiniu_setting['protocol'], $url);
+        }
         $arrInfo = [];
         if (config('FILE_UPLOAD_TYPE') == 'Qiniu' && $qiniuSetting['enable_picture_protect']) {
             //todo  qiniu code ...