Browse Source

信息登记页

linwu 1 year ago
parent
commit
efe48038f2

+ 70 - 0
app/admin/controller/Info.php

@@ -0,0 +1,70 @@
+<?php
+
+namespace app\admin\controller;
+
+use app\admin\AdminBaseController;
+use app\common\model\InfoModel;
+use app\common\model\UserFollowModel;
+use app\common\model\UserModel;
+use app\admin\validate\UserValidate;
+use think\exception\ValidateException;
+
+class Info extends AdminBaseController
+{
+    /**
+     * 列表
+     */
+    public function index()
+    {
+        return view('', [
+            'type_list' => InfoModel::TYPE,
+        ]);
+    }
+
+    public function listInfo()
+    {
+        $map   = $this->dealEqualInput(['type'], $this->dealLikeInput(['name', 'mobile']));
+        $list  = InfoModel::where($map)
+            ->order('id', 'desc')
+            ->limit(input('limit'))
+            ->page(input('page'))
+            ->append(['type_text','sex_text'])->select();
+        $count = InfoModel::where($map)->count();
+        if ($count == 0) {
+            ajax_return(1, '未查询到数据');
+        }
+        list_return($list, $count);
+    }
+
+    /**
+     * 用户跟进记录
+     */
+    public function follow()
+    {
+        $id   = input('id/d');
+        $info = InfoModel::find($id);
+        $list = UserFollowModel::where('info_id', $id)->order('id', 'desc')->limit(100)->select();
+        return view('', [
+            'info'      => $info,
+            'list'      => $list,
+            'type_list' => UserFollowModel::TYPE,
+        ]);
+    }
+
+    public function editFollow()
+    {
+        $id      = input('id/d', 0);
+        $user_id = input('user_id/d', 0);
+        $info    = InfoModel::find($id);
+        if (empty($info) || empty($user_id)) {
+            ajax_return(1, '用户信息不存在。');
+        }
+        UserFollowModel::create([
+            'user_id' => $user_id,
+            'info_id' => $id,
+            'type'    => input('type/d', 1),
+            'remark'  => input('remark/s', ""),
+        ]);
+        ajax_return();
+    }
+}

+ 84 - 0
app/admin/view/info/follow.html

@@ -0,0 +1,84 @@
+<div class="layui-fluid">
+    <div class="layui-card">
+        <div class="layui-card-header">用户授权信息</div>
+        <div class="layui-card-body">
+
+            <div class="layui-form layui-form-pane" lay-filter="{$lay_table}">
+                <input type="hidden" name="id" value="{$user.id}">
+                <div class="layui-form-item">
+                    <label class="layui-form-label">用户信息</label>
+                    <div class="layui-input-block">
+                        <input type="text" value="{$user.nickname} - {$user.mobile}" readonly
+                               class="layui-input">
+                    </div>
+                </div>
+                <div class="layui-form-item" pane>
+                    <label class="layui-form-label">跟进方式</label>
+                    <div class="layui-input-block">
+                        {volist name="type_list" id="v"}
+                        <input type="radio" name="type" value="{$key}" title="{$v}" {eq name="key" value="1" }checked{/eq} />
+                        {/volist}
+                    </div>
+                </div>
+                <div class="layui-form-item">
+                    <label class="layui-form-label"><span style="color:#f90c05;">*</span>跟进备注</label>
+                    <div class="layui-input-block">
+                        <textarea name="remark" lay-verify="required" placeholder="请输入..."
+                                  class="layui-textarea"></textarea>
+                    </div>
+                </div>
+                <div class="layui-form-item">
+                    <div class="layui-input-block">
+                        <input type="button" lay-submit lay-filter="{$lay_btn}" value="确认"
+                               class="layui-btn">
+                    </div>
+                </div>
+            </div>
+
+            <fieldset class="layui-elem-field layui-field-title" style="margin-top: 30px;">
+                <legend>以往跟进记录</legend>
+            </fieldset>
+            <ul class="layui-timeline">
+                {volist name="list" id="vo"}
+                <li class="layui-timeline-item">
+                    <i class="layui-icon layui-timeline-axis"></i>
+                    <div class="layui-timeline-content layui-text">
+                        <h3 class="layui-timeline-title">
+                            {$vo.create_time} 【{$vo.type_text}】
+                            <span style="color:#FF5722;">({$vo.user_type_text})</span>
+                        </h3>
+                        <p>{$vo.remark}</p>
+                    </div>
+                </li>
+                {/volist}
+                <li class="layui-timeline-item">
+                    <i class="layui-icon layui-timeline-axis"></i>
+                    <div class="layui-timeline-content layui-text">
+                        <div class="layui-timeline-title">已加载完 ( 最多显示最近100条跟进记录 )</div>
+                    </div>
+                </li>
+            </ul>
+
+
+        </div>
+    </div>
+</div>
+
+<script>
+    layui.use(['index', 'form', 'set', 'table'], function () {
+        const admin = layui.admin;
+        const form = layui.form;
+        form.render();
+
+        form.on('submit({$lay_btn})', function (obj) {
+            admin.req({
+                url: "{:url('user/editFollow')}",
+                data: obj.field,
+                done: function (res) {
+                    location.reload();
+                }
+            });
+        });
+
+    });
+</script>

+ 112 - 0
app/admin/view/info/index.html

@@ -0,0 +1,112 @@
+<style>
+
+</style>
+<div class="layui-fluid">
+    <div class="layui-card">
+        <div class="layui-form layui-form-pane  layui-card-header layuiadmin-card-header-auto">
+            <div class="layui-form-item">
+                <div class="layui-inline">
+                    <label class="layui-form-label">姓名</label>
+                    <div class="layui-input-block">
+                        <input type="text" name="name" placeholder="请输入姓名" autocomplete="off" class="layui-input">
+                    </div>
+                </div>
+                <div class="layui-inline">
+                    <label class="layui-form-label">电话</label>
+                    <div class="layui-input-block">
+                        <input type="text" name="mobile" placeholder="请输入电话" autocomplete="off" class="layui-input">
+                    </div>
+                </div>
+                <div class="layui-inline">
+                    <label class="layui-form-label">专业类别</label>
+                    <div class="layui-input-block">
+                        <select name="type">
+                            <option value="">全部</option>
+                            {volist name="type_list" id="v"}
+                            <option value="{$key}">{$v}</option>
+                            {/volist}
+                        </select>
+                    </div>
+                </div>
+                <div class="layui-inline">
+                    <button class="layui-btn" lay-submit lay-filter="{$lay_btn}">
+                        <i class="layui-icon layui-icon-search layuiadmin-button-btn"></i>
+                    </button>
+                </div>
+            </div>
+        </div>
+
+        <div class="layui-card-body">
+            <table id="{$lay_table}" lay-filter="{$lay_table}"></table>
+            <script type="text/html" id="setTpl">
+                <a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="detail"><i class="layui-icon layui-icon-edit"></i>详情</a>
+                <a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="follow"><i class="layui-icon layui-icon-engine"></i>跟进</a>
+            </script>
+        </div>
+    </div>
+</div>
+
+<script>
+    layui.use(['form', 'table'], function () {
+        const form = layui.form;
+        const table = layui.table;
+        form.render();
+
+        table.render({
+            elem: '#{$lay_table}',
+            url: "{:url('info/listInfo')}",
+            cols: [
+                [
+                    {field: 'type_text', title: '专业类别' ,width: 160,},
+                    {field: 'name', title: '姓名', width: 160},
+                    {field: 'mobile', title: '手机号', width: 160},
+                    {field: 'sex_text', title: '性别', width: 160},
+                    {field: 'school', title: '毕业学校', width: 160},
+                    {field: 'major', title: '专业', width: 160},
+                    {field: 'company', title: '意向单位', width: 160},
+                    {field: 'create_time', title: '录入时间'},
+                    {title: '操作', width: 160, align: 'center', fixed: 'right', toolbar: '#setTpl'}
+                ]
+            ],
+            page: true,
+            limit: 50,
+            cellMinWidth: 150,
+            text: '对不起,加载出现异常!'
+        });
+
+        form.on('submit({$lay_btn})', function (data) {
+            table.reload('{$lay_table}', {
+                where: data.field,
+                page: {
+                    curr: 1
+                }
+            });
+        });
+
+
+        //监听工具条
+        table.on('tool({$lay_table})', function (obj) {
+            const data = obj.data;
+            if (obj.event === 'detail') {
+                const index = layer.open({
+                    type: 2,
+                    title: '编辑用户',
+                    content: "{:url('user/userForm')}?id=" + data.id,
+                    maxmin: true,
+                    area: ['550px', '550px']
+                });
+                layer.full(index);
+            } else if (obj.event === 'follow') {
+                const index = layer.open({
+                    type: 2,
+                    title: '跟进记录',
+                    content: "{:url('user/follow')}?id=" + data.id,
+                    maxmin: true,
+                    area: ['550px', '550px']
+                });
+                layer.full(index);
+            }
+        });
+
+    });
+</script>

+ 1 - 0
app/admin/view/user/follow.html

@@ -45,6 +45,7 @@
                     <div class="layui-timeline-content layui-text">
                         <h3 class="layui-timeline-title">
                             {$vo.create_time} 【{$vo.type_text}】
+                            <span style="color:#FF5722;">({$vo.user_type_text})</span>
                         </h3>
                         <p>{$vo.remark}</p>
                     </div>

+ 2 - 2
app/admin/view/user/index.html

@@ -63,7 +63,7 @@
             </script>
             <script type="text/html" id="setTpl">
                 <a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit"><i class="layui-icon layui-icon-edit"></i>编辑</a>
-                <a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="follow"><i class="layui-icon layui-icon-engine"></i>跟进</a>
+                <!--<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="follow"><i class="layui-icon layui-icon-engine"></i>跟进</a>-->
                 <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del"><i class="layui-icon layui-icon-delete"></i>删除</a>
             </script>
         </div>
@@ -91,7 +91,7 @@
                     {field: 'last_login_ip', title: '最后登录IP', width: 160},
                     {field: 'last_login_time', title: '最后登录时间', width: 160},
                     {field: 'create_time', title: '注册时间'},
-                    {title: '操作', width: 240, align: 'center', fixed: 'right', toolbar: '#setTpl'}
+                    {title: '操作', width: 160, align: 'center', fixed: 'right', toolbar: '#setTpl'}
                 ]
             ],
             page: true,

+ 50 - 0
app/common/model/InfoModel.php

@@ -0,0 +1,50 @@
+<?php
+
+namespace app\common\model;
+
+class InfoModel extends BaseModel
+{
+    // 设置表名
+    protected $name = 'info';
+
+    //自动完成
+    protected $autoWriteTimestamp = true;
+
+    // 常量
+    const TYPE = [
+        'literature' => '哲学、文学、历史学大类',
+        'economy' => '经济学、管理学大类',
+        'law' => '法学大类',
+        'education' => '教育学大类',
+        'engineering' => '理学,工学大类',
+        'medicine' => '医学大类',
+        'agronomy' => '农学大类',
+        'military' => '军事学大类',
+    ];
+    const SEX = ['保密', '男', '女'];
+
+    const TYPE_DESCRIBE = [
+        'literature' => '哲学类,中国语言文学类,少数民族语言文学类,外国语言文学类,新闻传播学类,艺术设计类,表演艺术类,历史学类。',
+        'economy' => '经济贸易类,财政金融类,统计学类,管理科学与工程类,工商管理类,电商物流类,旅游餐饮类,会计与审计类,公共管理类,卫生管理类,农业经济管理类,图书档案学类。',
+        'law' => '法学类,监所管理类,马克思主义理论类,社会学类,民族宗教类,政治学类,公安学类。',
+        'education' => '教育学类,体育学类,职业技术教育类,科学教育类。',
+        'engineering' => '公安技术类,数学类,物理学类,化学类,生物科学类,天文学类,地质学类,地理科学类,地球物理学类,大气科学类,海洋科学类,心理学类,系统科学类,地矿类,材料类,
+        机械类,仪器仪表类,能源动力类,电子信息类,通信信息类,电气自动化类,计算机科学与技术类,计算机软件技术类,计算机网络技术类,计算机信息管理类,计算机多媒体技术类,计算机硬件技术类,
+        计算机专门应用类,土建类,水利类,测绘类,环境生态类,环境安全技术类,化工与制药类,交通运输类,交通运输综合管理类,交通运输装备类,公路运输类,铁道运输类,城市轨道运输类,水上运输类,
+        民航运输类,港口运输类,管道运输类,海洋工程类,食品科学与工程类,纺织科学与工程类,轻化工类,包装印刷类,航空航天类,武器类,工程力学类,生物工程类,农业工程类,林业工程类,光学工程类,核科学与技术类。',
+        'medicine' => '基础医学类,公共卫生与预防医学类,临床医学类,医学技术类,中医学和中西医结合类,法医学类,护理学类,药学类,中药学类。',
+        'agronomy' => '植物生产类,森林资源类,动物生产类,动物医学类,水产类。',
+        'military' => '军事学类,军事机械装备类,军事测绘遥感类,军事控制测试类,军事经济管理类,兵种指挥类,航空航天指挥类,信息作战指挥类,保障指挥类。',
+    ];
+
+    public function getTypeTextAttr($value, $data)
+    {
+        return self::TYPE[$data['type']];
+    }
+
+    public function getSexTextAttr($value, $data)
+    {
+        return self::SEX[$data['sex']];
+    }
+
+}

+ 12 - 4
app/common/model/UserFollowModel.php

@@ -11,17 +11,25 @@ class UserFollowModel extends BaseModel
     protected $autoWriteTimestamp = true;
 
     // 常量
-    const TYPE = [1 => '电话', 2 => '微信/QQ', 3 => '其他'];
+    const TYPE      = [1 => '电话', 2 => '微信/QQ', 3 => '其他'];
+    const USER_TYPE = [1 => '管理员', 2 => '用户'];
 
-    const TYPE_MOBILE = 1;
-    const TYPE_QQ     = 2;
-    const TYPE_OTHER  = 3;
+    const TYPE_MOBILE     = 1;
+    const TYPE_QQ         = 2;
+    const TYPE_OTHER      = 3;
+    const USER_TYPE_ADMIN = 1;
+    CONST USER_TYPE_USER  = 2;
 
     public function getTypeTextAttr($value, $data)
     {
         return self::TYPE[$data['type']];
     }
 
+    public function getUserTypeTextAttr($value, $data)
+    {
+        return self::USER_TYPE[$data['user_type']];
+    }
+
     public function User()
     {
         return $this->hasMany(UserModel::class, "id", "user_id");

+ 15 - 2
app/mobile/common.php

@@ -34,13 +34,13 @@ function get_user()
             $response = \think\Response::create($res, 'json');
             throw new \think\exception\HttpResponseException($response);
         } else {
-            session('back_url',request()->url());
+            session('back_url', request()->url());
             $response = redirect('/mobile/login/login');
             throw new \think\exception\HttpResponseException($response);
         }
     }
 
-    $user = \app\common\model\UserModel::where('id',$sessionUserId)->hidden(['password','salt'])->find();
+    $user = \app\common\model\UserModel::where('id', $sessionUserId)->hidden(['password', 'salt'])->find();
     if (empty($user)) {
         jump('该用户已删除');
     }
@@ -59,4 +59,17 @@ function get_user_id()
     }
 
     return $sessionUserId;
+}
+
+function array_to_vue($arr, $key = "", $value = "")
+{
+    $res = [];
+    foreach ($arr as $k => $v) {
+        if (!empty($key)) {
+            $res[] = ['text' => $v[$key], 'value' => $v[$value]];
+        } else {
+            $res[] = ['text' => $v, 'value' => $k];
+        }
+    }
+    return json_encode($res);
 }

+ 1 - 0
app/mobile/controller/Article.php

@@ -23,6 +23,7 @@ class Article extends MobileBaseController
     public function listArticle()
     {
         $map = $this->dealEqualInput(['cate_id']);
+        $map[] = ['status','=',ArticleModel::STATUS_PUBLISH];
 
         $list = ArticleModel::where($map)
             ->order(['priority' => 'desc', 'id' => 'desc'])

+ 140 - 0
app/mobile/controller/Info.php

@@ -0,0 +1,140 @@
+<?php
+
+namespace app\mobile\controller;
+
+use app\common\model\InfoModel;
+use app\common\model\UserFollowModel;
+use app\mobile\MobileBaseController;
+use app\mobile\validate\InfoValidate;
+use think\App;
+use think\exception\ValidateException;
+
+class Info extends MobileBaseController
+{
+    private $_user = null;
+
+    public function __construct(App $app)
+    {
+        parent::__construct($app);
+        $this->_user = get_user();
+    }
+
+    /**
+     * 登记列表
+     */
+    public function index()
+    {
+        $list = InfoModel::where('user_id', $this->_user['id'])
+            ->append(['type_text'])
+            ->select();
+
+        return view('', ['list' => $list]);
+    }
+
+    /**
+     * 类型介绍
+     */
+    public function type()
+    {
+        $list     = InfoModel::TYPE;
+        $describe = InfoModel::TYPE_DESCRIBE;
+
+        return view('', ['list' => $list, 'describe' => $describe]);
+    }
+
+    /**
+     * 登记表单
+     */
+    public function form()
+    {
+        $id = input('id/d', 0);
+        if (empty($id)) {
+            $info = '{}';
+        } else {
+            $info        = InfoModel::find($id);
+            $info['sex'] = (string)$info['sex'];
+            empty($info) && jump('该信息不存在');
+        }
+
+        $type      = InfoModel::TYPE;
+        $type_text = $info == '{}' ? '' : $type[$info['type']];
+        return view('', [
+            'info'      => $info,
+            'type_text' => $type_text,
+            'type_list' => array_to_vue($type),
+        ]);
+    }
+
+    /**
+     * 表单提交
+     */
+    public function formPost()
+    {
+        $data            = input('post.');
+        $data['user_id'] = $this->_user['id'];
+
+        try {
+            validate(InfoValidate::class)->check($data);
+        } catch (ValidateException $e) {
+            ajax_return(1, $e->getError());
+        }
+
+        if (empty($data['id'])) {
+            InfoModel::create($data);
+        } else {
+            InfoModel::update($data, ['id' => $data['id']]);
+        }
+
+        ajax_return();
+    }
+
+    /**
+     * 删除
+     */
+    public function delete()
+    {
+        $id = input('post.id');
+        empty($id) && ajax_return(1, '该信息不存在');
+
+        $user_id = $this->_user['id'];
+        $info    = InfoModel::where('id', $id)->where('user_id', $user_id)->find();
+        empty($info) && ajax_return(1, '该信息不存在');
+
+        UserFollowModel::destroy(['info_id' => $id]);
+        $info->delete();
+
+        ajax_return();
+    }
+
+    /**
+     * 跟进
+     */
+    public function follow()
+    {
+        $id = input('id');
+        empty($id) && jump('该记录不存在');
+
+        $list = UserFollowModel::where('user_id', $this->_user['id'])->where('info_id', $id)->order('id', 'desc')->select();
+
+        return view('', ['list' => $list, 'id' => $id]);
+    }
+
+    public function followPost()
+    {
+        $id = input('post.id');
+        empty($id) && ajax_return(1, '数据异常');
+        $remark = input('post.remark');
+        empty($remark) && ajax_return(1, '请填写跟进记录');
+
+        $data = [
+            'user_id'   => $this->_user['id'],
+            'info_id'   => $id,
+            'user_type' => UserFollowModel::USER_TYPE_USER,
+            'type'      => UserFollowModel::TYPE_OTHER,
+            'remark'    => $remark,
+        ];
+        UserFollowModel::create($data);
+
+        ajax_return();
+    }
+}

+ 28 - 0
app/mobile/validate/InfoValidate.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace app\mobile\validate;
+
+use think\Validate;
+
+class InfoValidate extends Validate
+{
+    protected $rule = [
+        'type'         => 'require',
+        'name'         => 'require',
+        'mobile'       => 'require|mobile',
+        'school'       => 'require',
+        'major'        => 'require',
+        'company'      => 'require',
+        'introduction' => 'require',
+    ];
+
+    protected $message = [
+        'type'         => '请选择专业类型',
+        'name'         => '请输入姓名',
+        'mobile'       => '手机号格式不对',
+        'school'       => '请输入毕业院校',
+        'major'        => '请输入专业',
+        'company'      => '请输入意向单位',
+        'introduction' => '请输入个人简介',
+    ];
+}

+ 7 - 6
app/mobile/view/article/index.html

@@ -7,6 +7,9 @@
         class="nav-theme"
         :fixed="true"
         :placeholder="true"
+        left-text="返回"
+        left-arrow
+        @click-left="onBack"
 >
     <template #title>
         <span class="text-white">文章</span>
@@ -22,11 +25,6 @@
 
 {include file="public/list_load" list="<article-list :list='list'></article-list>" /}
 
-<van-tabbar v-model="active" :placeholder="true">
-    <van-tabbar-item icon="wap-home-o" url="{:url('/')}">首页</van-tabbar-item>
-    <van-tabbar-item icon="description">文章</van-tabbar-item>
-    <van-tabbar-item icon="user-circle-o" url="{:url('my/index')}">我的</van-tabbar-item>
-</van-tabbar>
 {/block}
 {block name="script"}
 <script>
@@ -34,7 +32,6 @@
         let form = { cate_id : {$cate_id} };
         let base = list_load('/article/listArticle',form);
 
-        base.active = 1;
         base.tab_active = Vue.ref('{$cate_id}');
 
         base.onTab = ({name}) => {
@@ -42,6 +39,10 @@
             base.onRefresh();
         };
 
+        base.onBack = () => {
+            history.back();
+        };
+
         return base;
     }
 </script>

+ 5 - 9
app/mobile/view/index/index.html

@@ -1,7 +1,7 @@
 {extend name="public/base"/}
 {block name="css"}
 <style>
-
+    .van-cell__title {font-size:16px;}
 </style>
 {/block}
 {block name="body"}
@@ -22,18 +22,14 @@
     </van-swipe-item>
     {/volist}
 </van-swipe>
-
-<van-grid :border="false">
-    {volist name="navigation" id="item"}
-    <van-grid-item url="{$item.url}" icon="{$item.image}" text="{$item.title}"></van-grid-item>
-    {/volist}
-</van-grid>
-
+<van-cell-group>
+    <van-cell title="新闻资讯" is-link value="查看更多" @click="toUrl('{:url('article/index')}')"></van-cell>
+</van-cell-group>
 <article-list :list="list"></article-list>
 
 <van-tabbar v-model="active" :placeholder="true">
     <van-tabbar-item icon="wap-home-o">首页</van-tabbar-item>
-    <van-tabbar-item icon="description" url="{:url('article/index')}">文章</van-tabbar-item>
+    <van-tabbar-item icon="description" url="{:url('info/index')}">信息登记</van-tabbar-item>
     <van-tabbar-item icon="user-circle-o" url="{:url('my/index')}">我的</van-tabbar-item>
 </van-tabbar>
 {/block}

+ 67 - 0
app/mobile/view/info/follow.html

@@ -0,0 +1,67 @@
+{extend name="public/base"/}
+{block name="css"}
+
+{/block}
+{block name="body"}
+<van-nav-bar
+        class="nav-theme"
+        :fixed="true"
+        :placeholder="true"
+        left-text="返回"
+        left-arrow
+        @click-left="onBack"
+>
+    <template #title>
+        <span class="text-white">跟进记录</span>
+    </template>
+</van-nav-bar>
+<van-form @submit="onSubmit">
+    <van-field
+            required
+            v-model="remark"
+            rows="3"
+            autosize
+            label="跟进记录"
+            type="textarea"
+            placeholder="请填写跟进记录"
+            :rules="[{ required: true, message: '请填写跟进记录' }]"
+    ></van-field>
+    <div style="margin: 16px;">
+        <van-button round block type="primary" native-type="submit">
+            提交
+        </van-button>
+    </div>
+</van-form>
+<van-steps direction="vertical" :active="0">
+    {volist name="list" id="vo"}
+        <van-step>
+            <h4>
+                {$vo.create_time} 【{$vo.type_text}】
+                <span style="color:#FF5722;">({$vo.user_type_text})</span>
+            </h4>
+            <p>{$vo.remark} </p>
+        </van-step>
+    {/volist}
+</van-steps>
+{/block}
+{block name="script"}
+<script>
+    function v_setup() {
+        let base = {};
+
+        base.onBack = () => {
+            location.href = "{:url('info/index')}";
+        };
+
+        //表单
+        base.remark = Vue.ref('');
+        base.onSubmit = (form) => {
+            postJson("{:url('info/followPost')}",{remark:base.remark.value,id:{$id}}).then(({data}) => {
+                location.reload();
+            });
+        };
+
+        return base;
+    }
+</script>
+{/block}

+ 159 - 0
app/mobile/view/info/form.html

@@ -0,0 +1,159 @@
+{extend name="public/base"/}
+{block name="css"}
+
+{/block}
+{block name="body"}
+<van-nav-bar
+        class="nav-theme"
+        :fixed="true"
+        :placeholder="true"
+        left-text="返回"
+        left-arrow
+        @click-left="onBack"
+>
+    <template #title>
+        <span class="text-white">信息登记</span>
+    </template>
+</van-nav-bar>
+
+<van-form @submit="onSubmit">
+    <h2 class="lw-title">基础信息</h2>
+    <van-cell-group inset>
+        <!--专业类型-->
+        <van-field
+                v-model="type_text"
+                is-link
+                readonly
+                required
+                label="专业类型"
+                placeholder="选择专业类型"
+                @click="show_type = true"
+        ></van-field>
+        <van-popup v-model:show="show_type" round position="bottom">
+            <van-picker
+                    :columns="type_list"
+                    @cancel="show_type = false"
+                    @confirm="onTypeConfirm"
+            ></van-picker>
+        </van-popup>
+        <van-field
+                required
+                v-model="form.name"
+                label="姓名"
+                placeholder="请填写姓名"
+                :rules="[{ required: true, message: '请填写姓名' }]"
+        ></van-field>
+        <van-field required label="性别">
+            <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
+                v-model="form.mobile"
+                label="手机号"
+                placeholder="请填写手机号"
+                :rules="[
+                    { required: true, message: '请填写电话' },
+                    { validator, message: '请输入正确的手机号'}
+                ]"
+        ></van-field>
+    </van-cell-group>
+
+    <h2 class="lw-title">学校信息</h2>
+    <van-cell-group inset>
+        <van-field
+                required
+                v-model="form.school"
+                label="毕业学校"
+                placeholder="请填写毕业学校"
+                :rules="[{ required: true, message: '请填写毕业学校' }]"
+        ></van-field>
+        <van-field
+                required
+                v-model="form.major"
+                label="专业"
+                placeholder="请填写专业"
+                :rules="[{ required: true, message: '请填写专业' }]"
+        ></van-field>
+        <van-field
+                required
+                v-model="form.company"
+                label="意向单位"
+                placeholder="请填写意向单位"
+                :rules="[{ required: true, message: '请填写意向单位' }]"
+        ></van-field>
+        <van-field
+                required
+                v-model="form.introduction"
+                rows="3"
+                autosize
+                label="个人简介"
+                type="textarea"
+                placeholder="请填写个人简介"
+                :rules="[{ required: true, message: '请填写个人简介' }]"
+        ></van-field>
+        <van-field
+                v-model="form.awards"
+                rows="3"
+                autosize
+                label="获得的奖项"
+                type="textarea"
+                placeholder="请填写获得的奖项"
+        ></van-field>
+    </van-cell-group>
+    <div style="margin: 16px;">
+        <van-button round block type="primary" native-type="submit">
+            提交
+        </van-button>
+    </div>
+</van-form>
+{/block}
+{block name="script"}
+<script>
+    function v_setup() {
+        let base = {};
+
+        base.form = Vue.reactive({$info});
+
+        base.onBack = () => {
+            history.back();
+        };
+
+        // 专业类型
+        base.type_list = {$type_list};
+        base.type_text = Vue.ref('{$type_text}');
+        base.show_type = Vue.ref(false);
+        base.toggleType = (val) => {
+            base.showType.value = val;
+        };
+        base.onTypeConfirm = (op) => {
+            base.form.type = op.selectedValues[0];
+            base.type_text.value = op.selectedOptions[0].text;
+            base.show_type.value = false;
+        };
+
+        //手机号验证
+        base.validator = (val) => {
+            return /^1(?:3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8\d|9\d)\d{8}$/.test(val);
+        };
+
+        //表单提交
+        base.onSubmit = (form) => {
+            if (base.form.type === '') {
+                vant.showToast('请选择类型');
+                return false;
+            }
+
+            postJson("{:url('info/formPost')}",base.form).then(({data}) => {
+                location.href = "{:url('info/index')}";
+            });
+        };
+
+        return base;
+    }
+</script>
+{/block}

+ 115 - 0
app/mobile/view/info/index.html

@@ -0,0 +1,115 @@
+{extend name="public/base"/}
+{block name="css"}
+<style>
+    .bottom-button {
+        width: 160px;
+        height: 40px;
+    }
+    .van-cell {
+        flex-wrap:wrap;
+    }
+    .cell-extra {
+        width:100%;
+        text-align:right;
+    }
+    .cell-extra button {
+        margin-right:5px;
+    }
+    .plus {
+        margin-top:20px;
+    }
+    .plus .plus-icon {
+        margin:0 auto;
+        width:60px;
+        height:60px;
+        border-radius:50%;
+        background:white;
+        display:flex;
+        justify-content:center;
+        align-items:center;
+        font-size:30px;
+    }
+</style>
+{/block}
+{block name="body"}
+<van-nav-bar
+        class="nav-theme"
+        :fixed="true"
+        :placeholder="true"
+        right-text="类别说明"
+        @click-right="onClickRight"
+>
+    <template #title>
+        <span class="text-white">信息登记</span>
+    </template>
+</van-nav-bar>
+
+<div v-if="list.length > 0">
+    <van-cell-group>
+        <van-cell v-for="item in list" :title="item.name" :value="item.mobile" :label="item.type_text">
+            <template #extra>
+                <div class="cell-extra">
+                    <van-button type="primary" size="small" @click="toFollow(item.id)">跟进</van-button>
+                    <van-button type="primary" size="small" @click="toEdit(item.id)">编辑</van-button>
+                    <van-button type="danger" size="small" @click="deleteItem(item.id)">删除</van-button>
+                </div>
+            </template>
+        </van-cell>
+    </van-cell-group>
+    <div class="plus">
+        <div class="plus-icon" @click="toAdd">
+            <van-icon name="plus"></van-icon>
+        </div>
+    </div>
+</div>
+<van-empty v-else description="暂无信息">
+    <van-button round type="danger" @click="toAdd" class="bottom-button">
+        立即添加
+    </van-button>
+</van-empty>
+
+<van-tabbar v-model="active" :placeholder="true">
+    <van-tabbar-item icon="wap-home-o" url="{:url('/')}">首页</van-tabbar-item>
+    <van-tabbar-item icon="description">信息登记</van-tabbar-item>
+    <van-tabbar-item icon="user-circle-o" url="{:url('my/index')}">我的</van-tabbar-item>
+</van-tabbar>
+{/block}
+{block name="script"}
+<script>
+    function v_setup() {
+        let base = {};
+
+        base.active = 1;
+        base.list = {$list};
+
+        base.onClickRight = () => {
+            location.href = "{:url('info/type')}";
+        };
+
+        base.toAdd = () => {
+            location.href = "{:url('info/form')}";
+        };
+
+        base.toEdit = (id) => {
+            location.href = "{:url('info/form')}?id=" + id;
+        };
+
+        base.toFollow = (id) => {
+            location.href = "{:url('info/follow')}?id=" + id;
+        };
+
+        base.deleteItem = id => {
+            vant.showConfirmDialog({
+                title: '提示',
+                message: '确认要删除吗?',
+            }).then(() => {
+                postJson("{:url('info/delete')}", {id:id}).then(function ({data}) {
+                    location.reload();
+                });
+            }).catch(error=>{});
+        };
+
+        return base;
+    }
+</script>
+{/block}

+ 47 - 0
app/mobile/view/info/type.html

@@ -0,0 +1,47 @@
+{extend name="public/base"/}
+{block name="css"}
+
+{/block}
+{block name="body"}
+<van-nav-bar
+        class="nav-theme"
+        :fixed="true"
+        :placeholder="true"
+        left-text="返回"
+        left-arrow
+        @click-left="onBack"
+>
+    <template #title>
+        <span class="text-white">专业类别说明</span>
+    </template>
+</van-nav-bar>
+<van-collapse v-model="activeNames">
+    {volist name="list" id="vo"}
+    <van-collapse-item title="{$vo}" name="{$key}">
+        {$describe[$key]}
+    </van-collapse-item>
+    {/volist}
+</van-collapse>
+<div style="margin: 16px;">
+    <van-button block type="primary" @click="toArticle">查看具体明细</van-button>
+</div>
+{/block}
+{block name="script"}
+<script>
+    function v_setup() {
+        let base = {};
+
+        base.onBack = () => {
+            history.back();
+        };
+
+        base.activeNames = Vue.ref(['']);
+
+        base.toArticle = () => {
+            location.href = "{:url('article/detail')}?id=1";
+        };
+
+        return base;
+    }
+</script>
+{/block}

+ 9 - 1
app/mobile/view/login/login.html

@@ -32,7 +32,10 @@
                         required
                         label="电话"
                         placeholder="请输入电话"
-                        :rules="[{ required: true, message: '请填写电话' }]"
+                        :rules="[
+                            { required: true, message: '请填写电话' },
+                            { validator, message: '请输入正确的手机号'}
+                        ]"
                 ></van-field>
                 <van-field
                         v-model="verify"
@@ -205,6 +208,11 @@
             base[value].value = true;
         };
 
+        //手机号验证
+        base.validator = (val) => {
+            return /^1(?:3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8\d|9\d)\d{8}$/.test(val);
+        }
+
         return base;
     }
 </script>

+ 11 - 11
app/mobile/view/my/index.html

@@ -48,7 +48,7 @@
         </div>
     </div>
     <div class="user-grid">
-        <van-grid :border="false">
+        <van-grid :border="false" :column-num="3">
             <van-grid-item @click="navTo('{:url('my/info')}')">
                 <van-image
                         width="30"
@@ -73,14 +73,14 @@
                 ></van-image>
                 <div class="grid-text">换绑手机</div>
             </van-grid-item>
-            <van-grid-item @click="navTo('{:url('my/auth')}')">
-                <van-image
-                        width="30"
-                        height="30"
-                        src="__MIMAGES__/icon_name_auth.png"
-                ></van-image>
-                <div class="grid-text">实名认证</div>
-            </van-grid-item>
+            <!--<van-grid-item @click="navTo('{:url('my/auth')}')">-->
+                <!--<van-image-->
+                        <!--width="30"-->
+                        <!--height="30"-->
+                        <!--src="__MIMAGES__/icon_name_auth.png"-->
+                <!--&gt;</van-image>-->
+                <!--<div class="grid-text">实名认证</div>-->
+            <!--</van-grid-item>-->
         </van-grid>
     </div>
 </div>
@@ -88,13 +88,13 @@
 <van-cell-group inset>
     <van-cell title="绑定微信" v-if="!user.openid" is-link url="{:url('login/wechat')}"></van-cell>
     <van-cell title="意见反馈" is-link url="{:url('my/feedback')}"></van-cell>
-    <van-cell title="关于我们" is-link url="{:url('my/about')}"></van-cell>
+    <!--<van-cell title="关于我们" is-link url="{:url('my/about')}"></van-cell>-->
     <van-cell title="退出" is-link url="{:url('login/logout')}"></van-cell>
 </van-cell-group>
 
 <van-tabbar v-model="active" @change="onTab" :placeholder="true">
     <van-tabbar-item icon="wap-home-o" url="{:url('/')}">首页</van-tabbar-item>
-    <van-tabbar-item icon="description" url="{:url('article/index')}">文章</van-tabbar-item>
+    <van-tabbar-item icon="description" url="{:url('info/index')}">信息登记</van-tabbar-item>
     <van-tabbar-item icon="user-circle-o">我的</van-tabbar-item>
 </van-tabbar>
 {/block}

+ 7 - 0
public/static/mobile/css/style.css

@@ -26,3 +26,10 @@ html {
 .article-list article .s-left .s-title{font-size: 16px;text-overflow: ellipsis;display: -webkit-box;overflow: hidden;-webkit-box-orient: vertical;-webkit-box-pack: center;-webkit-box-align: center;-webkit-line-clamp: 3;}
 .article-list article .s-left .s-time{font-size: 12px;color:#999;margin-top:auto;}
 .article-list article .s-right {width:110px;margin-left:auto;}
+
+.lw-title {margin: 0;
+    padding: 32px 16px 16px;
+    color: #969799;
+    font-weight: 400;
+    font-size: 14px;
+    line-height: 16px;}