From 12a7e2186feee6c34c48ce9c06eaf07f7fbb4738 Mon Sep 17 00:00:00 2001 From: xy <271556543@qq.com> Date: Fri, 28 Mar 2025 09:49:38 +0800 Subject: [PATCH] init --- script/apiTemplate.ejs | 37 ++ script/create.js | 80 ++++ script/drawerTemplate.ejs | 297 +++++++++++++ script/index.js | 6 + script/showTemplate.ejs | 155 +++++++ script/tableTemplate.ejs | 606 +++++++++++++++++++++++++++ script/tables.js | 852 ++++++++++++++++++++++++++++++++++++++ script/utils.js | 40 ++ 8 files changed, 2073 insertions(+) create mode 100644 script/apiTemplate.ejs create mode 100644 script/create.js create mode 100644 script/drawerTemplate.ejs create mode 100644 script/index.js create mode 100644 script/showTemplate.ejs create mode 100644 script/tableTemplate.ejs create mode 100644 script/tables.js create mode 100644 script/utils.js diff --git a/script/apiTemplate.ejs b/script/apiTemplate.ejs new file mode 100644 index 0000000..60acc31 --- /dev/null +++ b/script/apiTemplate.ejs @@ -0,0 +1,37 @@ +import request from '@/utils/request' + +export function index(params,isLoading = true) { + return request({ + method: 'get', + url: '/api/admin/<%- data.name %>/index', + params, +isLoading + }) +} + +export function show(params,isLoading = true) { + return request({ + method: 'get', + url: '/api/admin/<%- data.name %>/show', + params, + isLoading + }) +} + +export function save(data, isLoading = true) { + return request({ + method: 'post', + url: '/api/admin/<%- data.name %>/save', + data, + isLoading + }) +} + +export function destroy(params, isLoading = true) { + return request({ + method: 'get', + url: '/api/admin/<%- data.name %>/destroy', + params, + isLoading + }) +} diff --git a/script/create.js b/script/create.js new file mode 100644 index 0000000..90b0f20 --- /dev/null +++ b/script/create.js @@ -0,0 +1,80 @@ +const {compiler, resolveName, ensureDirectoryExistence, writeFile} = require("./utils"); +const path = require("path"); +const fs = require("fs"); +const moment = require('moment'); +const { t } = require("./tables") + +async function createTable(name, fields, options) { + const fileRes = await compiler("tableTemplate.ejs", { + name: resolveName(name), + originalName: name, + fields, + options + }) + ensureDirectoryExistence(path.resolve(__dirname, `../src/views/${resolveName(name)}`)) + const filePath = path.resolve(__dirname, `../src/views/${resolveName(name)}`, `${resolveName(name)}.vue`) + + await writeFile(filePath, fileRes) +} +async function createDrawer(name, fields, options) { + const fileRes = await compiler("drawerTemplate.ejs", { + name: resolveName(name), + originalName: name, + fields, + options + }) + ensureDirectoryExistence(path.resolve(__dirname, `../src/views/${resolveName(name)}`)) + ensureDirectoryExistence(path.resolve(__dirname, `../src/views/${resolveName(name)}/components`)) + const filePath = path.resolve(__dirname, `../src/views/${resolveName(name)}/components`, `Add${resolveName(name)}.vue`) + + await writeFile(filePath, fileRes) +} +async function createDetail(name, fields, options) { + const fileRes = await compiler("showTemplate.ejs", { + name: resolveName(name), + originalName: name, + fields, + options + }) + ensureDirectoryExistence(path.resolve(__dirname, `../src/views/${resolveName(name)}`)) + ensureDirectoryExistence(path.resolve(__dirname, `../src/views/${resolveName(name)}/components`)) + const filePath = path.resolve(__dirname, `../src/views/${resolveName(name)}/components`, `Show${resolveName(name)}.vue`) + + await writeFile(filePath, fileRes) +} +async function createApi(name) { + const fileRes = await compiler("apiTemplate.ejs", { + name + }) + ensureDirectoryExistence(path.resolve(__dirname, `../src/api/${name}`)) + const filePath = path.resolve(__dirname, `../src/api/${name}`, `${name}.js`) + + await writeFile(filePath, fileRes) +} + +function create(name, fields, options) { + try { + createApi(name) + createTable(name, fields, options) + createDrawer(name, fields, options) + createDetail(name, fields, options) + t[name] = { + fields, + options + } + const textPath = path.resolve(__dirname, './log.txt') + if (!fs.existsSync(textPath)) { + fs.writeFileSync(textPath, '') + } + fs.appendFileSync(textPath, name + '\n', 'utf8') + fs.appendFileSync(textPath, JSON.stringify(fields) + '\n', 'utf8') + fs.appendFileSync(textPath, JSON.stringify(options) + '\n', 'utf8') + fs.appendFileSync(textPath, moment().format('YYYY-MM-DD HH:mm:ss') + '\n', 'utf8') + } catch (err) { + console.error(err) + } +} + +module.exports = { + create +} diff --git a/script/drawerTemplate.ejs b/script/drawerTemplate.ejs new file mode 100644 index 0000000..00021a6 --- /dev/null +++ b/script/drawerTemplate.ejs @@ -0,0 +1,297 @@ +<% function handleFormName(name) { + if (/-/.test(name)) { + let arrs = name.split("-") + return arrs.reduce((pre, cur, index) => pre + (index === 0 ? cur : (cur.charAt(0).toUpperCase() + cur.slice(1))), '') + } else { + return name + } +} %> + + + + + diff --git a/script/index.js b/script/index.js new file mode 100644 index 0000000..4ff97af --- /dev/null +++ b/script/index.js @@ -0,0 +1,6 @@ +const { t } = require('./tables') + +const { create } = require('./create') +const createName = 'recommend' +const { fields, options } = t['recommend'] +create(createName, fields, options) diff --git a/script/showTemplate.ejs b/script/showTemplate.ejs new file mode 100644 index 0000000..d9387cb --- /dev/null +++ b/script/showTemplate.ejs @@ -0,0 +1,155 @@ +<% function handleFormName(name) { + if (/-/.test(name)) { + let arrs = name.split("-") + return arrs.reduce((pre, cur, index) => pre + (index === 0 ? cur : (cur.charAt(0).toUpperCase() + cur.slice(1))), '') + } else { + return name + } +} %> + + + + + diff --git a/script/tableTemplate.ejs b/script/tableTemplate.ejs new file mode 100644 index 0000000..47cade2 --- /dev/null +++ b/script/tableTemplate.ejs @@ -0,0 +1,606 @@ +<% function handleFormName(name) { + if (/-/.test(name)) { + let arrs = name.split("-") + return arrs.reduce((pre, cur, index) => pre + (index === 0 ? cur : (cur.charAt(0).toUpperCase() + cur.slice(1))), '') + } else { + return name + } +} %> + + + + + diff --git a/script/tables.js b/script/tables.js new file mode 100644 index 0000000..6eb71d9 --- /dev/null +++ b/script/tables.js @@ -0,0 +1,852 @@ +const t = { + user: { + fields: [ + { + name: 'white', + label: '是否填报白名单', + type: 'input' + }, + { + name: 'nickname', + label: '昵称', + type: 'input', + }, + { + name: 'openid', + label: 'openid', + type: 'input', + }, + { + name: 'headimgurl', + label: '头像地址', + type: 'input', + }, + { + name: 'mobile', + label: '手机号', + type: 'input', + rules: [ + { required: true }, + { pattern: /(^$)|(^1[3456789]\d{9})|(^(0\d{2,3}(-)*)?\d{7})$/ } + ] + }, + { + name: 'sex', + label: '性别', + type: 'select', + optionsParams: [ + { + value: '男', + label: '男' + }, + { + value: '女', + label: '女' + }, + { + value: '保密', + label: '保密' + } + ] + }, + { + name: 'area', + label: '区县', + type: 'input', + }, + { + name: 'province', + label: '省份', + type: 'input', + }, + { + name: 'city', + label: '城市', + type: 'input', + }, + { + name: 'name', + label: '学生姓名', + type: 'input', + }, + { + name: 'grade', + label: '年级', + type: 'input', + }, + { + name: 'middle_exam_year', + label: '中考年份', + type: 'date', + props: { + type: 'year' + } + }, + { + name: 'nationality', + label: '民族', + type: 'input', + }, + { + name: 'school', + label: '学校', + type: 'input', + }, + ] + }, + area: { + fields: [ + { + name: 'name', + label: '名称', + type: 'input' + }, + { + name: 'group', + label: '分组', + type: 'input' + } + ] + }, + school: { + fields: [ + { + name: 'name', + label: '学校名称', + type: 'input', + rules: [ + { + required: true + } + ] + }, + { + name: 'area_id', + label: '区域', + type: 'select', + optionsFrom: 'area', + optionProps: { + value: 'id', + label: 'name' + }, + rules: [ + { + required: true + } + ] + }, + { + name: 'code', + label: '学校代码', + type: 'input' + }, + { + name: 'star', + label: '星级', + type: 'input' + }, + { + name: 'address', + label: '地址', + type: 'input' + }, + { + name: 'nature', + label: '性质', + type: 'select', + optionsParams: [ + { + value: 1, + label: '公办' + }, + { + value: 2, + label: '民办' + } + ] + }, + { + name: 'type', + label: '学校类型', + type: 'select', + optionsParams: ['初中', '中专', '3+3', '五年制大专', '中本贯通5+2', '中本贯通3+4', '综合高中', '高中'].map(i => ({ label: i, value: i })), + props: { + multiple: true + } + }, + { + name: 'build_year', + label: '建校年份', + type: 'input' + }, + { + name: 'introduce', + label: '学校介绍', + type: 'richtext' + }, + { + name: 'teacher', + label: '教师信息', + type: 'richtext' + }, + ] + }, + score: { + fields: [ + { + name: 'code', + label: '代码', + type: 'input' + }, + { + name: 'school_id', + label: '所属学校', + type: 'select', + optionsFrom: 'school', + optionProps: { + value: 'id', + label: 'name' + }, + }, + { + name: 'year', + label: '年份', + type: 'date', + props: { + type: 'year' + } + }, + { + name: 'total_score', + label: '统招总分', + type: 'input-number' + }, + { + name: 'main_score', + label: '统招语数外', + type: 'input-number' + }, + { + name: 'area_total_score', + label: '跨区总分', + type: 'input-number' + }, + { + name: 'area_main_score', + label: '跨区语数外', + type: 'input-number' + }, + ] + }, + "middle-school-indicator": { + fields: [ + { + name: "school_id", + label: "学校", + type: "select", + optionsFrom: 'school', + optionProps: { + value: 'id', + label: 'name' + }, + }, + { + name: 'year', + label: '年份', + type: 'date', + props: { + type: 'year' + } + }, + { + name: 'total', + label: '总分', + type: 'input-number' + }, + { + name: 'details', + label: '详情', + type: 'input' + }, + ] + }, + "specialty": { + fields: [ + { + name: "code", + label: "专业代码", + type: "input" + }, + { + name: "school_id", + label: "学校", + type: "select", + optionsFrom: 'school', + optionProps: { + value: 'id', + label: 'name' + }, + }, + { + name: "name", + label: "名称", + type: "input" + }, + { + name: "content", + label: "内容", + type: "textarea" + }, + ] + }, + "batch": { + fields: [ + { + name: "name", + label: "名称", + type: "input" + }, + { + name: 'aspiration_id', + label: '归属总表', + type: 'select', + optionsFrom: 'aspiration', + optionProps: { + value: 'id', + label: 'name' + }, + rules: [ + { + required: true + } + ] + }, + { + name: "sort", + label: "排序", + type: "input-number" + }, + ] + }, + "independent-recruitment": { + "fields": [ + { + name: "name", + label: "名称", + type: "input", + rules: [ + { required: true }, + ] + }, + { + name: 'area_id', + label: '区域', + type: 'select', + optionsFrom: 'area', + optionProps: { + value: 'id', + label: 'name' + }, + rules: [ + { + required: true + } + ] + }, + { + name: 'year', + label: '年份', + type: 'date', + props: { + type: 'year' + } + }, + { + name: 'sex', + label: '性别', + type: 'select', + optionsParams: [ + { + value: '男', + label: '男' + }, + { + value: '女', + label: '女' + }, + { + value: '保密', + label: '保密' + } + ] + }, + { + name: "number", + label: "编号", + type: "input" + }, + { + name: "type", + label: "考试类型", + type: "input" + }, + { + name: "nationality", + label: "民族", + type: "input" + }, + { + name: "address", + label: "地址", + type: "textarea" + }, + { + name: 'mobile', + label: '手机号', + type: 'input', + rules: [ + { pattern: /(^$)|(^1[3456789]\d{9})|(^(0\d{2,3}(-)*)?\d{7})$/ } + ] + }, + { + name: "school", + label: "学校", + type: "input" + }, + { + name: "school_code", + label: "学校代码", + type: "input" + }, + { + name: "school_name", + label: "学校名称", + type: "input" + }, + { + name: 'is_independent', + label: '是否独立招生', + type: 'select', + optionsParams: [ + { + value: 1, + label: '是' + }, + { + value: 0, + label: '否' + } + ] + }, + { + name: "evaluation", + label: "评估信息", + type: "textarea" + } + ] + }, + "aspiration": { + fields: [ + { + name: "name", + label: "名称", + type: "input", + rules: [ + { required: true }, + ] + }, + { + name: 'area_id', + label: '区域', + type: 'select', + optionsFrom: 'area', + optionProps: { + value: 'id', + label: 'name' + }, + rules: [ + { + required: true + } + ] + }, + { + name: 'year', + label: '年份', + type: 'date', + props: { + type: 'year', + 'valueFormat': 'yyyy' + } + }, + { + name: "title", + label: "标题", + type: "input", + rules: [ + { required: true }, + ] + }, + { + name: "remark", + label: "备注", + type: "textarea" + }, + { + name: "tip", + label: "提示", + type: "textarea" + }, + { + name: 'image_id', + label: '填报图', + type: 'file', + relationName: 'image', + defaultValue: [], + props: { + multiple: false + } + }, + { + name: 'need_sign', + label: '是否需要签名', + type: 'select', + optionsParams: [ + { + value: 1, + label: '是' + }, + { + value: 0, + label: '否' + } + ] + }, + ] + }, + "batch-sub": { + fields: [ + { + name: "name", + label: "名称", + type: "input", + rules: [ + { required: true }, + ] + }, + { + name: 'batch_id', + label: '归属批次', + type: 'select', + optionsFrom: 'batch', + optionProps: { + value: 'id', + label: 'name' + }, + rules: [ + { + required: true + } + ] + }, + { + name: "sort", + label: "排序", + type: "input-number" + }, + { + name: 'show_school_obey', + label: '是否显示学校服从', + type: 'select', + optionsParams: [ + { + value: 1, + label: '是' + }, + { + value: 0, + label: '否' + } + ] + }, + { + name: 'show_specialty_obey', + label: '是否显示专业服从', + type: 'select', + optionsParams: [ + { + value: 1, + label: '是' + }, + { + value: 0, + label: '否' + } + ] + }, + ] + }, + "batch-sub-school": { + fields: [ + { + label: "归属批次详情", + name: "batch_sub_id", + type: "select", + optionsFrom: 'batch-sub', + optionProps: { + value: 'id', + label: 'name' + }, + rules: [ + { + required: true + } + ] + }, + { + name: "number", + label: "序号", + type: "input-number" + }, + { + name: "specialty", + label: "专业", + type: "input" + }, + ] + }, + banners: { + fields: [ + { + name: 'name', + label: '标题', + type: 'input' + }, + { + name: 'sub_name', + label: '副标题', + type: 'input' + }, + { + name: 'position', + label: '显示位置', + type: 'select', + optionsParams: [ + { + value: 1, + label: '首页' + } + ] + }, + { + name: 'jump_type', + label: '跳转类型', + type: 'select', + optionsParams: [ + { + value: 1, + label: '小程序' + }, + { + value: 2, + label: 'h5' + } + ] + }, + { + name: 'jump_url', + label: '跳转链接', + type: 'input' + }, + { name: 'sort', label: '排序', type: 'input-number' }, + { + name: 'image_id', + label: '封面图', + type: 'file', + relationName: 'image', + defaultValue: [], + props: { + multiple: false + } + } + ] + }, + "recommend": { + fields: [ + { + name: 'name', + label: '名称', + type: 'input' + }, + { + name: 'year', + label: '年份', + type: 'date', + props: { + type: 'year', + 'valueFormat': 'yyyy' + } + }, + { + name: 'school_way', + label: '计算几年平均分', + type: 'input-number', + rules: [ + { required: true }, + { pattern: /^[1-9]$|^10$/ } + ] + }, + { + name: 'chong_max', + label: '“冲”分数-上限', + type: 'input-number', + }, + { + name: 'chong_min', + label: '“冲”分数-下限', + type: 'input-number', + }, + { + name: 'bao_max', + label: '“保”分数-上限', + type: 'input-number', + }, + { + name: 'bao_min', + label: '“保”分数-下限', + type: 'input-number', + }, + { + name: 'wen_max', + label: '“稳”分数-上限', + type: 'input-number', + }, + { + name: 'wen_min', + label: '“稳”分数-下限', + type: 'input-number', + }, + ] + }, + "recommend-form": { + fields: [ + { + name: 'name', + label: '名称', + type: 'input' + }, + { + name: 'nationality', + label: '民族', + type: 'input' + }, + { + name: 'anticipate_score', + label: '估分', + type: 'input-number' + }, + { + name: 'year', + label: '年份', + type: 'date', + props: { + type: 'year', + 'valueFormat': 'yyyy' + } + }, + { + name: 'sex', + label: '性别', + type: 'select', + optionsParams: [ + { + value: '男', + label: '男' + }, + { + value: '女', + label: '女' + }, + { + value: '保密', + label: '保密' + } + ] + }, + { + name: 'area_id', + label: '区域', + type: 'select', + optionsFrom: 'area', + optionProps: { + value: 'id', + label: 'name' + } + }, + { + name: 'is_stable', + label: '成绩是否稳定', + type: 'select', + optionsParams: [ + { + value: 1, + label: '是' + }, + { + value: 0, + label: '否' + } + ] + }, + { + name: 'is_bare', + label: '是否为裸分', + type: 'select', + optionsParams: [ + { + value: 1, + label: '是' + }, + { + value: 0, + label: '否' + } + ] + }, + ] + }, + "user-follow": { + fields: [ + { + name: 'user_id', + label: '归属用户', + type: 'select', + optionsFrom: 'user', + optionProps: { + value: 'id', + label: 'mobile' + } + }, + { + name: 'remark', + label: '备注', + type: 'textarea' + }, + { + name: 'time', + label: '时间', + type: 'date', + props: { + valueFormat: 'yyyy-MM-dd' + } + } + ] + }, + "batch-data": { + "fields": [] + } +} + +module.exports = { + t +} diff --git a/script/utils.js b/script/utils.js new file mode 100644 index 0000000..9932dc6 --- /dev/null +++ b/script/utils.js @@ -0,0 +1,40 @@ +const ejs = require('ejs') +const path = require('path') +const fs = require('fs') + +const compiler = (template,data) => { + const templatePath = path.resolve(__dirname,`./${template}`) + + return new Promise((resolve,reject)=>{ + ejs.renderFile(templatePath,{data},(err,result)=>{ + if(err){ + console.log(err); + reject(err) + return + } + resolve(result) + }) + }) +} + +const writeFile = (path,content) =>{ + return fs.promises.writeFile(path,content) +} + +const resolveName = name => { + if (/(-|_)/g.test(name)) { + let splitName = name.split(/(-|_)/).filter(i => !/(-|_)/.test(i)).map(i => i.charAt(0).toUpperCase() + i.slice(1)) + return splitName.join('') + } else { + return (name.charAt(0).toUpperCase() + name.slice(1)) + } +} +const ensureDirectoryExistence = (filePath) => { + if (!fs.existsSync(filePath)) { + fs.mkdirSync(filePath); + } +} +module.exports = { + compiler,writeFile,resolveName,ensureDirectoryExistence +} +