Files
dvcp-node-service/src/tools/generate.js
2023-02-02 17:19:49 +08:00

162 lines
7.8 KiB
JavaScript

const fse = require("fs-extra");
const {readFile} = require("../utils/fsUtils");
const {checkJson} = require("./index");
/**
* 生成入口页
*/
const genHome = (app, dest) => {
return readFile('./tpl/AppEntry.vue').then(data => {
let file = data.toString(),
content = file.replace(/@appName/g, app.appName)
.replace(/@name/g, app.name)
let dicts = `'yesOrNo'`
if (checkJson(app.props)) {
let props = JSON.parse(app.props)?.map(e => e.dict).filter(e => !!e)
props.length > 0 && (dicts = props.map(e => `'${e}'`).toString())
}
content = content.replace(/@dicts/g, dicts)
return fse.outputFileSync(`${dest}/${app.appName}.vue`, content)
})
}
/**
* 生成列表页
*/
const genList = (app, dest) => {
return readFile('./tpl/list.vue').then(data => {
let file = data.toString(),
content = file.replace(/@rightCode/g, app.rightCode)
.replace(/@name/g, app.name),
listProps = "", searchProps = "", btns = "", tableBtns = ""
if (checkJson(app.props)) {
let props = JSON.parse(app.props)
listProps = JSON.stringify(props.filter(e => e.isTable)?.map(e => {
delete e.isSearch
delete e.isTable
delete e.isDetail
return e
}) || null)?.replace(/"([^"]+)":/g, '$1:')
props.filter(e => e.isSearch && e.dict).map(e => {
searchProps += `<ai-select v-model="search.${e.prop}" placeholder="${e.label}" :selectList="dict.getDict('${e.dict}')"/>`
})
}
if (checkJson(app.btns)) {
let buttons = JSON.parse(app.btns)
buttons.map(e => {
if (e == "insertEnable") {
btns += `<el-button type="primary" icon="iconfont iconAdd" @click="handleAdd()">添加</el-button>`
} else if (e == "importEnable") {
btns += `<ai-import :instance="instance" name="${app.name}" title="导入${app.name}" suffixName="xlsx"
url="/app/${app.rightCode}/downloadTemplate" importUrl="/app/${app.rightCode}/import"
@onSuccess="page.current=1,getTableData()"/>`
} else if (e == "exportEnalbe") {
btns += `<ai-download url="/app/${app.rightCode}/export" :params="{...search,ids}" :instance="instance" fileName="${app.name}导出文件"/>`
} else if (e == "editEnable") {
tableBtns += `<el-button type="text" @click="handleAdd(row.id)">编辑</el-button>`
} else if (e == "deleteEnable") {
tableBtns += `<el-button type="text" @click="handleDelete(row.id)">删除</el-button>`
} else if (e == "batchDelEnable") {
btns += `<el-button icon="iconfont iconDelete" :disabled="!search.ids" @click="handleDelete(search.ids)">删除</el-button>`
}
})
if (!searchProps) {
//当没有筛选条件时,按钮替换原筛选条件位置
searchProps = btns
btns = ""
} else {
btns = `<ai-search-bar><template #left>${btns}</template></ai-search-bar>`
}
}
content = content.replace(/@listProps/g, listProps)
.replace(/@searchProps/g, searchProps)
.replace(/@btns/g, btns)
.replace(/@tableBtns/g, tableBtns)
return fse.outputFileSync(`${dest}/list.vue`, content)
})
}
/**
* 生成新增/编辑页
*/
const genAdd = (app, dest) => {
return readFile('./tpl/add.vue').then(data => {
let file = data.toString(),
content = file.replace(/@rightCode/g, app.rightCode)
.replace(/@name/g, app.name),
rules = "", domain = ""
if (checkJson(app.detailConfig)) {
let detail = JSON.parse(app.detailConfig), props = detail?.map(e => e.column).flat()
props.filter(e => e.mustFill == 1).map(e => {
rules += `${e.prop}: {required: true, message: "${e.fieldTips}"},`
})
detail.map(group => {
let fields = ``
group.column?.map(e => {
fields += `<el-form-item label="${e.fieldName}" prop="${e.prop}" ${e.grid == 1 ? '' : 'class="half"'}>${getComp(e)}</el-form-item>`
})
domain += `<ai-card title="${group.groupName}"><template #content> ${fields}</template></ai-card>`
})
}
content = content.replace(/@content/g, domain)
.replace(/@rules/g, rules)
return fse.outputFileSync(`${dest}/add.vue`, content)
})
}
const getComp = e => {
//字典下拉选择
if (e.type == 'dict') {
return `<ai-select v-model="form.${e.prop}" placeholder="${e.fieldName}" :selectList="dict.getDict('${e.dict}')" ${e.disable == 1 ? 'disabled' : ''}/>`
//单选radio
} else if (e.type == 'radio') {
return `<el-radio-group v-model="form.${e.prop}" ${e.disable == 1 ? 'disabled' : ''}>
<el-radio :label="item.dictValue" v-for="(item, i) in dict.getDict('${e.dict}')" :key="i">{{ item.dictName }}</el-radio>
</el-radio-group>`
//开关onOff
} else if (e.type == 'onOff') {
return `<el-switch v-model="form.${e.prop}" active-color="#26f" inactive-color="#ddd" active-value="1" inactive-value="0" ${e.disable == 1 ? 'disabled' : ''}/>`
//多选checkbox
} else if (e.type == 'checkbox') {
return `<el-checkbox-group v-model="form.${e.prop}" ${e.disable == 1 ? 'disabled' : ''}>
<el-checkbox v-for="(item, i) in dict.getDict('${e.dict}')" :label="item.dictValue" :key="i">{{ item.dictName }}</el-checkbox>
</el-checkbox-group>`
} else if (e.type == 'idNumber') {
return `<ai-id v-model="form.${e.prop}" ${e.disable == 1 ? 'disabled' : ''}/>`
//input输入框
} else if (['input', 'name', 'phone'].includes(e.type)) {
return `<el-input v-model="form.${e.prop}" placeholder="请输入${e.fieldName}" clearable ${e.disable == 1 ? 'disabled' : ''} :maxlength="${e.maxLength}" show-word-limit/>`
//number 输入框
} else if (e.type == 'number') {
return `<el-input-number v-model="form.${e.prop}" label="请输入${e.fieldName}" ${e.disable == 1 ? 'disabled' : ''} :precision="${e.decimalPlaces}" :max="${e.maxValue}" :min="${e.minValue}"/>`
//textarea输入框
} else if (e.type == 'textarea' || e.type == 'text') {
return `<el-input v-model="form.${e.prop}" placeholder="请输入${e.fieldName}" clearable ${e.disable == 1 ? 'disabled' : ''} :maxlength="${e.maxLength}" type="textarea" show-word-limit :rows="3"/>`
//日期选择
} else if (e.type == 'date') {
return `<el-date-picker style="width: 100%;" v-model="form.${e.prop}" type="date" placeholder="请选择" ${e.disable == 1 ? 'disabled' : ''} :value-format="${e.timePattern}"/>`
//日期带时分秒选择
} else if (e.type == 'datetime') {
return `<el-date-picker v-model="form.${e.prop}" type="datetime" placeholder="选择日期时间" ${e.disable == 1 ? 'disabled' : ''} :value-format="${e.timePattern}"/>`
//时间-时分秒选择
} else if (e.type == 'time') {
return `<el-time-picker v-model="form.${e.prop}" placeholder="请选择" ${e.disable == 1 ? 'disabled' : ''} :value-format="${e.timePattern}"/>`
//附件
} else if (e.type == 'upload') {
return ` <ai-uploader :instance="instance" isShowTip fileType="file" v-model="form.${e.prop}" ${e.disable == 1 ? 'disabled' : ''}
acceptType=".zip,.rar,.doc,.docx,.xls,.ppt,.pptx,.pdf,.txt,.jpg,.png,.xlsx" :limit="${e.fileMaxCount}" :maxSize="${e.fileChoseSize}"/>`
//富文本
} else if (e.type == 'rtf') {
return `<ai-editor v-model="form.${e.prop}" :instance="instance" ${e.disable == 1 ? 'disabled' : ''}/>`
//地区选择
} else if (e.type == 'area') {
return ` <ai-area-get :instance="instance" v-model="form.${e.prop}" :name.sync="form.${e.fieldDbName}_name" ${e.disable == 1 ? 'disabled' : ''}/>`
} else if (e.type == 'user') {
//人员选择
return `<ai-wechat-selecter slot="append" isShowUser :instance="instance" v-model="form.${e.prop}"/>`
}
}
const generate = (app, dest) => {
fse.emptydirSync(dest)
let tasks = [genHome(app, dest), genList(app, dest)]
app.detailType == 0 && tasks.push(genAdd(app, dest))
return Promise.all(tasks)
}
module.exports = generate