vue3+webman 管理后台,自动代码生成

199¥
类型 完整应用
版本 1.0.2
版本更新时间 15天前
大小 2.42 MB
开发商
快易乐
评分

详细介绍

一套用于快速起新项目的基础框架,后台前端采用vue3+TS,后端采用webman
已经内置的功能包括:
1.登录
2.权限管理(用户,角色,权限,部门;可对角色授权以及对用户直接授权,权限精确到操作)
3.待办和通知消息
4.文章管理
5.操作日志,登录日志
6.配置
7.队列(基于redis)
8.websocket(可主动推消息到前端)
9.回收站功能(代码生成时自动检查是否有deleted_at字段,前端组件只需一个参数即可支持回收站功能)
10.数据导入导出(任何列表页只需要在前端组件调用时加一个参数,即可实现数据导出功能,可自定义导出表头)
11.丰富的命令行工具(根据数据表自动生成完整业务代码,本框架的特色,下面详细介绍)

演示地址
超级管理员:admin 密码:admin123
部分权限账号:yunying 密码:admin123

功能特性

1.代码生成

框架前后端的都有一套完整的扩展性极强的基础控件,很少的代码即可支持大部分场景下的增删改查,基于此再实现了一套命令,可以根据数据表通过命令直接生成对应的增删改查代码,为开发节约大量时间,让我们把更多时间用在项目设计及架构上面

例如有一张表 example, 它的字段包括

CREATE TABLE `example` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '名称',
  `example_cate_id` int unsigned NOT NULL DEFAULT 0 COMMENT '分类',
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  `deleted_at` datetime DEFAULT NULL,
  `status` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '状态',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `title` (`title`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

通过命令php webman model example生成的模型文件内容如下

<?php

declare(strict_types=1);

namespace app\model;

use app\common\traits\StatusAttr;

/**
 * @property int $id
 * @property string $title 名称
 * @property int $example_cate_id 分类
 * @property ?string $created_at
 * @property ?string $updated_at
 * @property ?string $deleted_at
 * @property int $status 状态
 */
class Example extends BaseModel
{
    use StatusAttr;

    protected $table = 'example';

    protected $pk = 'id';

    protected $field = [
        'id',
        'title',
        'example_cate_id',
        'created_at',
        'updated_at',
        'deleted_at',
        'status',
    ];

    protected $type = [];
}

通过命令php webman controller example --title 示例生成的控制器文件内容如下,index接口自动支持所有字段搜索排序,columns为前端表格的表头,可根据前端组件自动调整是否支持搜索和排序;Permission注解即权限管理,对需要控制权限的方法加上注解,通过命令php webman permission example 即可生成对应的权限

<?php

declare(strict_types=1);

namespace app\admin\controller;

use app\common\annotation\Permission;
use app\common\traits\CrudHelper;
use app\common\traits\Jump;
use app\common\traits\RecycleAction;
use app\common\traits\ValidateHelper;
use app\model\Example as Model;
use support\Request;
use support\Response;

class ExampleController
{
    use Jump;
    use CrudHelper;
    use ValidateHelper;
    use RecycleAction;

    #[Permission(title: '示例', isMenu: 1, parentUrl: 'system')]
    public function index(Request $request): Response
    {
        $lists = $this->tableList($request, Model::class, ['id' => 'DESC'], ['title'])
            ->selectData($request);
        return $this->success('', [
            'list' => $lists,
        ]);
    }

    #[Permission(title: '修改示例')]
    public function edit(Request $request): Response
    {
        return $this->mEdit($request, Model::class);
    }

    #[Permission(title: '添加示例')]
    public function add(Request $request): Response
    {
        return $this->mAdd($request, Model::class);
    }

    #[Permission(title: '删除示例')]
    public function delete(Request $request): Response
    {
        return $this->mDelete($request, Model::class);
    }

    #[Permission(title: '彻底删除示例')]
    public function forceDelete(Request $request): Response
    {
        return $this->mForceDelete($request, Model::class);
    }

    #[Permission(title: '恢复示例')]
    public function restore(Request $request): Response
    {
        return $this->mRestore($request, Model::class);
    }

    #[Permission(title: '清空示例回收站')]
    public function cleanRecycle(Request $request): Response
    {
        return $this->mCleanRecycle($request, Model::class);
    }

    public function get(Request $request): Response
    {
        return $this->success('', [
            'detail' => Model::find(input('id')),
        ]);
    }

    #[Permission(title: '修改示例状态')]
    public function status(Request $request): Response
    {
        $status = input('status', 0);
        Model::update(['status' => $status], ['id' => $this->getInputPk($request)]);
        return $this->success('修改成功', ['status' => $status]);
    }

    public function select(Request $request): Response
    {
        return $this->success('', [
            'list' => $this->tableList($request, Model::class)->field('title as label,id as value')->select(),
        ]);
    }

    public function columns(Request $request): array
    {
        return [
            [
                'prop' => 'id',
                'label' => 'ID',
                'search' => [
                    'prop' => 'id_match',
                ],
            ],
            [
                'prop' => 'title',
                'label' => '名称',
                'search' => [
                    'prop' => 'title_like',
                ],
            ],
            [
                'prop' => 'example_cate_id',
                'label' => '分类',
                'sort' => 'example_cate_id',
                'search' => [
                    'valueType' => 'select',
                    'prop' => 'example_cate_id_multiple',
                    'optionsConfig' => [
                        'url' => '/example_cate/select',
                        'key' => '',
                    ],
                    'fieldProps' => [
                        'multiple' => true,
                    ],
                ],
                'replace' => true,
            ],
            $this->getDateSearchColumns('created_at', '日期'),
            $this->getStatusColumns('status', '状态'),
        ];
    }
}

通过命令php webman view example生成的vue3文件内容如下

  • 列表页
<script setup lang="ts">
defineOptions({ name: "ExampleIndex" });
import ExampleAddDialog from "@/views/example/dialog/exampleAddDialog.vue";
import { ref } from "vue";

const addDialogRef = ref();
const tableRef = ref();
const handleEdit = row => {
  addDialogRef.value.open(row);
};
const afterDone = () => {
  tableRef.value.refresh();
};
</script>

<template>
  <div>
    <KylTable
      ref="tableRef"
      base-url="/example"
      recycle
      @add="handleEdit({})"
      @edit="handleEdit"
    />
    <ExampleAddDialog ref="addDialogRef" @done="afterDone" />
  </div>
</template>
  • 弹窗编辑页面
<script setup lang="ts">
import { FieldValues } from "plus-pro-components";
import { computed, ref } from "vue";
import { useOptionsStoreHook } from "@/store/modules/Options";
import { KylFormColumn } from "@/components/KylForm/types/form";
const emit = defineEmits<{
  (e: "done", value: FieldValues): void;
  (e: "cancel"): void;
}>();
export interface Props {
  module?: string;
  title?: string;
}
const props = withDefaults(defineProps<Props>(), {
  module: "/example",
  title: "添加/编辑"
});
const action = computed(() => {
  return props.module + "/" + (state.value.id ? "edit" : "add");
});
const initValue = () => ({
  id: undefined,
  title: "",
  example_cate_id: undefined,
  status: 1
});
const state = ref<FieldValues>(initValue());
const columns: KylFormColumn[] = [
  {
    prop: "id",
    hideInForm: true
  },
  {
    label: "名称",
    prop: "title",
    required: true
  },
  {
    label: "分类",
    prop: "example_cate_id",
    valueType: "select",
    required: true,
    options: useOptionsStoreHook().getOptionsList("/example_cate/select")
  },
  {
    label: "状态",
    prop: "status",
    valueType: "status",
    required: true
  }
];
const visible = ref(false);
const rules = {};
const handleSubmit = (values: FieldValues) => {
  useOptionsStoreHook().clearOptionsCache(props.module + "/select");
  emit("done", values);
};
const open = data => {
  visible.value = true;
  state.value = { ...initValue(), ...data };
};
defineExpose({
  open
});
</script>
<template>
  <KylDialogForm
    v-model:visible="visible"
    v-model="state"
    v-bind="$attrs"
    :action="action"
    :columns="columns"
    :rules="rules"
    :title="title"
    @submit="handleSubmit"
    @cancel="emit('cancel')"
  />
</template>

2.通用组件

  1. 后端有一套丰富的trait,包含CRUD、上传等常见操作;还有表格导入,表格导出的扩展类。
  2. 前端最常用两个功能:表格和表单,都有功能非常强大的组件;
    • 表格组件可通过接口动态生成表头或者自定义表头,根据表头配置自动生成排序和搜索表单,支持回收站、导出、表头排序显示隐藏设置等,可覆盖90%的场景使用场景,针对特别特殊的场景也有丰富的插槽可实现任意表格显示需求。
    • 表单组件是通过配置生成表单,告别繁琐的html代码,直接通过ts代码实现表单功能,可看前一部分的弹窗编辑页面的代码示例,表单支持绝大多数场景下的使用需求,基于PlusProComponents扩展了更多组件,包括数字范围输入、上传(单文件,多文件)、富文本、单值级联、segmented等等。表单组件还有一套弹窗表单组件。

安装使用

本框架只适用于二次开发,没有完整的业务功能,解压后webman目录为后端代码,admin目录为前端代码

联系方式

281313840@qq.com

版本历史记录
1.0.2
15天前
修改了部分页面显示
1.0.1
17天前
去掉runtime下无效文件
1.0.0
17天前
全新框架
后端PHP>=8.2
前端vue3+TS
评分及评论
0 满分5分
🔝