123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540 |
- <?php
- namespace app\common\model\base\models;
- /**
- * @title : Vue代码生成服务
- * @desc :
- * @Author : Rock
- * @Date : 2023-04-19 18:56:57
- */
- use app\common\model\base\menu\Menu;
- use app\common\model\base\menu\Menurequest;
- use think\facade\Db;
- class VueServer
- {
- /**
- * @title: 根据数据表名生成name属性
- * @desc: 描述
- * @param {string} {name} {} {数据表名}
- * @return {*}
- * @author: Rock
- * @method: POST
- * @Date: 2023-04-18 17:09:13
- */
- static protected function getCamel(string $name)
- {
- $name = str_replace(['/','\\'],'_',$name);
- $arr = explode('_',$name);
- $arr = array_filter($arr);
- $classname = "";
- foreach($arr as $item){
- $classname .= ucfirst($item);
- }
- return $classname;
- }
- /**
- * @title: 根据数据表名生成短横线链接的类名,组件名
- * @desc: 描述
- * @param {string} $name
- * @return {*}
- * @author: Rock
- * @method: POST
- * @Date: 2023-05-04 15:22:21
- */
- static protected function getLine(string $name)
- {
- return str_replace(['/','\\','_'],'-',$name);
- }
- /**
- * @title: 格式化dir路径
- * @desc: 描述
- * @param {string} $dirname
- * @return {*}
- * @author: Rock
- * @method: POST
- * @Date: 2023-04-24 14:46:37
- */
- static protected function parseDirname(string $dirname)
- {
- return !empty($dirname)?explode(DS,str_replace(['/','\\'],DS,$dirname))[0]:'';
- }
- /**
- * @title: 生成接口文件
- * @desc: 描述
- * @return {*}
- * @author: Rock
- * @method: POST
- * @Date: 2023-04-20 10:38:37
- */
- static public function createApiJS(int $model_id)
- {
- $info = ModelManage::where('id',$model_id)->find();
- $classname = self::getCamel($info->name);
- $dirname = self::parseDirname($info->dirname);
- $url = !empty($dirname)?str_replace('/','.',$dirname).'.'.$classname:$classname;
- $path = !empty($dirname)?root_path()."public".DS."vue".DS."src".DS."api".DS.$dirname.DS:root_path()."public".DS."vue".DS."src".DS."api".DS;
- if(!is_dir($path)){
- mkdir($path,0777,true);
- }
- $filename = $path.$classname.'.js';
- $content = <<<APIJS
- import request from '@/utils/request'
- export function getList(data) {
- return request({
- url: '/$url/getList',
- method: 'post',
- data,
- })
- }
- export function getTree(data) {
- return request({
- url: '/$url/getTree',
- method: 'post',
- data,
- })
- }
- export function getInfo(data) {
- return request({
- url: '/$url/getInfo',
- method: 'post',
- data,
- })
- }
- export function doEdit(data) {
- return request({
- url: '/$url/doEdit',
- method: 'post',
- data,
- })
- }
- export function doDelete(data) {
- return request({
- url: '/$url/doDelete',
- method: 'post',
- data,
- })
- }
- export function doExport(data) {
- return request({
- url: '/$url/doExport',
- method: 'post',
- data,
- })
- }
- export function getOptions(data) {
- return request({
- url: '/$url/getOptions',
- method: 'post',
- data,
- })
- }
- export function changeStatus(data) {
- return request({
- url: '/$url/changeStatus',
- method: 'post',
- data,
- })
- }
- APIJS;
- FileServer::writeLine($filename,$content);
- }
- /**
- * @title: 创建菜单和菜单请求
- * @desc: 描述
- * @param {int} {model_id} {} {模型ID}
- * @return {*}
- * @author: Rock
- * @method: POST
- * @Date: 2023-04-21 15:41:21
- */
- static public function createMenu(int $model_id)
- {
- $info = ModelManage::where('id',$model_id)->find();
- $menuModel = new Menu;
- $requestModel = new Menurequest;
- $methods = ['getList','getInfo','doEdit','doDelete','changeStatus','doExport'];
- $classname = self::getCamel($info->name);
- $dirname = self::parseDirname($info->dirname);
- $hasParent = $menuModel->where('path','/'.$dirname)->find();
- $url = !empty($dirname)?str_replace('/','.',$dirname).'.'.$classname:$classname;
- $component = "@/views/".$dirname.'/'.$classname;//根据vue页面文件判断是否已经有这个菜单了,当模型的存放路径dirname或数据表名name有变动时,原有的菜单需要在模型编辑时删除
- $has = $menuModel->where('component',$component)->find();
- $menuData = [
- 'pid' => $hasParent?$hasParent->menu_id:0,
- 'parentName' => $hasParent?$hasParent->title:'顶级菜单',
- 'name' => $classname,
- 'path' => '/'.$dirname.'/'.$classname,
- 'component' => '@/views/'.$dirname.'/'.$classname,
- 'redirect' => '',
- 'title' => $info->title,
- 'icon' => '',
- 'badge' => '',
- 'sort' => 0,
- 'is_root' => 2,
- 'hidden' => 2,
- 'alwaysShow' => 1,
- 'isCustomSvgIcon' => 2,
- 'affix' => 2,
- 'noKeepAlive' => 1,
- 'tabHidden' => 2,
- 'parent_path' => $hasParent?$hasParent->parent_path:'',
- ];
- if($has){
- $menuData['menu_id'] = $has->menu_id;
- }
- $parentData = [];
- if(!$hasParent){
- $parentData = [
- 'pid' => 0,
- 'parentName' => '顶级菜单',
- 'name' => $classname.'Manage',
- 'path' => '/'.$dirname,
- 'component' => 'Layout',
- 'redirect' => $dirname.'/'.$classname,
- 'title' => self::getCamel(str_replace(DS,'',$dirname)),
- 'icon' => '',
- 'badge' => '',
- 'sort' => 0,
- 'is_root' => 1,
- 'hidden' => 2,
- 'alwaysShow' => 1,
- 'isCustomSvgIcon' => 2,
- 'affix' => 2,
- 'noKeepAlive' => 1,
- 'tabHidden' => 2,
- 'parent_path' => '',
- ];
- }
- try{
- Db::startTrans();
- $pres = null;
- if(!empty($parentData)){
- $res = Menu::create($parentData);
- $pid = $res->menu_id;
- $menuData['pid'] = $pid;
- Menu::where('menu_id',$pid)->update(['parent_path'=>$pid]);
- $menuData['parent_path'] = $pid;
- }
- $menuModel->replace()->save($menuData);
- $menu_id = $menuModel->menu_id;
- $info = Menu::find($menu_id);
- $parent_path = array_filter(explode(',',$info->parent_path));
- $parent_path[] = $menu_id;
- $info->parent_path = implode(',',$parent_path);
- $info->save();
- $oldRequest = $requestModel->where('menu_id',$menu_id)->column('*','operate');
- $requestData = [];
- foreach($methods as $method){
- $requestItem = [
- 'menu_id' => $menu_id,
- 'name' => '',
- 'path' => '',
- 'model' => 1,
- 'operate' => '',
- 'status' => 1
- ];
- switch($method){
- case 'getList':
- if(isset($oldRequest['READ'])){
- $requestItem['menu_request_id'] = $oldRequest['READ']['menu_request_id'];
- }
- $requestItem['name'] = '查看';
- $requestItem['operate'] = 'READ';
- $requestItem['path'] = '/'.$url.'/'.$method;
- $requestData[] = $requestItem;
- break;
- case 'getInfo':
- if(isset($oldRequest['INFO'])){
- $requestItem['menu_request_id'] = $oldRequest['INFO']['menu_request_id'];
- }
- $requestItem['name'] = '信息';
- $requestItem['operate'] = 'INFO';
- $requestItem['path'] = '/'.$url.'/'.$method;
- $requestData[] = $requestItem;
- break;
- case 'doEdit':
- if(isset($oldRequest['ADD'])){
- $requestItem['menu_request_id'] = $oldRequest['ADD']['menu_request_id'];
- }
- $requestItem['name'] = '添加';
- $requestItem['operate'] = 'ADD';
- $requestItem['path'] = '/'.$url.'/'.$method;
- $requestData[] = $requestItem;
- if(isset($oldRequest['EDIT'])){
- $requestItem['menu_request_id'] = $oldRequest['EDIT']['menu_request_id'];
- }
- $requestItem['name'] = '编辑';
- $requestItem['operate'] = 'EDIT';
- $requestItem['path'] = '/'.$url.'/'.$method;
- $requestData[] = $requestItem;
- break;
- case 'doDelete':
- if(isset($oldRequest['DELETE'])){
- $requestItem['menu_request_id'] = $oldRequest['DELETE']['menu_request_id'];
- }
- $requestItem['name'] = '删除';
- $requestItem['operate'] = 'DELETE';
- $requestItem['path'] = '/'.$url.'/'.$method;
- $requestData[] = $requestItem;
- break;
- case 'changeStatus':
- if(isset($oldRequest['STATUS'])){
- $requestItem['menu_request_id'] = $oldRequest['STATUS']['menu_request_id'];
- }
- $requestItem['name'] = '启用禁用';
- $requestItem['operate'] = 'STATUS';
- $requestItem['path'] = '/'.$url.'/'.$method;
- $requestData[] = $requestItem;
- break;
- case 'doExport':
- if(isset($oldRequest['EXPORT'])){
- $requestItem['menu_request_id'] = $oldRequest['EXPORT']['menu_request_id'];
- }
- $requestItem['name'] = '导出';
- $requestItem['operate'] = 'EXPORT';
- $requestItem['path'] = '/'.$url.'/'.$method;
- $requestData[] = $requestItem;
- break;
- }
- }
- $res = $requestModel->replace()->saveAll($requestData);
- Db::commit();
- return $res;
- }catch(\Exception $e){
- Db::rollback();
- abort(2,$e->getMessage());
- return false;
- }
- }
- /**
- * @title: 删除模型的apijs文件
- * @desc: 描述
- * @param {int} $model_id
- * @return {*}
- * @author: Rock
- * @method: POST
- * @Date: 2023-04-23 17:29:56
- */
- static public function deleteAPI(int $model_id)
- {
- $info = ModelManage::where('id',$model_id)->find();
- $classname = self::getCamel($info->name);
- $dirname = self::parseDirname($info->dirname);
- $path = !empty($dirname)?root_path()."public".DS."vue".DS."src".DS."api".DS.$dirname.DS:root_path()."public".DS."vue".DS."src".DS."api".DS;
- $filename = $path.$classname.'.js';
- if(file_exists($filename)){
- @unlink($filename);
- }
- }
- /**
- * @title: 删除菜单及菜单请求
- * @desc: 描述
- * @param {int} $model_id
- * @return {*}
- * @author: Rock
- * @method: POST
- * @Date: 2023-04-23 17:30:31
- */
- static public function deleteMenu(int $model_id)
- {
- $info = ModelManage::where('id',$model_id)->find();
- $menuModel = new Menu;
- $requestModel = new Menurequest;
- $classname = self::getCamel($info->name);
- $dirname =self::parseDirname( $info->dirname);
- $component = "@/views/".$dirname.'/'.$classname;//根据vue页面文件判断是否已经有这个菜单了,当模型的存放路径dirname或数据表名name有变动时,原有的菜单需要在模型编辑时删除
- $has = $menuModel->where('component',$component)->find();
- if($has){
- $requestModel::destroy(function($query)use($has){
- $query->where('menu_id',$has->menu_id);
- });
- $has->delete();
- }
- }
- /**
- * @title: 删除选择器代码
- * @desc: 描述
- * @param {int} $model_id
- * @return {*}
- * @author: Rock
- * @method: POST
- * @Date: 2023-07-25 17:02:36
- */
- static public function deleteSelector(int $model_id)
- {
- $info = ModelManage::where('id',$model_id)->find();
- $name = $info->name;
- $dirname = self::parseDirname($info->dirname);// 文件保存位置
- $classname = self::getCamel($info->name);// 获取类名
- if(!empty($dirname)){
- $path = root_path()."public".DS."vue".DS."src".DS."views".DS.$dirname.DS.$classname.DS.'components'.DS;
- }else{
- $path = root_path()."public".DS."vue".DS."src".DS."views".DS.$classname.DS.'components'.DS;
- }
- $filename = $path.'Selector.vue';
- if(file_exists($filename)){
- @unlink($filename);
- }
- }
- /**
- * @title: 创建选择器代码
- * @desc: 描述
- * @return {*}
- * @author: Rock
- * @method: POST
- * @Date: 2023-04-27 11:23:32
- */
- static public function createSelector(int $model_id)
- {
- $info = ModelManage::where('id',$model_id)->find();
- $name = self::getLine($info->name);
- $pk = ModelManage::pk($info->name);
- $dirname = self::parseDirname($info->dirname);// 文件保存位置
- $classname = self::getCamel($info->name);// 获取类名
- $apiJS = "@/api/$dirname/$classname";
- if(!empty($dirname)){
- $path = root_path()."public".DS."vue".DS."src".DS."views".DS.$dirname.DS.$classname.DS.'components'.DS;
- }else{
- $path = root_path()."public".DS."vue".DS."src".DS."views".DS.$classname.DS.'components'.DS;
- }
- if(!is_dir($path)){
- mkdir($path,0777,true);
- }
- $filename = $path.'Selector.vue';
- $content = <<<SELECTOR
- <template>
- <el-select
- ref="$name-select"
- v-model="title"
- :clearable="true"
- :collapse-tags="false"
- filterable
- :multiple="multiple"
- placeholder="请选择"
- style="width: 100%"
- @clear="clear"
- >
- <el-option label="请选择" style="height: auto; padding: 0" :value="0">
- <el-tree
- ref="$name-tree"
- :accordion="true"
- :data="list"
- :highlight-current="true"
- node-key="$pk"
- :props="{
- children: 'children',
- label: labelField,
- isLeaf: 'hasChildren',
- }"
- :show-checkbox="multiple"
- @check-change="handleNodeCheck"
- @node-click="handleNodeClick"
- />
- </el-option>
- </el-select>
- </template>
- <script>
- import { getTree } from '$apiJS'
- import { isArray } from '@/utils/validate'
- export default {
- name:'{$classname}Selector',
- components:{},
- props: {
- value: {
- type: [Number,String,Array],
- default: 0,
- require: false,
- },
- labelField:{
- type:String,
- default:'name',
- require:true,
- },
- multiple:{
- type:Boolean,
- default:false,
- require:false,
- },
- },
- data(){
- return {
- loading:false,
- val:0,
- title:'请选择',
- list:[],
- }
- },
- watch:{
- value:{
- handler(n){
- this.val = n
- this.setDefault(n, this.list)
- },
- },
- },
- created() {
- this.val = this.multiple ? [] : ''
- this.title = this.multiple ? [] : ''
- },
- mounted(){
- this.\$nextTick(()=>{
- this.fetchTree()
- })
- },
- methods:{
- // 设置默认显示
- setDefault(defVal, list) {
- list.forEach((element) => {
- if (this.multiple && isArray(defVal)) {
- defVal.forEach((val) => {
- if (element.$pk == val) {
- this.title.push(element[this.labelField])
- this.title = [...new Set(this.title)]
- }
- })
- } else if (parseInt(element.$pk) == parseInt(defVal)) {
- this.title = element[this.labelField]
- }
- if (element.children) {
- this.setDefault(defVal, element.children)
- }
- })
- },
- async fetchTree(){
- this.loading = true
- const {data} = await getTree({labelField:this.labelField})
- this.list = data
- this.loading = false
- if (this.multiple && isArray(this.value)) {
- this.\$refs['$name-tree'].setCheckedKeys(this.value)
- }
- this.setDefault(this.value,this.list)
- },
- handleNodeClick(node){
- this.val = node.$pk
- this.title = node[this.labelField]
- this.\$emit('input', this.val)
- this.\$refs['$name-select'].blur()
- },
- handleNodeCheck() {
- this.val = this.\$refs['$name-tree'].getCheckedKeys()
- let nodes = this.\$refs['$name-tree'].getCheckedNodes()
- let titles = []
- nodes.forEach((node) => {
- titles.push(node[this.labelField])
- })
- this.title = titles
- this.\$emit('input', this.val)
- },
- clear(){
- this.val = 0
- this.\$emit('input',this.val)
- },
- }
- }
- </script>
- SELECTOR;
- FileServer::writeLine($filename,$content);
- return true;
- }
- }
|