基于(tp5.1、tp6.0)后台开发框架(设计思路参考laravel-admin)

项目基于tp5/tp6,受laravel-admin启发,思路上大体一样,细节不同。

已在多个项目中稳定使用。

主要就是form,table,tree,column,row等组件的封装。

每个控制器内置导出功能,selectpage(下拉数据源)。

项目仓库

gitee.com/tpext/myadmin

文档

gitee.com/tpext/myadmin/wikis/page... 

演示

网址:

  1. [tp5.1] quick.shenzhuo.vip:10582/admin 
  2. [tp6.0] tpext.shenzhuo.vip:10582/admin 

账号:

admintpextadmin

不要乱删数据

谢谢大家关注,使用中有什么问题或建议请到gitee上面提交isuse,这里不是经常来看。

实例:

HasBuilder 封装了常用操作,可供控制器引入使用

<?php
namespace app\admin\controller;
use app\common\logic\MemberLogic;
use app\common\model;
use think\Controller;
use tpext\builder\traits\HasBuilder;

/**
 * Undocumented class
 * @title 会员管理
 */
class Member extends Controller
{
    use HasBuilder;

    /**
     * Undocumented variable
     *
     * @var model\Member
     */
    protected $dataModel;

    protected function initialize()
    {
        $this->dataModel = new model\Member;
        $this->pageTitle = '会员管理';
        $this->enableField = 'status';
        $this->pagesize = 8;

        /* 作为下拉选择数据源 相关设置 */
        //显示
        $this->selectTextField = '{id}#{nickname}({mobile})';
        //like查询字段,$this->dataModel->where('username|nickname|mobile', 'like', $kwd);
        $this->selectSearch = 'username|nickname|mobile';
    }

    protected function filterWhere()
    {
        $searchData = request()->post();
        $where = [];
        if (!empty($searchData['id'])) {
            $where[] = ['id', 'eq', $searchData['id']];
        }
        if (!empty($searchData['username'])) {
            $where[] = ['username', 'like', '%' . $searchData['username'] . '%'];
        }
        if (!empty($searchData['nickname'])) {
            $where[] = ['nickname', 'like', '%' . $searchData['nickname'] . '%'];
        }
        if (!empty($searchData['mobile'])) {
            $where[] = ['mobile', 'like', '%' . $searchData['mobile'] . '%'];
        }
        if (isset($searchData['status']) && $searchData['status'] != '') {
            $where[] = ['status', 'eq', $searchData['status']];
        }
        if (isset($searchData['level']) && $searchData['level'] != '') {
            $where[] = ['level', 'eq', $searchData['level']];
        }
        if (!empty($searchData['province'])) {
            $where[] = ['province', 'eq', $searchData['province']];
            if (!empty($searchData['city'])) {
                $where[] = ['city', 'eq', $searchData['city']];
                if (!empty($searchData['area'])) {
                    $where[] = ['area', 'eq', $searchData['area']];
                }
            }
        }
        return $where;
    }

    /**
     * 构建搜索
     *
     * @return void
     */
    protected function builSearch()
    {
        $search = $this->search;

        $search->text('id', '会员id')->maxlength(20);
        $search->text('username', '账号')->maxlength(20);
        $search->text('nickname', '昵称')->maxlength(20);
        $search->text('mobile', '手机号')->maxlength(20);
        $search->select('level', '等级')->optionsData(model\MemberLevel::order('level')->select(), 'name', 'level')->afterOptions([0 => '普通会员']);
        $search->select('status', '状态')->options([0 => '禁用', 1 => '正常']);
        $search->select('province', '省份')->dataUrl(url('api/areacity/province'), 'ext_name')->withNext(
            $search->select('city', '城市')->dataUrl(url('api/areacity/city'), 'ext_name')->withNext(
                $search->select('area', '地区')->dataUrl(url('api/areacity/area'), 'ext_name')
            )
        );
    }

    /**
     * 构建表格
     *
     * @return void
     */
    protected function buildTable(&$data = [])
    {
        $table = $this->table;

        $table->show('id', 'ID');
        $table->image('avatar', '头像')->thumbSize(50, 50)->default('/static/images/touxiang.png');
        $table->show('username', '账号');
        $table->text('nickname', '昵称')->autoPost()->getWrapper()->addStyle('width:130px');
        $table->show('mobile', '手机号')->getWrapper()->addStyle('width:100px');
        $table->match('gender', '性别')->options([1 => '男', 2 => '女', 0 => '未知'])->getWrapper()->addStyle('width:50px');
        $table->show('age', '性别');
        $table->show('level_name', '等级');
        $table->show('money', model\MemberAccount::$types['money']);
        $table->show('points', model\MemberAccount::$types['points']);
        $table->show('pca', '省市区');
        $table->switchBtn('status', '状态')->default(1)->autoPost()->getWrapper()->addStyle('width:60px');
        $table->show('last_login_time', '最近登录')->getWrapper()->addStyle('width:150px');
        $table->show('create_time', '注册时间')->getWrapper()->addStyle('width:150px');

        $table->sortable('id,sort,money,points,commission,re_comm,shares,last_login_time');

        $table->getToolbar()
            ->btnAdd()
            ->btnEnableAndDisable('启用', '禁用')
            ->btnRefresh();

        $table->getActionbar()
            ->btnEdit()
            ->btnView()
            ->btnLink('account', url('/admin/memberaccount/add', ['member_id' => '__data.pk__']), '', 'btn-success', 'mdi-square-inc-cash');
    }

    /**
     * 构建表单
     *
     * @param boolean $isEdit
     * @param array $data
     */
    protected function builForm($isEdit, &$data = [])
    {
        $form = $this->form;

        $form->tab('基本信息');
        $form->image('avatar', '头像')->thumbSize(50, 50);
        $form->text('username', '账号')->required()->maxlength(20);
        $form->text('nickname', '昵称')->required()->maxlength(20);
        $form->text('mobile', '手机号')->maxlength(11);
        $form->text('email', '邮件')->maxlength(60);
        $form->number('age', '年龄')->max(100)->min(1)->default(18);
        $form->radio('gender', '性别')->options([0 => '未知', 1 => '男', 2 => '女'])->default(0);

        $form->tab('其他信息');
        $form->textarea('remark', '备注')->maxlength(255);
        $form->switchBtn('status', '状态')->default(1);

        if ($isEdit) {
            $form->show('last_login_time', '最近登录时间');
            $form->show('create_time', '注册时间');
            $form->show('update_time', '修改时间');
        }
    }

    /**
     * 保存数据
     *
     * @param integer $id
     * @return void
     */
    private function save($id = 0)
    {
        $data = request()->only([
            'avatar',
            'username',
            'nickname',
            'mobile',
            'email',
            'gender',
            'age',
            'status',
            'remark',
        ], 'post');

        $result = $this->validate($data, [
            'username|账号' => 'require',
            'nickname|昵称' => 'require',
            'mobile|手机号' => 'mobile',
            'age|年龄' => 'number',
        ]);

        if (true !== $result) {
            $this->error($result);
        }

        return $this->doSave($data, $id);
    }
}

八.效果展示:








本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 4年前 自动加精
讨论数量: 10

兄弟配置完数据库,扩展安装报错

file

4年前 评论
ichynul (楼主) 4年前
来杯奶茶 (作者) 4年前
来杯奶茶 (作者) 4年前
ichynul (楼主) 4年前
来杯奶茶 (作者) 4年前
ichynul (楼主) 4年前
来杯奶茶 (作者) 4年前

file 6.0的包也是报错

4年前 评论
ichynul (楼主) 4年前

试了下目前只有这个方法可以成功

file

4年前 评论
VeryCool

我也在做类似的 不过 我这个是cms 模型 给 文章 栏目 编辑页面增加扩展用的 :see_no_evil:构思好了 这阵子挺忙没动手

4年前 评论
ichynul (楼主) 4年前

感谢老大给加精华 :kissing_heart:

4年前 评论

感谢大佬文档 安装成功后UI生成的好像比演示网址的少 是版本的问题吗

4年前 评论
ichynul (楼主) 4年前

file
出现了这个是什么问题啊
使用UI生成器生成的,直接报这个错误

4年前 评论
ichynul (楼主) 4年前

file 兄弟更新了一下,卸载插件的时候,提示token错误是什么情情况呀

4年前 评论
ichynul (楼主) 4年前

兄弟演示地址打不开啦

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!