parent
cee713915f
commit
12a7e2186f
@ -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
|
||||
})
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
const { t } = require('./tables')
|
||||
|
||||
const { create } = require('./create')
|
||||
const createName = 'recommend'
|
||||
const { fields, options } = t['recommend']
|
||||
create(createName, fields, options)
|
||||
@ -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
|
||||
}
|
||||
} %>
|
||||
<template>
|
||||
<div>
|
||||
<el-drawer
|
||||
:title="$route.meta.title"
|
||||
direction="rtl"
|
||||
size="68%"
|
||||
:visible.sync="visible"
|
||||
append-to-body
|
||||
@close="$emit('update:isShow',false)">
|
||||
<section class="drawer-container">
|
||||
<el-descriptions class="drawer-container__desc" size="small" border ref="elDesc" :column="<%- data.options?.columns ?? 2 %>" direction="vertical" :labelStyle="{ 'font-weight': '500', 'font-size': '15px' }">
|
||||
<% data.fields.forEach((field, index) => {
|
||||
switch (field.type) {
|
||||
case 'input': %>
|
||||
<el-descriptions-item label="<%- field.label %>">
|
||||
{{ form['<%- field.name %>'] }}
|
||||
</el-descriptions-item>
|
||||
<% break
|
||||
case 'textarea':
|
||||
%>
|
||||
<el-descriptions-item label="<%- field.label %>" span="2">
|
||||
<div v-html="form['<%- field.name %>']"></div>
|
||||
</el-descriptions-item>
|
||||
<% break
|
||||
case 'richtext':
|
||||
%>
|
||||
<el-descriptions-item label="<%- field.label %>" span="2">
|
||||
{{ form['<%- field.name %>'] }}
|
||||
</el-descriptions-item>
|
||||
<% break
|
||||
case 'input-number':
|
||||
%>
|
||||
<el-descriptions-item label="<%- field.label %>">
|
||||
{{ typeof form['<%- field.name %>'] === 'number' ? form['<%- field.name %>'].toFixed(2) : form['<%- field.name %>'] }}
|
||||
</el-descriptions-item>
|
||||
<% break
|
||||
case 'select':
|
||||
%>
|
||||
<el-descriptions-item label="<%- field.label %>">
|
||||
{{ <%- field.optionsFrom ? handleFormName(field.optionsFrom) : JSON.stringify(field.optionsParams).replaceAll('"','\'') %>.find(i => i['<%- field.optionProps?.value ?? 'value' %>'] === form['<%- field.name %>']) ? <%- field.optionsFrom ? handleFormName(field.optionsFrom) : JSON.stringify(field.optionsParams).replaceAll('"','\'') %>.find(i => i['<%- field.optionProps?.value ?? 'value' %>'] === form['<%- field.name %>'])['<%- field.optionProps?.label ?? 'label' %>'] : '' }}
|
||||
</el-descriptions-item>
|
||||
<% break
|
||||
case 'date':
|
||||
%>
|
||||
<el-descriptions-item label="<%- field.label %>">
|
||||
{{ form['<%- field.name %>'] }}
|
||||
</el-descriptions-item>
|
||||
<% break
|
||||
case 'switch':
|
||||
%>
|
||||
<el-descriptions-item label="<%- field.label %>">
|
||||
{{ form['<%- field.name %>'] ? '是' : '否' }}
|
||||
</el-descriptions-item>
|
||||
<% break
|
||||
case 'file': %>
|
||||
<el-form-item label="<%- field.label %>" prop="<%- field.name %>">
|
||||
<el-upload
|
||||
:file-list="form['<%- field.name %>']"
|
||||
accept="application/msword,image/jpeg,application/pdf,image/png,application/vnd.ms-powerpoint,text/plain,application/x-zip-compressed,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document">
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<% break
|
||||
}
|
||||
})%>
|
||||
</el-descriptions>
|
||||
</section>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { show } from "@/api/<%- data.originalName %>/<%- data.originalName %>";
|
||||
|
||||
export default {
|
||||
name: "<%- data.name %>Show",
|
||||
props: {
|
||||
isShow: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required: true
|
||||
},
|
||||
<% for (let index in data.fields) {
|
||||
let field = data.fields[index]
|
||||
if (field.optionsFrom) { %>
|
||||
<%- handleFormName(field.optionsFrom) %> : {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
<% }
|
||||
}%>
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
visible: false,
|
||||
form: {
|
||||
<% for (let index in data.fields){ %>
|
||||
<%- data.fields[index].name %>: <%- JSON.stringify(data.fields[index].defaultValue) ?? "''" %>,
|
||||
<% } %>
|
||||
},
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
isShow(newVal) {
|
||||
this.visible = newVal
|
||||
},
|
||||
visible(newVal) {
|
||||
this.$emit('update:isShow', newVal)
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async getDetail(id) {
|
||||
try {
|
||||
const detail = await show({
|
||||
id
|
||||
})
|
||||
for (let key in this.form) {
|
||||
if (detail.hasOwnProperty(key)) {
|
||||
this.form[key] = detail[key]
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.span2 {
|
||||
grid-column: span 2;
|
||||
}
|
||||
::v-deep .el-form-item > * {
|
||||
max-width: 100%;
|
||||
}
|
||||
.drawer-container {
|
||||
height: 100%;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
& > * {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -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
|
||||
}
|
||||
} %>
|
||||
<template>
|
||||
<div>
|
||||
<el-card shadow="never" style="margin-top: 20px;">
|
||||
<template #header>
|
||||
<slot name="header">
|
||||
<vxe-toolbar :print="isHasAuth('print')" custom ref="toolbar">
|
||||
<template #toolSuffix>
|
||||
<vxe-button style="margin-right: 10px;" v-if="isHasAuth('export')" icon="vxe-icon-download" circle @click="exportMethod"></vxe-button>
|
||||
</template>
|
||||
<template #buttons>
|
||||
<el-button
|
||||
v-if="isHasAuth('create')"
|
||||
icon="el-icon-plus"
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="isShowAdd = true"
|
||||
>新增</el-button
|
||||
>
|
||||
<el-button
|
||||
v-if="isHasAuth('search')"
|
||||
icon="el-icon-search"
|
||||
type="primary"
|
||||
plain
|
||||
size="small"
|
||||
@click="getList"
|
||||
>搜索</el-button
|
||||
>
|
||||
</template>
|
||||
</vxe-toolbar>
|
||||
</slot>
|
||||
</template>
|
||||
|
||||
<vxe-table
|
||||
ref="table"
|
||||
stripe
|
||||
style="margin-top: 10px"
|
||||
:loading="loading"
|
||||
:height="tableHeight"
|
||||
keep-source
|
||||
show-overflow
|
||||
:menu-config="{
|
||||
className: 'my-menus',
|
||||
body: {
|
||||
options: [
|
||||
[
|
||||
{ code: 'copy', name: '复制', prefixConfig: { icon: 'vxe-icon-copy' }, suffixConfig: { content: 'Ctrl+C' } },
|
||||
{ code: 'remove', name: '删除', prefixConfig: { icon: 'vxe-icon-delete-fill', className: 'color-red' } }
|
||||
],
|
||||
]
|
||||
}
|
||||
}"
|
||||
@menu-click="contextMenuClickEvent"
|
||||
:row-config="{ isCurrent: true, isHover: true }"
|
||||
:column-config="{ resizable: true }"
|
||||
:export-config="{}"
|
||||
:edit-rules="validRules"
|
||||
:edit-config="{
|
||||
trigger: 'manual',
|
||||
mode: 'row',
|
||||
showStatus: true,
|
||||
isHover: true,
|
||||
autoClear: false,
|
||||
}"
|
||||
<% if (!!data.options?.isTree) { %>
|
||||
:tree-config="{
|
||||
|
||||
}"
|
||||
<% } %>
|
||||
:align="allAlign"
|
||||
:data="tableData"
|
||||
>
|
||||
<vxe-column type="checkbox" width="50" align="center" />
|
||||
<vxe-column type="seq" width="58" align="center" <% if (!!data.options?.isTree) { %>tree-node<% } %> />
|
||||
<% for (let index in data.fields) { %>
|
||||
<% let field = data.fields[index] %>
|
||||
<% if (!field.hidden) { %>
|
||||
<% switch (field.type) {
|
||||
case 'input':
|
||||
case 'textarea': %>
|
||||
<vxe-column
|
||||
header-align="center"
|
||||
field="<%- field.name %>"
|
||||
width="<%- field.width || 160 %>"
|
||||
title="<%- field.label %>"
|
||||
:edit-render="{ name: 'input', attrs: { type: 'text' } }"
|
||||
/>
|
||||
<% break
|
||||
case 'input-number': %>
|
||||
<vxe-column
|
||||
header-align="center"
|
||||
align="right"
|
||||
field="<%- field.name %>"
|
||||
width="<%- field.width || 160 %>"
|
||||
title="<%- field.label %>"
|
||||
:edit-render="{ name: 'input', attrs: { type: 'number' } }"
|
||||
/>
|
||||
<% break
|
||||
case 'richtext': %>
|
||||
<vxe-column
|
||||
align="center"
|
||||
header-align="center"
|
||||
field="<%- field.name %>"
|
||||
width="<%- field.width || 120 %>"
|
||||
title="<%- field.label %>"
|
||||
:edit-render="{}"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-button slot="reference" size="small" type="primary" icon="el-icon-search" @click="$refs['RichTextModal'].open({ text: row['<%- field.name %>'], readonly: true, fieldName: '<%- field.name %>', row })">查看</el-button>
|
||||
</template>
|
||||
<template #edit="{ row }">
|
||||
<el-button slot="reference" size="small" type="primary" icon="el-icon-edit" @click="$refs['RichTextModal'].open({ text: row['<%- field.name %>'], readonly: false, fieldName: '<%- field.name %>', row })">编辑</el-button>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<% break
|
||||
case 'select': %>
|
||||
<vxe-column
|
||||
align="center"
|
||||
field="<%- field.name %>"
|
||||
width="<%- field.width || 180 %>"
|
||||
title="<%- field.label %>"
|
||||
:edit-render="{ name: 'VxeSelect', options: <%- field.optionsFrom ? handleFormName(field.optionsFrom) : JSON.stringify(field.optionsParams).replaceAll('"','\'') %>, props: { multiple: <%- field.props?.multiple ?? false %> }, optionProps: { value: '<%- field.optionProps?.value ?? 'value' %>', label: '<%- field.optionProps?.label ?? 'label' %>' } }"
|
||||
/>
|
||||
<% break
|
||||
case 'date': %>
|
||||
<vxe-column
|
||||
align="center"
|
||||
field="<%- field.name %>"
|
||||
width="<%- field.width || 180 %>"
|
||||
title="<%- field.label %>"
|
||||
:edit-render="{}"
|
||||
>
|
||||
<template #edit="{ row }">
|
||||
<el-date-picker v-model="row['<%- field.name %>']" style="width: 100%;" size="small" type="<%- field.props.type %>" value-format="<%- field.props.valueFormat ?? 'yyyy-MM-dd' %>"></el-date-picker>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<% break
|
||||
case 'switch': %>
|
||||
<vxe-column
|
||||
align="center"
|
||||
field="<%- field.name %>"
|
||||
width="<%- field.width || 140 %>"
|
||||
title="<%- field.label %>"
|
||||
:edit-render="{ name: 'VxeSelect', options: [{ label: '是', value: 1 },{ label: '否', value: 0 }] }"
|
||||
/>
|
||||
<% break
|
||||
case 'tree':
|
||||
function treeOptions(myfield) {
|
||||
if (myfield.isOwnOptions) {
|
||||
if (myfield.optionsHasRoot) {
|
||||
return `[{ ${myfield.optionProps?.value ?? 'id'}: 0, ${myfield.optionProps?.label ?? 'label'}: '根结点' ,children: tableData }]`
|
||||
} else {
|
||||
return 'tableData'
|
||||
}
|
||||
} else {
|
||||
return myfield.optionsFrom ? (myfield.optionsHasRoot ? `[{ ${myfield.optionProps?.value ?? 'id'}: 0, ${myfield.optionProps?.label ?? 'label'}: '根结点' ,children: ${handleFormName(myfield.optionsFrom)} }]` : handleFormName(myfield.optionsFrom)) : myfield.optionsParams
|
||||
}
|
||||
}
|
||||
%>
|
||||
<vxe-column
|
||||
align="center"
|
||||
field="<%- field.name %>"
|
||||
width="<%- field.width || 160 %>"
|
||||
title="<%- field.label %>"
|
||||
:edit-render="{ name: 'VxeTreeSelect', options: <%- treeOptions(field) %>, props: { multiple: <%- field.props?.multiple ?? false %> }, optionProps: { value: '<%- field.optionProps?.value ?? 'id' %>', label: '<%- field.optionProps?.label ?? 'label' %>' } }"
|
||||
/>
|
||||
<% break
|
||||
case 'file': %>
|
||||
<vxe-column
|
||||
field="<%- field.name %>"
|
||||
min-width="180"
|
||||
title="<%- field.label %>"
|
||||
header-align="center"
|
||||
align="left"
|
||||
:edit-render="{}"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<vxe-upload v-model="row['<%- field.relationName ? field.relationName : field.name %>']" name-field="original_name" readonly progress-text="{percent}%" :more-config="{ maxCount: 1, layout: 'horizontal' }" :show-button-text="false" <%- field.props.multiple ? '' : 'single-mode' %> />
|
||||
</template>
|
||||
<template #edit="{ row }">
|
||||
<vxe-upload
|
||||
name-field="original_name"
|
||||
v-model="row['<%- field.relationName ? field.relationName : field.name %>']"
|
||||
progress-text="{percent}%"
|
||||
:more-config="{ maxCount: 1, layout: 'horizontal' }"
|
||||
:limit-size="uploadSize / 1024 / 1024"
|
||||
:show-button-text="false"
|
||||
<%- field.props.multiple ? '' : 'single-mode' %>
|
||||
:upload-method="({file}) => uploadMethod(file)" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
<% break
|
||||
}
|
||||
}
|
||||
} %>
|
||||
<vxe-column field="operate" header-align="center" title="操作" min-width="220" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<template v-if="isActiveStatus(row)">
|
||||
<el-button size="small" type="primary" @click="saveRowEvent(row)"
|
||||
>保存</el-button
|
||||
>
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
plain
|
||||
@click="cancelRowEvent(row)"
|
||||
>取消</el-button
|
||||
>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button v-if="isHasAuth('detail')" size="small" type="primary" plain @click="detail(row)"
|
||||
>查看</el-button
|
||||
>
|
||||
<el-button v-if="isHasAuth('edit')" size="small" type="warning" @click="editRowEvent(row)"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button
|
||||
v-if="isHasAuth('delete')"
|
||||
size="small"
|
||||
type="danger"
|
||||
@click="destroyRowEvent(row)"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
|
||||
<% if (!data.options?.isTree) { %>
|
||||
<el-pagination
|
||||
style="margin-top: 10px;display: flex;justify-content: flex-end;"
|
||||
:current-page.sync="select.page"
|
||||
:page-sizes="[20, 30, 40, 50]"
|
||||
:page-size.sync="select.page_size"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
@size-change="
|
||||
(e) => {
|
||||
select.page_size = e;
|
||||
select.page = 1;
|
||||
getList();
|
||||
}
|
||||
"
|
||||
@current-change="
|
||||
(e) => {
|
||||
select.page = e;
|
||||
getList();
|
||||
}
|
||||
"
|
||||
/>
|
||||
<% } %>
|
||||
</el-card>
|
||||
|
||||
<Add<%- data.name %>
|
||||
ref="Add<%- data.name %>"
|
||||
<% for (let index in data.fields) {
|
||||
let field = data.fields[index]
|
||||
if (field.optionsFrom) { %>
|
||||
:<%- field.optionsFrom %>="<%- handleFormName(field.optionsFrom) %>"
|
||||
<% }
|
||||
if (field.type === 'tree' && !field.optionsFrom) { %>
|
||||
:table-data="tableData"
|
||||
<% }
|
||||
}%>
|
||||
:is-show.sync="isShowAdd"
|
||||
@refresh="getList"
|
||||
/>
|
||||
<Show<%- data.name %>
|
||||
ref="Show<%- data.name %>"
|
||||
<% for (let index in data.fields) {
|
||||
let field = data.fields[index]
|
||||
if (field.optionsFrom) { %>
|
||||
:<%- field.optionsFrom %>="<%- handleFormName(field.optionsFrom) %>"
|
||||
<% }
|
||||
}%>
|
||||
:is-show.sync="isShowDetail"
|
||||
/>
|
||||
<% if (data.fields.find(field => field.type === 'richtext')) {%>
|
||||
<rich-text-modal ref="RichTextModal" @confirm="({ row, fieldName, text }) => row[fieldName] = text"></rich-text-modal>
|
||||
<%}%>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VxeUI from "vxe-pc-ui";
|
||||
<% if (data.fields.find(field => field.type === 'richtext')) {%>
|
||||
import RichTextModal from "@/components/RichTextModal/index.vue";
|
||||
<%}%>
|
||||
import { authMixin } from "@/mixin/authMixin"
|
||||
import { uploadSize } from "@/settings";
|
||||
import { deepCopy } from "@/utils";
|
||||
import { download } from "@/utils/downloadRequest";
|
||||
import { destroy, index, save } from "@/api/<%- data.originalName %>/<%- data.originalName %>";
|
||||
import Add<%- data.name %> from "./components/Add<%- data.name %>.vue";
|
||||
import Show<%- data.name %> from "./components/Show<%- data.name %>.vue";
|
||||
import axios from "axios";
|
||||
import { getToken } from "@/utils/auth";
|
||||
<% for (let index in data.fields) {
|
||||
let field = data.fields[index]
|
||||
if (field.optionsFrom) { %>
|
||||
<%- `import { index as ${handleFormName(field.optionsFrom)}Index } from '@/api/${field.optionsFrom}/${field.optionsFrom}';` %>
|
||||
<% }
|
||||
}%>
|
||||
export default {
|
||||
name: "<%- data.name %>",
|
||||
mixins: [authMixin],
|
||||
components: {
|
||||
<% if (data.fields.find(field => field.type === 'richtext')) {%>
|
||||
RichTextModal,
|
||||
<%}%>
|
||||
Add<%- data.name %>,
|
||||
Show<%- data.name %>,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
uploadSize,
|
||||
examineKey: 0,
|
||||
isShowAdd: false,
|
||||
isShowDetail: false,
|
||||
|
||||
loading: false,
|
||||
tableHeight: 400,
|
||||
select: {
|
||||
page: 1,
|
||||
page_size: 20,
|
||||
keyword: '',
|
||||
show_relation: <%- JSON.stringify(data.fields.filter(i => i.hasOwnProperty('relationName') && i.relationName).map(i => i.relationName)) %>,
|
||||
<% if (!!data.options?.isTree) { %>is_tree: 1,<% } %>
|
||||
},
|
||||
total: 0,
|
||||
allAlign: null,
|
||||
tableData: [],
|
||||
form: {
|
||||
id: '',
|
||||
<% for (let index in data.fields){ %>
|
||||
<%- data.fields[index].name %>: <%- JSON.stringify(data.fields[index].defaultValue) ?? "''" %>,
|
||||
<% } %>
|
||||
},
|
||||
validRules: {
|
||||
<% let rulesFields = data.fields.filter(i => i.hasOwnProperty('rules'))
|
||||
for (let index in rulesFields){ %>
|
||||
<%- rulesFields[index].name %>: [
|
||||
<% rulesFields[index].rules.forEach(rule => {
|
||||
if (rule.hasOwnProperty('required')) { %>
|
||||
{
|
||||
required: true,
|
||||
message: '<%-rulesFields[index].label%>'+'必填'
|
||||
},
|
||||
<% } else if (rule.hasOwnProperty('pattern')) { %>
|
||||
{
|
||||
pattern: <%-rule.pattern%>,
|
||||
message: '<%-rulesFields[index].label%>'+'验证失败'
|
||||
},
|
||||
<% }
|
||||
})%>
|
||||
],
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% for (let index in data.fields) {
|
||||
let field = data.fields[index]
|
||||
if (field.optionsFrom) { %>
|
||||
<%- handleFormName(field.optionsFrom) + ": []," %>
|
||||
<% }
|
||||
}%>
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isActiveStatus() {
|
||||
return function (row) {
|
||||
if (this.$refs["table"]) {
|
||||
return this.$refs["table"].isEditByRow(row);
|
||||
}
|
||||
};
|
||||
},
|
||||
isHasAuth() {
|
||||
return function (auth) {
|
||||
return this.auths_auth_mixin.indexOf(auth) !== -1
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
<% for (let index in data.fields) {
|
||||
let field = data.fields[index]
|
||||
if (field.optionsFrom) { %>
|
||||
<%- `this.get${handleFormName(field.optionsFrom).charAt(0).toUpperCase() + handleFormName(field.optionsFrom).slice(1)}()` %>
|
||||
<% }
|
||||
}%>
|
||||
this.getList();
|
||||
},
|
||||
mounted() {
|
||||
this.bindToolbar()
|
||||
this.calcTableHeight()
|
||||
},
|
||||
methods: {
|
||||
exportMethod() {
|
||||
this.$confirm("请选择导出方式", "提示", {
|
||||
confirmButtonText: "全量导出",
|
||||
cancelButtonText: "部分导出",
|
||||
distinguishCancelAndClose: true
|
||||
}).then(_ => {
|
||||
download('/api/admin/school/index', 'get', {
|
||||
...this.select,
|
||||
page: 1,
|
||||
page_size: 9999,
|
||||
is_export: 1,
|
||||
export_fields: Object.keys(this.form)
|
||||
})
|
||||
}).catch(action => {
|
||||
if (action === 'cancel' && this.$refs['table']) {
|
||||
this.$refs['table'].openExport()
|
||||
}
|
||||
});
|
||||
},
|
||||
calcTableHeight() {
|
||||
let clientHeight = document.documentElement.clientHeight;
|
||||
let cardTitle = document.querySelector(".el-card__header")?.getBoundingClientRect()?.height;
|
||||
let search = document.querySelector(".vxe-toolbar")?.getBoundingClientRect()?.height;
|
||||
let paginationHeight = (document.querySelector(".el-pagination")?.getBoundingClientRect()?.height ?? 0) + 10; //分页的高度
|
||||
let topHeight = 50; //页面 头部
|
||||
let padding = 80;
|
||||
let margin = 20;
|
||||
this.tableHeight =
|
||||
clientHeight - cardTitle - search - paginationHeight - topHeight - padding - margin;
|
||||
},
|
||||
contextMenuClickEvent ({ menu, row, column }) {
|
||||
switch (menu.code) {
|
||||
case 'copy':
|
||||
// 示例
|
||||
if (row && column) {
|
||||
if (VxeUI.clipboard.copy(row[column.field])) {
|
||||
this.$message.success('已复制到剪贴板!')
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'remove':
|
||||
if (row && column) {
|
||||
this.destroyRowEvent(row)
|
||||
}
|
||||
default:
|
||||
}
|
||||
},
|
||||
async detail (row) {
|
||||
await this.$refs["Show<%- data.name %>"].getDetail(row.id)
|
||||
this.isShowDetail = true
|
||||
},
|
||||
|
||||
<% for (let index in data.fields) {
|
||||
let field = data.fields[index]
|
||||
if (field.optionsFrom) { %>
|
||||
<%- `async get${handleFormName(field.optionsFrom).charAt(0).toUpperCase() + handleFormName(field.optionsFrom).slice(1)}() {
|
||||
try {
|
||||
const res = await ${handleFormName(field.optionsFrom)}Index({
|
||||
page: 1,
|
||||
page_size: 999,
|
||||
${field.type === 'tree' ? 'is_tree: 1,' : ''}
|
||||
}, false)
|
||||
this.${handleFormName(field.optionsFrom)} = res${field.type !== 'tree' ? '.data': ''}
|
||||
} catch(err) {
|
||||
console.error(err)
|
||||
}
|
||||
},` %>
|
||||
<% }
|
||||
}%>
|
||||
|
||||
uploadMethod(file) {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
window.$_uploading = true
|
||||
return axios.post(process.env.VUE_APP_UPLOAD_API, formData, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${getToken()}`,
|
||||
}
|
||||
}).then((response) => {
|
||||
window.$_uploading = false
|
||||
if (response.status === 200 && !response.data.code) {
|
||||
return {
|
||||
response: response.data,
|
||||
name: response.data.original_name,
|
||||
url: response.data.url
|
||||
}
|
||||
} else {
|
||||
this.$message.error("上传失败")
|
||||
}
|
||||
}).catch(_ => {
|
||||
window.$_uploading = false
|
||||
})
|
||||
},
|
||||
bindToolbar() {
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs["table"] && this.$refs["toolbar"]) {
|
||||
this.$refs["table"].connect(this.$refs["toolbar"]);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
editRowEvent(row) {
|
||||
if (this.$refs["table"]) {
|
||||
this.$refs["table"].setEditRow(row);
|
||||
}
|
||||
},
|
||||
cancelRowEvent(row) {
|
||||
if (this.$refs["table"]) {
|
||||
this.$refs["table"].clearEdit().then(() => {
|
||||
// 还原行数据
|
||||
this.$refs["table"].revertData(row);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
async getList() {
|
||||
this.loading = true;
|
||||
try {
|
||||
const res = await index(this.select, false);
|
||||
this.tableData = res<% if (!data.options?.isTree) { %>.data<% } %>;
|
||||
this.total = res.total;
|
||||
this.loading = false;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
async saveRowEvent(row) {
|
||||
if (window.$_uploading) {
|
||||
this.$message.warning("文件正在上传中")
|
||||
return
|
||||
}
|
||||
try {
|
||||
const errMap = await this.$refs["table"].validate();
|
||||
if (errMap) {
|
||||
throw new Error(errMap);
|
||||
}
|
||||
await this.$confirm("确认保存?", "提示", {
|
||||
confirmButtonText: "确认",
|
||||
cancelButtonText: "取消",
|
||||
});
|
||||
await this.$refs["table"].clearEdit();
|
||||
let form = deepCopy(this.form);
|
||||
for (const key in form) {
|
||||
form[key] = row[key];
|
||||
}
|
||||
<% for (let index in data.fields) {
|
||||
if (data.fields[index].relationName) {
|
||||
if (data.fields[index].type === 'file') {
|
||||
if (data.fields[index].props?.multiple) {
|
||||
%>
|
||||
form['<%- data.fields[index].name %>'] = row['<%- data.fields[index].relationName %>'].map(i => i.response?.id).filter(i => i)
|
||||
<% } else { %>
|
||||
form['<%- data.fields[index].name %>'] = (row['<%- data.fields[index].relationName %>']?.response?.id || row['<%- data.fields[index].relationName %>']?.id) ?? ''
|
||||
<% }
|
||||
}
|
||||
}
|
||||
} %>
|
||||
this.loading = true;
|
||||
await save(form, false);
|
||||
await this.getList();
|
||||
this.loading = false;
|
||||
} catch (err) {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
async destroyRowEvent(row) {
|
||||
try {
|
||||
await this.$confirm("确认删除?", "提示", {
|
||||
confirmButtonText: "确认",
|
||||
cancelButtonText: "取消",
|
||||
});
|
||||
this.loading = true;
|
||||
if (row.id) {
|
||||
await destroy({
|
||||
id: row.id,
|
||||
},false);
|
||||
await this.getList();
|
||||
} else {
|
||||
console.log(row);
|
||||
this.tableData.splice(
|
||||
this.tableData.findIndex((i) => i._X_ROW_KEY === row._X_ROW_KEY),
|
||||
1
|
||||
);
|
||||
}
|
||||
this.loading = false;
|
||||
} catch (err) {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
::v-deep .el-card__header {
|
||||
padding: 6px 20px;
|
||||
}
|
||||
::v-deep .el-tag + .el-tag {
|
||||
margin-left: 4px;
|
||||
}
|
||||
</style>
|
||||
@ -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
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
|
||||
Loading…
Reference in new issue