guregu/null测试失败版

This commit is contained in:
xiangheng
2024-08-09 14:01:05 +08:00
parent f0fe3f493f
commit cae4690703
35 changed files with 790 additions and 370 deletions

View File

@@ -17,7 +17,7 @@
"@highlightjs/vue-plugin": "^2.1.0",
"@logicflow/core": "^1.2.28",
"@logicflow/extension": "^1.2.28",
"@vue/shared": "^3.4.35",
"@vue/shared": "^3.4.37",
"@vueuse/core": "^10.11.0",
"@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^5.1.12",
@@ -30,13 +30,13 @@
"highlight.js": "^11.10.0",
"lodash-es": "^4.17.21",
"nprogress": "^0.2.0",
"pinia": "^2.2.0",
"pinia": "^2.2.1",
"query-string": "^9.1.0",
"vform3-builds": "^3.0.10",
"vue": "^3.4.35",
"vue": "^3.4.37",
"vue-clipboard3": "^2.0.0",
"vue-echarts": "^6.7.3",
"vue-router": "^4.4.2",
"vue-router": "^4.4.3",
"vue3-video-play": "^1.3.2",
"vuedraggable": "^4.1.0"
},
@@ -61,9 +61,9 @@
"sass": "^1.77.8",
"tailwindcss": "^3.4.7",
"typescript": "~5.5.4",
"unplugin-auto-import": "^0.17.8",
"unplugin-auto-import": "^0.18.2",
"unplugin-vue-components": "^0.27.3",
"vite": "^5.3.5",
"vite": "^5.4.0",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-style-import": "^2.0.0",
"vite-plugin-svg-icons": "^2.0.1",

View File

@@ -1,7 +1,9 @@
<template>
<div>
<template v-for="(item, index) in getOptions" :key="index">
<span :style="{ color: item.color }">{{ index != 0 ? '、' : '' }}{{ item.name }}</span>
<span :style="{ color: item.color }"
>{{ index != 0 ? '、' : '' }}{{ item[props.valueKey] }}</span
>
</template>
</div>
</template>
@@ -10,9 +12,14 @@ const props = withDefaults(
defineProps<{
options: any[]
value: any
labelKey?: string
valueKey?: string
}>(),
{
options: () => []
options: () => [],
value: null,
labelKey: 'name',
valueKey: 'value'
}
)
@@ -25,6 +32,6 @@ const values = computed(() => {
})
const getOptions = computed(() => {
return props.options.filter((item) => values.value.includes(item.value))
return props.options.filter((item) => values.value.includes(item[props.valueKey]))
})
</script>

View File

@@ -7,7 +7,7 @@
:mode="mode"
/>
<w-editor
class="overflow-y-auto flex-1"
class="overflow-y-auto flex-1 border-solid border rounded-s"
v-model="valueHtml"
:defaultConfig="editorConfig"
:mode="mode"

View File

@@ -12,6 +12,7 @@
:width="width"
draggable
:close-on-click-modal="clickModalClose"
top="0"
@closed="close"
>
<!-- 弹窗内容 -->
@@ -127,8 +128,12 @@ export default defineComponent({
})
</script>
<style scoped lang="scss">
<style lang="scss">
.dialog-body {
white-space: pre-line;
}
.el-dialog__body {
max-height: calc(100vh - 200px);
overflow: auto;
}
</style>

View File

@@ -1,3 +1,4 @@
import request from '@/utils/request'
import { dictDataAll } from '@/api/setting/dict'
import { reactive, toRaw } from 'vue'
@@ -38,6 +39,18 @@ export function useDictOptions<T = any>(options: Options) {
}
}
export type type_dict = {
color?: string
createTime?: string
id?: number
name?: string
remark?: string
sort?: number
status?: number
typeId?: number
updateTime?: string
value?: string
}
export function useDictData<T = any>(dict: string[]) {
const options: Options = {}
for (const type of dict) {
@@ -54,4 +67,24 @@ export function useDictData<T = any>(dict: string[]) {
}
}
// export function useAllList<T = any>(options: Options) {}
export function useListAllData<T = any>(paths: Record<string, string>) {
const options: Options = {}
for (const key in paths) {
options[key] = {
api: () => request.get({ url: paths[key], params: {} }),
transformData: (data: any) => {
console.log('data', data)
return data
}
// params: {
// dictType: path
// }
}
}
const { optionsData } = useDictOptions<T>(options)
return {
listAllData: optionsData
}
}

View File

@@ -73,7 +73,7 @@
</template>
</el-table-column>
<el-table-column label="sql类型" prop="columnType" min-width="100" />
<el-table-column label="go类型" min-width="100">
<el-table-column label="go类型" min-width="120">
<template v-slot="{ row }">
<el-select v-model="row.goType">
<el-option label="int" value="int" />
@@ -136,7 +136,7 @@
/>
</template>
</el-table-column>
<el-table-column label="查询方式">
<el-table-column label="查询方式" min-width="140">
<template v-slot="{ row }">
<el-select v-model="row.queryType">
<el-option label="=" value="EQ" />
@@ -165,19 +165,19 @@
</el-select>
</template>
</el-table-column>
<el-table-column label="字典类型" min-width="120">
<el-table-column label="字典类型" min-width="140">
<template v-slot="{ row }">
<el-select
v-model="row.dictType"
clearable
:disabled="
!(
row.htmlType == 'select' ||
v-if="
(row.htmlType == 'select' ||
row.htmlType == 'radio' ||
row.htmlType == 'checkbox'
)
row.htmlType == 'checkbox') &&
!row.listAllApi
"
placeholder="字典类型"
@change="row.listAllApi = null"
>
<el-option
v-for="(item, index) in optionsData.dictType"
@@ -189,6 +189,31 @@
</el-select>
</template>
</el-table-column>
<el-table-column label="数据来源(字典类型优先)" min-width="280">
<template v-slot="{ row }">
<el-select
v-model="row.listAllApi"
clearable
filterable
v-if="
(row.htmlType == 'select' ||
row.htmlType == 'radio' ||
row.htmlType == 'checkbox') &&
!row.dictType
"
placeholder="字典类型"
@change="row.dictType = null"
>
<el-option
v-for="(item, index) in optionsData.ApiList"
:key="index"
:label="item"
:value="item"
/>
</el-select>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="生成配置" name="config">
@@ -270,6 +295,7 @@ import { dictTypeAll } from '@/api/setting/dict'
import type { FormInstance } from 'element-plus'
import feedback from '@/utils/feedback'
import { menuLists } from '@/api/perms/menu'
import { getApiList } from '@/api/setting/website'
import { useDictOptions } from '@/hooks/useDictOptions'
import useMultipleTabs from '@/hooks/useMultipleTabs'
enum GenTpl {
@@ -332,6 +358,7 @@ const getDetails = async () => {
const { optionsData } = useDictOptions<{
dictType: any[]
menu: any[]
ApiList: string[]
}>({
dictType: {
api: dictTypeAll
@@ -343,6 +370,14 @@ const { optionsData } = useDictOptions<{
menu.children = data
return menu
}
},
ApiList: {
api: getApiList,
transformData(data: any) {
return data.filter((item: any) => {
return item.endsWith('listAll')
})
}
}
})

View File

@@ -1,7 +1,13 @@
<template>
<div class="code-preview">
<el-dialog v-model="show" width="95%" title="代码预览" top="10px" draggable>
<el-container style="height: calc(100vh - 170px)">
<el-dialog
v-model="show"
width="98%"
:title="'代码预览【' + showItem.label + '】'"
top="0px"
draggable
>
<el-container style="max-height: calc(100vh - 200px)">
<el-aside
width="400px"
style="padding: 10px 0; margin-right: 20px; border: 1px solid #dcdfe6"
@@ -15,7 +21,7 @@
</el-aside>
<el-main style="padding: 0; border: 1px solid #dcdfe6">
<div class="flex flex-col h-[100%]">
<div class="flex">
<!-- <div class="flex">
<div class="flex-1 p-4">{{ showItem.label }}</div>
<div>
<el-button @click="handleCopy(showItem.value)" type="primary" link>
@@ -25,14 +31,32 @@
复制
</el-button>
</div>
</div>
</div> -->
<div class="flex-1 overflow-auto">
<highlightjs autodetect :code="showItem.value" language="javascript" />
<div style="height: calc(100vh - 200px)">
<highlightjs
autodetect
:code="showItem.value"
language="javascript"
/>
</div>
</div>
</div>
</el-main>
</el-container>
<template v-slot:footer>
<div>
<!-- {{ showItem.label }} -->
<el-button
icon="el-icon-CopyDocument"
type="primary"
@click="handleCopy(showItem.value)"
>复制</el-button
>
<el-button @click="show = false">关闭</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
@@ -110,3 +134,9 @@ const show = computed<boolean>({
}
})
</script>
<style lang="scss">
.code-preview .el-dialog__body {
// max-height: calc(100vh - 200px);
overflow: auto;
}
</style>

View File

@@ -1,3 +1,6 @@
# goreleaser release --snapshot --clean
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com
@@ -18,6 +21,9 @@ before:
builds:
- env:
- CGO_ENABLED=0
goarch:
- amd64
# - arm64
goos:
- linux
- windows

View File

@@ -1,5 +1,7 @@
{
"cSpell.words": [
"daterange",
"datetime",
"dcloudio",
"endregion",
"excelize",
@@ -14,9 +16,12 @@
"jinzhu",
"mapstructure",
"oneof",
"qrtz",
"rmvb",
"singleflight",
"strconv",
"struct",
"typeof",
"uniapp",
"Warnf",
"webp",

View File

@@ -60,4 +60,5 @@ func RegisterGroup(rg *gin.RouterGroup) {
MonitorProjectRoute(rg)
MonitorClientRoute(rg)
MonitorWebRoute(rg)
SystemLogSmsRoute(rg)
}

View File

@@ -58,6 +58,7 @@ type EditColumn struct {
QueryType string `form:"queryType" binding:"required,max=30"` // 查询方式
HtmlType string `form:"htmlType" binding:"required,max=30"` // 表单类型
DictType string `form:"dictType" binding:"required,max=200"` // 字典类型
ListAllApi string `form:"listAllApi" binding:"max=200"` // 下拉框数据来源listAll
CreateTime core.TsTime `form:"createTime"` // 创建时间
UpdateTime core.TsTime `form:"updateTime"` // 更新时间
@@ -169,6 +170,7 @@ type GenColumnResp struct {
QueryType string `json:"queryType" structs:"queryType"` // 查询方式: [等于、不等于、大于、小于、范围]
HtmlType string `json:"htmlType" structs:"htmlType"` // 显示类型: [文本框、文本域、下拉框、复选框、单选框、日期控件]
DictType string `json:"dictType" structs:"dictType"` // 字典类型
ListAllApi string `json:"listAllApi" structs:"listAllApi"` // 下拉框数据来源listAll
CreateTime core.TsTime `json:"createTime" structs:"createTime"` // 创建时间
UpdateTime core.TsTime `json:"updateTime" structs:"updateTime"` // 更新时间
}

View File

@@ -220,7 +220,9 @@ func (genSrv generateService) SyncTable(id uint) (e error) {
col.ID = prevCol.ID
if col.IsList == 0 {
col.DictType = prevCol.DictType
col.ListAllApi = prevCol.ListAllApi
col.QueryType = prevCol.QueryType
}
if prevCol.IsRequired == 1 && prevCol.IsPk == 0 && prevCol.IsInsert == 1 || prevCol.IsEdit == 1 {
col.HtmlType = prevCol.HtmlType

View File

@@ -35,7 +35,7 @@ var SqlConstants = sqlConstants{
//页面不需要编辑字段
ColumnNameNotEdit: []string{"is_delete", "create_time", "update_time", "delete_time"},
//页面不需要列表字段
ColumnNameNotList: []string{"id", "intro", "content", "is_delete", "delete_time"},
ColumnNameNotList: []string{"id", "is_delete", "delete_time"},
//页面不需要查询字段
ColumnNameNotQuery: []string{"is_delete", "delete_time"}, //"create_time", "update_time",
}

View File

@@ -13,7 +13,7 @@ import (
)
type {{{ title (toCamelCase .ModuleName) }}}Handler struct {
type {{{ toUpperCamelCase .ModuleName }}}Handler struct {
requestGroup singleflight.Group
}
@@ -33,18 +33,18 @@ type {{{ title (toCamelCase .ModuleName) }}}Handler struct {
{{{- end }}}
{{{- end }}}
{{{- end }}}
//@Success 200 {object} {{{getPageResp (title (toCamelCase .EntityName)) }}} "成功"
//@Success 200 {object} {{{getPageResp (toUpperCamelCase .EntityName) }}} "成功"
//@Router /api/admin/{{{ .ModuleName }}}/list [get]
func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) List(c *gin.Context) {
func (hd *{{{ toUpperCamelCase .ModuleName }}}Handler) List(c *gin.Context) {
var page request.PageReq
var listReq {{{ title (toCamelCase .EntityName) }}}ListReq
var listReq {{{ toUpperCamelCase .EntityName }}}ListReq
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &page)) {
return
}
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &listReq)) {
return
}
res, err := {{{ title (toCamelCase .EntityName) }}}Service.List(page, listReq)
res, err := {{{ toUpperCamelCase .EntityName }}}Service.List(page, listReq)
response.CheckAndRespWithData(c, res, err)
}
@@ -61,14 +61,14 @@ func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) List(c *gin.Context)
{{{- end }}}
{{{- end }}}
{{{- end }}}
// @Success 200 {object} response.Response{ data=[]{{{ title (toCamelCase .EntityName) }}}Resp} "成功"
// @Success 200 {object} response.Response{ data=[]{{{ toUpperCamelCase .EntityName }}}Resp} "成功"
// @Router /api/admin/{{{ .ModuleName }}}/listAll [get]
func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) ListAll(c *gin.Context) {
var listReq {{{ title (toCamelCase .EntityName) }}}ListReq
func (hd *{{{ toUpperCamelCase .ModuleName }}}Handler) ListAll(c *gin.Context) {
var listReq {{{ toUpperCamelCase .EntityName }}}ListReq
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &listReq)) {
return
}
res, err := {{{ title (toCamelCase .EntityName) }}}Service.ListAll(listReq)
res, err := {{{ toUpperCamelCase .EntityName }}}Service.ListAll(listReq)
response.CheckAndRespWithData(c, res, err)
}
@@ -81,15 +81,15 @@ func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) ListAll(c *gin.Contex
// @Param {{{ toCamelCase .GoField }}} query {{{ .GoType }}} false "{{{ .ColumnComment }}}"
{{{- end }}}
{{{- end }}}
// @Success 200 {object} response.Response{ data={{{ title (toCamelCase .EntityName) }}}Resp} "成功"
// @Success 200 {object} response.Response{ data={{{ toUpperCamelCase .EntityName }}}Resp} "成功"
// @Router /api/admin/{{{ .ModuleName }}}/detail [get]
func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) Detail(c *gin.Context) {
var detailReq {{{ title (toCamelCase .EntityName) }}}DetailReq
func (hd *{{{ toUpperCamelCase .ModuleName }}}Handler) Detail(c *gin.Context) {
var detailReq {{{ toUpperCamelCase .EntityName }}}DetailReq
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &detailReq)) {
return
}
res, err, _ := hd.requestGroup.Do("{{{ title (toCamelCase .EntityName) }}}:Detail:"+strconv.Itoa(detailReq.{{{ title (toCamelCase .PrimaryKey) }}}), func() (any, error) {
v, err := {{{ title (toCamelCase .EntityName) }}}Service.Detail(detailReq.{{{ title (toCamelCase .PrimaryKey) }}})
res, err, _ := hd.requestGroup.Do("{{{ toUpperCamelCase .EntityName }}}:Detail:"+strconv.Itoa(detailReq.{{{ toUpperCamelCase .PrimaryKey }}}), func() (any, error) {
v, err := {{{ toUpperCamelCase .EntityName }}}Service.Detail(detailReq.{{{ toUpperCamelCase .PrimaryKey }}})
return v, err
})
@@ -108,12 +108,12 @@ func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) Detail(c *gin.Context
{{{- end }}}
// @Success 200 {object} response.Response "成功"
// @Router /api/admin/{{{ .ModuleName }}}/add [post]
func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) Add(c *gin.Context) {
var addReq {{{ title (toCamelCase .EntityName) }}}AddReq
func (hd *{{{ toUpperCamelCase .ModuleName }}}Handler) Add(c *gin.Context) {
var addReq {{{ toUpperCamelCase .EntityName }}}AddReq
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &addReq)) {
return
}
createId, e := {{{ title (toCamelCase .EntityName) }}}Service.Add(addReq)
createId, e := {{{ toUpperCamelCase .EntityName }}}Service.Add(addReq)
response.CheckAndRespWithData(c,createId, e)
}
// @Summary {{{ .FunctionName }}}编辑
@@ -127,12 +127,12 @@ func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) Add(c *gin.Context) {
{{{- end }}}
// @Success 200 {object} response.Response "成功"
// @Router /api/admin/{{{ .ModuleName }}}/edit [post]
func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) Edit(c *gin.Context) {
var editReq {{{ title (toCamelCase .EntityName) }}}EditReq
func (hd *{{{ toUpperCamelCase .ModuleName }}}Handler) Edit(c *gin.Context) {
var editReq {{{ toUpperCamelCase .EntityName }}}EditReq
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &editReq)) {
return
}
response.CheckAndRespWithData(c,editReq.{{{ title (toCamelCase .PrimaryKey) }}}, {{{ title (toCamelCase .EntityName) }}}Service.Edit(editReq))
response.CheckAndRespWithData(c,editReq.{{{ toUpperCamelCase .PrimaryKey }}}, {{{ toUpperCamelCase .EntityName }}}Service.Edit(editReq))
}
// @Summary {{{ .FunctionName }}}删除
// @Tags {{{ .ModuleName }}}-{{{ .FunctionName }}}
@@ -145,12 +145,12 @@ func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) Edit(c *gin.Context)
{{{- end }}}
// @Success 200 {object} response.Response "成功"
// @Router /api/admin/{{{ .ModuleName }}}/del [post]
func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) Del(c *gin.Context) {
var delReq {{{ title (toCamelCase .EntityName) }}}DelReq
func (hd *{{{ toUpperCamelCase .ModuleName }}}Handler) Del(c *gin.Context) {
var delReq {{{ toUpperCamelCase .EntityName }}}DelReq
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &delReq)) {
return
}
response.CheckAndResp(c, {{{ title (toCamelCase .EntityName) }}}Service.Del(delReq.{{{ title (toCamelCase .PrimaryKey) }}}))
response.CheckAndResp(c, {{{ toUpperCamelCase .EntityName }}}Service.Del(delReq.{{{ toUpperCamelCase .PrimaryKey }}}))
}
@@ -170,12 +170,12 @@ func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) Del(c *gin.Context) {
{{{- end }}}
{{{- end }}}
// @Router /api/admin/{{{ .ModuleName }}}/ExportFile [get]
func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) ExportFile(c *gin.Context) {
var listReq {{{ title (toCamelCase .EntityName) }}}ListReq
func (hd *{{{ toUpperCamelCase .ModuleName }}}Handler) ExportFile(c *gin.Context) {
var listReq {{{ toUpperCamelCase .EntityName }}}ListReq
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &listReq)) {
return
}
res, err := {{{ title (toCamelCase .EntityName) }}}Service.ExportFile(listReq)
res, err := {{{ toUpperCamelCase .EntityName }}}Service.ExportFile(listReq)
if err != nil {
response.FailWithMsg(c, response.SystemError, "查询信息失败")
return
@@ -192,22 +192,20 @@ func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) ExportFile(c *gin.Con
// @Tags {{{ .ModuleName }}}-{{{ .FunctionName }}}
// @Produce json
// @Router /api/admin/{{{ .ModuleName }}}/ImportFile [post]
func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) ImportFile(c *gin.Context) {
func (hd *{{{ toUpperCamelCase .ModuleName }}}Handler) ImportFile(c *gin.Context) {
file, _, err := c.Request.FormFile("file")
if err != nil {
c.String(http.StatusInternalServerError, "文件不存在")
return
}
defer file.Close()
importList := []{{{ title (toCamelCase .EntityName) }}}Resp{}
importList := []{{{ toUpperCamelCase .EntityName }}}Resp{}
err = excel.GetExcelData(file, &importList)
if err != nil {
c.String(http.StatusInternalServerError, err.Error())
return
}
// for _, t := range importList {
// fmt.Printf("%#v", t)
// }
err = {{{ title (toCamelCase .EntityName) }}}Service.ImportFile(importList)
err = {{{ toUpperCamelCase .EntityName }}}Service.ImportFile(importList)
response.CheckAndResp(c, err)
}

View File

@@ -2,19 +2,22 @@ package model
import (
"x_admin/core"
"gorm.io/plugin/soft_delete"
"github.com/guregu/null/v5"
)
//{{{ title (toCamelCase .EntityName) }}} {{{ .FunctionName }}}实体
type {{{ title (toCamelCase .EntityName) }}} struct {
//{{{ toUpperCamelCase .EntityName }}} {{{ .FunctionName }}}实体
type {{{ toUpperCamelCase .EntityName }}} struct {
{{{- range .Columns }}}
{{{- if not (contains $.SubTableFields .ColumnName) }}}
{{{ if eq .GoField "is_delete" }}}
{{{- if eq .GoField "is_delete" }}}
IsDelete soft_delete.DeletedAt `gorm:"not null;default:0;softDelete:flag,DeletedAtField:DeleteTime;comment:'是否删除: 0=否, 1=是'"`
{{{ else }}}
{{{ if eq .GoType "core.TsTime" }}}
{{{ title (toCamelCase .GoField) }}} core.TsTime `gorm:"{{{ if eq .GoField "create_time" }}}autoCreateTime;{{{ else }}}{{{if eq .GoField "update_time"}}}autoUpdateTime;{{{ end }}}{{{ end }}}comment:'{{{ .ColumnComment }}}'" excel:"name:{{{ .ColumnComment }}};"` // {{{ .ColumnComment }}}
{{{ else }}}
{{{ title (toCamelCase .GoField) }}} {{{ .GoType }}} `gorm:"{{{ if .IsPk }}}primarykey;{{{ end }}}comment:'{{{ .ColumnComment }}}'" excel:"name:{{{ .ColumnComment }}};"` // {{{ .ColumnComment }}}
{{{- else }}}
{{{- if eq .GoType "core.TsTime" }}}
{{{ toUpperCamelCase .GoField }}} core.TsTime `gorm:"{{{ if eq .GoField "create_time" }}}autoCreateTime;{{{ else }}}{{{if eq .GoField "update_time"}}}autoUpdateTime;{{{ end }}}{{{ end }}}comment:'{{{ .ColumnComment }}}'" excel:"name:{{{ .ColumnComment }}};"` // {{{ .ColumnComment }}}
{{{- else if .IsPk }}}
{{{ toUpperCamelCase .GoField }}} {{{ .GoType }}} `gorm:"primarykey;" excel:"name:{{{ .ColumnComment }}};"` // {{{ .ColumnComment }}}
{{{- else }}}
{{{ toUpperCamelCase .GoField }}} {{{goToNullType .GoType }}} `gorm:"" excel:"name:{{{ .ColumnComment }}};"` // {{{ .ColumnComment }}}
{{{- end }}}
{{{- end }}}

View File

@@ -13,7 +13,7 @@ import (
- 下载并解压压缩包后直接复制server、admin文件夹到项目根目录即可
2. 注册路由
请在 admin/entry.go 文件引入{{{ title (toCamelCase .ModuleName) }}}Route注册路由
请在 admin/entry.go 文件引入{{{ toUpperCamelCase .ModuleName }}}Route注册路由
3. 后台手动添加菜单和按钮
admin:{{{ .ModuleName }}}:add
@@ -26,8 +26,9 @@ admin:{{{.ModuleName }}}:ExportFile
admin:{{{.ModuleName }}}:ImportFile
// 列表-先添加菜单获取菜单id
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, paths, component, is_cache, is_show, is_disable, create_time, update_time) VALUES (0, 'C', '{{{ .FunctionName }}}', '/{{{ .ModuleName }}}/index', '{{{ .ModuleName }}}/index', 0, 1, 0, now(), now());
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, paths, component, is_cache, is_show, is_disable, create_time, update_time) VALUES (0, 'C', '{{{nameToPath .FunctionName }}}', '{{{nameToPath .ModuleName }}}/index', '{{{ .ModuleName }}}/index', 0, 1, 0, now(), now());
按钮-替换pid参数为菜单id
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_show, is_disable, create_time, update_time) VALUES (0, 'A', '{{{ .FunctionName }}}添加','admin:{{{ .ModuleName }}}:add', 0, 1, 0, now(), now());
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_show, is_disable, create_time, update_time) VALUES (0, 'A', '{{{ .FunctionName }}}编辑','admin:{{{ .ModuleName }}}:edit', 0, 1, 0, now(), now());
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_show, is_disable, create_time, update_time) VALUES (0, 'A', '{{{ .FunctionName }}}删除','admin:{{{ .ModuleName }}}:del', 0, 1, 0, now(), now());
@@ -39,9 +40,9 @@ INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_sh
*/
// {{{ title (toCamelCase .ModuleName) }}}Route(rg)
func {{{ title (toCamelCase .ModuleName) }}}Route(rg *gin.RouterGroup) {
handle := {{{ .ModuleName}}}.{{{ title (toCamelCase .EntityName) }}}Handler{}
// {{{ toUpperCamelCase .ModuleName }}}Route(rg)
func {{{ toUpperCamelCase .ModuleName }}}Route(rg *gin.RouterGroup) {
handle := {{{ .ModuleName}}}.{{{ toUpperCamelCase .EntityName }}}Handler{}
r := rg.Group("/", middleware.TokenAuth())
r.GET("/{{{ .ModuleName }}}/list", handle.List)

View File

@@ -1,64 +1,74 @@
package {{{ .ModuleName }}}
import (
"x_admin/core"
"github.com/guregu/null/v5"
)
//{{{ title (toCamelCase .EntityName) }}}ListReq {{{ .FunctionName }}}列表参数
type {{{ title (toCamelCase .EntityName) }}}ListReq struct {
//{{{ toUpperCamelCase .EntityName }}}ListReq {{{ .FunctionName }}}列表参数
type {{{ toUpperCamelCase .EntityName }}}ListReq struct {
{{{- range .Columns }}}
{{{- if .IsQuery }}}
{{{- if eq .HtmlType "datetime" }}}
{{{ title (toCamelCase .GoField) }}}Start string `form:"{{{ toCamelCase .GoField }}}Start"` // {{{ .ColumnComment }}}
{{{ title (toCamelCase .GoField) }}}End string `form:"{{{ toCamelCase .GoField }}}End"` // {{{ .ColumnComment }}}
{{{ toUpperCamelCase .GoField }}}Start null.String `form:"{{{ toCamelCase .GoField }}}Start"` // {{{ .ColumnComment }}}
{{{ toUpperCamelCase .GoField }}}End null.String `form:"{{{ toCamelCase .GoField }}}End"` // {{{ .ColumnComment }}}
{{{- else }}}
{{{ title (toCamelCase .GoField) }}} {{{ .GoType }}} `form:"{{{ toCamelCase .GoField }}}"` // {{{ .ColumnComment }}}
{{{ toUpperCamelCase .GoField }}} {{{goToNullType .GoType }}} `form:"{{{ toCamelCase .GoField }}}"` // {{{ .ColumnComment }}}
{{{- end }}}
{{{- end }}}
{{{- end }}}
}
//{{{ title (toCamelCase .EntityName) }}}DetailReq {{{ .FunctionName }}}详情参数
type {{{ title (toCamelCase .EntityName) }}}DetailReq struct {
{{{- range .Columns }}}
{{{- if .IsPk }}}
{{{ title (toCamelCase .GoField) }}} {{{ .GoType }}} `form:"{{{ toCamelCase .GoField }}}"` // {{{ .ColumnComment }}}
{{{- end }}}
{{{- end }}}
}
//{{{ title (toCamelCase .EntityName) }}}AddReq {{{ .FunctionName }}}新增参数
type {{{ title (toCamelCase .EntityName) }}}AddReq struct {
//{{{ toUpperCamelCase .EntityName }}}AddReq {{{ .FunctionName }}}新增参数
type {{{ toUpperCamelCase .EntityName }}}AddReq struct {
{{{- range .Columns }}}
{{{- if .IsInsert }}}
{{{ title (toCamelCase .GoField) }}} {{{ .GoType }}} `form:"{{{ toCamelCase .GoField }}}"` // {{{ .ColumnComment }}}
{{{ toUpperCamelCase .GoField }}} {{{goToNullType .GoType }}} `form:"{{{ toCamelCase .GoField }}}"` // {{{ .ColumnComment }}}
{{{- end }}}
{{{- end }}}
}
//{{{ title (toCamelCase .EntityName) }}}EditReq {{{ .FunctionName }}}编辑参数
type {{{ title (toCamelCase .EntityName) }}}EditReq struct {
//{{{ toUpperCamelCase .EntityName }}}EditReq {{{ .FunctionName }}}编辑参数
type {{{ toUpperCamelCase .EntityName }}}EditReq struct {
{{{- range .Columns }}}
{{{- if .IsEdit }}}
{{{ title (toCamelCase .GoField) }}} *{{{ .GoType }}} `form:"{{{ toCamelCase .GoField }}}"` // {{{ .ColumnComment }}}
{{{- if .IsPk }}}
{{{ toUpperCamelCase .GoField }}} {{{ .GoType }}} `form:"{{{ toCamelCase .GoField }}}"` // {{{ .ColumnComment }}}
{{{- else }}}
{{{ toUpperCamelCase .GoField }}} {{{goToNullType .GoType }}} `form:"{{{ toCamelCase .GoField }}}"` // {{{ .ColumnComment }}}
{{{- end }}}
{{{- end }}}
{{{- end }}}
}
//{{{ title (toCamelCase .EntityName) }}}DelReq {{{ .FunctionName }}}新增参数
type {{{ title (toCamelCase .EntityName) }}}DelReq struct {
//{{{ toUpperCamelCase .EntityName }}}DetailReq {{{ .FunctionName }}}详情参数
type {{{ toUpperCamelCase .EntityName }}}DetailReq struct {
{{{- range .Columns }}}
{{{- if .IsPk }}}
{{{ title (toCamelCase .GoField) }}} {{{ .GoType }}} `form:"{{{ toCamelCase .GoField }}}"` // {{{ .ColumnComment }}}
{{{ toUpperCamelCase .GoField }}} {{{.GoType }}} `form:"{{{ toCamelCase .GoField }}}"` // {{{ .ColumnComment }}}
{{{- end }}}
{{{- end }}}
}
//{{{ title (toCamelCase .EntityName) }}}Resp {{{ .FunctionName }}}返回信息
type {{{ title (toCamelCase .EntityName) }}}Resp struct {
//{{{ toUpperCamelCase .EntityName }}}DelReq {{{ .FunctionName }}}删除参数
type {{{ toUpperCamelCase .EntityName }}}DelReq struct {
{{{- range .Columns }}}
{{{- if .IsPk }}}
{{{ toUpperCamelCase .GoField }}} {{{ .GoType }}} `form:"{{{ toCamelCase .GoField }}}"` // {{{ .ColumnComment }}}
{{{- end }}}
{{{- end }}}
}
//{{{ toUpperCamelCase .EntityName }}}Resp {{{ .FunctionName }}}返回信息
type {{{ toUpperCamelCase .EntityName }}}Resp struct {
{{{- range .Columns }}}
{{{- if or .IsList .IsPk }}}
{{{- if .IsPk }}}
{{{ title (toCamelCase .GoField) }}} {{{ .GoType }}} `json:"{{{ toCamelCase .GoField }}}" structs:"{{{ toCamelCase .GoField }}}"` // {{{ .ColumnComment }}}
{{{ toUpperCamelCase .GoField }}} {{{ .GoType }}} `json:"{{{ toCamelCase .GoField }}}" structs:"{{{ toCamelCase .GoField }}}"` // {{{ .ColumnComment }}}
{{{- else }}}
{{{ title (toCamelCase .GoField) }}} {{{ .GoType }}} `json:"{{{ toCamelCase .GoField }}}" structs:"{{{ toCamelCase .GoField }}}" excel:"name:{{{ .ColumnComment }}};"` // {{{ .ColumnComment }}}
{{{ toUpperCamelCase .GoField }}} {{{goToNullType .GoType }}} `json:"{{{ toCamelCase .GoField }}}" structs:"{{{ toCamelCase .GoField }}}" excel:"name:{{{ .ColumnComment }}};"` // {{{ .ColumnComment }}}
{{{- end }}}
{{{- end }}}
{{{- end }}}

View File

@@ -6,72 +6,52 @@ import (
"x_admin/core/response"
"x_admin/model"
"gorm.io/gorm"
"x_admin/util"
)
var {{{ title (toCamelCase .EntityName) }}}Service=New{{{ title (toCamelCase .EntityName) }}}Service()
// New{{{ title (toCamelCase .EntityName) }}}Service 初始化
func New{{{ title (toCamelCase .EntityName) }}}Service() *{{{ toCamelCase .EntityName }}}Service {
db := core.GetDB()
return &{{{ toCamelCase .EntityName }}}Service{db: db}
var {{{ toUpperCamelCase .EntityName }}}Service=New{{{ toUpperCamelCase .EntityName }}}Service()
var cacheUtil = util.CacheUtil{
Name: {{{ toUpperCamelCase .EntityName }}}Service.Name,
}
// New{{{ toUpperCamelCase .EntityName }}}Service 初始化
func New{{{ toUpperCamelCase .EntityName }}}Service() *{{{ toCamelCase .EntityName }}}Service {
return &{{{ toCamelCase .EntityName }}}Service{
db: core.GetDB(),
Name: "{{{ toCamelCase .EntityName }}}",
}
}
//{{{ toCamelCase .EntityName }}}Service {{{ .FunctionName }}}服务实现类
type {{{ toCamelCase .EntityName }}}Service struct {
db *gorm.DB
Name string
}
// 设置缓存
func (service {{{ toCamelCase .EntityName }}}Service) SetCache(obj model.{{{ title (toCamelCase .EntityName) }}}) bool {
str, e := util.ToolsUtil.ObjToJson(obj)
if e != nil {
return false
}
return util.RedisUtil.HSet("{{{ toCamelCase .EntityName }}}",strconv.Itoa(obj.{{{ title (toCamelCase .PrimaryKey) }}}), str, 3600)
}
// 获取缓存
func (service {{{ toCamelCase .EntityName }}}Service) GetCache(key int) (model.{{{ title (toCamelCase .EntityName) }}}, error) {
var obj model.{{{ title (toCamelCase .EntityName) }}}
str := util.RedisUtil.HGet("{{{ toCamelCase .EntityName }}}", strconv.Itoa(key))
if str == "" {
return obj, errors.New("获取缓存失败")
}
err := util.ToolsUtil.JsonToObj(str, &obj)
if err != nil {
return obj, errors.New("获取缓存失败")
}
return obj, nil
}
// 删除缓存
func (service {{{ toCamelCase .EntityName }}}Service) RemoveCache(obj model.{{{ title (toCamelCase .EntityName) }}}) bool {
return util.RedisUtil.HDel("{{{ toCamelCase .EntityName }}}", strconv.Itoa(obj.{{{ title (toCamelCase .PrimaryKey) }}}))
}
// List {{{ .FunctionName }}}列表
func (service {{{ toCamelCase .EntityName }}}Service) GetModel(listReq {{{ title (toCamelCase .EntityName) }}}ListReq) *gorm.DB {
func (service {{{ toCamelCase .EntityName }}}Service) GetModel(listReq {{{ toUpperCamelCase .EntityName }}}ListReq) *gorm.DB {
//
dbModel := service.db.Model(&model.{{{ title (toCamelCase .EntityName) }}}{})
dbModel := service.db.Model(&model.{{{ toUpperCamelCase .EntityName }}}{})
{{{- range .Columns }}}
{{{- if .IsQuery }}}
{{{- $queryOpr := index $.ModelOprMap .QueryType }}}
{{{- if eq .HtmlType "datetime" }}}
if listReq.{{{ title (toCamelCase .ColumnName) }}}Start != "" {
dbModel = dbModel.Where("{{{ .ColumnName }}} >= ?", listReq.{{{ title (toCamelCase .ColumnName) }}}Start)
if listReq.{{{ toUpperCamelCase .ColumnName }}}Start.Valid {
dbModel = dbModel.Where("{{{ .ColumnName }}} >= ?", listReq.{{{ toUpperCamelCase .ColumnName }}}Start.ValueOrZero())
}
if listReq.{{{ title (toCamelCase .ColumnName) }}}End != "" {
dbModel = dbModel.Where("{{{ .ColumnName }}} <= ?", listReq.{{{ title (toCamelCase .ColumnName) }}}End)
if listReq.{{{ toUpperCamelCase .ColumnName }}}End.Valid {
dbModel = dbModel.Where("{{{ .ColumnName }}} <= ?", listReq.{{{ toUpperCamelCase .ColumnName }}}End.ValueOrZero())
}
{{{- else }}}
{{{- if and (eq .GoType "string") (eq $queryOpr "like") }}}
if listReq.{{{ title (toCamelCase .ColumnName) }}} != "" {
dbModel = dbModel.Where("{{{ .ColumnName }}} like ?", "%"+listReq.{{{ title (toCamelCase .ColumnName) }}}+"%")
if listReq.{{{ toUpperCamelCase .ColumnName }}}.Valid {
dbModel = dbModel.Where("{{{ .ColumnName }}} like ?", "%"+listReq.{{{ toUpperCamelCase .ColumnName }}}.ValueOrZero()+"%")
}
{{{- else }}}
if listReq.{{{ title (toCamelCase .ColumnName) }}} {{{ if eq .GoType "string" }}}!= ""{{{ else }}}> 0{{{ end }}} {
dbModel = dbModel.Where("{{{ .ColumnName }}} = ?", listReq.{{{ title (toCamelCase .ColumnName) }}})
if listReq.{{{ toUpperCamelCase .ColumnName }}}.Valid {
dbModel = dbModel.Where("{{{ .ColumnName }}} = ?", listReq.{{{ toUpperCamelCase .ColumnName }}}.ValueOrZero())
}
{{{- end }}}
{{{- end }}}
@@ -83,7 +63,7 @@ func (service {{{ toCamelCase .EntityName }}}Service) GetModel(listReq {{{ title
return dbModel
}
// List {{{ .FunctionName }}}列表
func (service {{{ toCamelCase .EntityName }}}Service) List(page request.PageReq, listReq {{{ title (toCamelCase .EntityName) }}}ListReq) (res response.PageResp, e error) {
func (service {{{ toCamelCase .EntityName }}}Service) List(page request.PageReq, listReq {{{ toUpperCamelCase .EntityName }}}ListReq) (res response.PageResp, e error) {
//
limit := page.PageSize
offset := page.PageSize * (page.PageNo - 1)
@@ -95,12 +75,12 @@ func (service {{{ toCamelCase .EntityName }}}Service) List(page request.PageReq,
return
}
//
var modelList []model.{{{ title (toCamelCase .EntityName) }}}
var modelList []model.{{{ toUpperCamelCase .EntityName }}}
err = dbModel.Limit(limit).Offset(offset).Order("id desc").Find(&modelList).Error
if e = response.CheckErr(err, "查询失败"); e != nil {
return
}
result := []{{{ title (toCamelCase .EntityName) }}}Resp{}
result := []{{{ toUpperCamelCase .EntityName }}}Resp{}
response.Copy(&result, modelList)
return response.PageResp{
PageNo: page.PageNo,
@@ -110,10 +90,10 @@ func (service {{{ toCamelCase .EntityName }}}Service) List(page request.PageReq,
}, nil
}
// ListAll {{{ .FunctionName }}}列表
func (service {{{ toCamelCase .EntityName }}}Service) ListAll(listReq {{{ title (toCamelCase .EntityName) }}}ListReq) (res []{{{ title (toCamelCase .EntityName) }}}Resp, e error) {
func (service {{{ toCamelCase .EntityName }}}Service) ListAll(listReq {{{ toUpperCamelCase .EntityName }}}ListReq) (res []{{{ toUpperCamelCase .EntityName }}}Resp, e error) {
dbModel := service.GetModel(listReq)
var modelList []model.{{{ title (toCamelCase .EntityName) }}}
var modelList []model.{{{ toUpperCamelCase .EntityName }}}
err := dbModel.Find(&modelList).Error
if e = response.CheckErr(err, "查询全部失败"); e != nil {
@@ -124,11 +104,11 @@ func (service {{{ toCamelCase .EntityName }}}Service) ListAll(listReq {{{ title
}
// Detail {{{ .FunctionName }}}详情
func (service {{{ toCamelCase .EntityName }}}Service) Detail({{{ title (toCamelCase .PrimaryKey) }}} int) (res {{{ title (toCamelCase .EntityName) }}}Resp, e error) {
var obj, err = service.GetCache({{{ title (toCamelCase .PrimaryKey) }}})
// var obj model.{{{ title (toCamelCase .EntityName) }}}
func (service {{{ toCamelCase .EntityName }}}Service) Detail({{{ toUpperCamelCase .PrimaryKey }}} int) (res {{{ toUpperCamelCase .EntityName }}}Resp, e error) {
var obj = model.SystemLogSms{}
err := cacheUtil.GetCache({{{ toUpperCamelCase .PrimaryKey }}}, &obj)
if err != nil {
err := service.db.Where("{{{ $.PrimaryKey }}} = ?{{{ if contains .AllFields "is_delete" }}} AND is_delete = ?{{{ end }}}", {{{ title (toCamelCase .PrimaryKey) }}}{{{ if contains .AllFields "is_delete" }}}, 0{{{ end }}}).Limit(1).First(&obj).Error
err := service.db.Where("{{{ $.PrimaryKey }}} = ?{{{ if contains .AllFields "is_delete" }}} AND is_delete = ?{{{ end }}}", {{{ toUpperCamelCase .PrimaryKey }}}{{{ if contains .AllFields "is_delete" }}}, 0{{{ end }}}).Limit(1).First(&obj).Error
if e = response.CheckErrDBNotRecord(err, "数据不存在!"); e != nil {
return
}
@@ -141,7 +121,7 @@ func (service {{{ toCamelCase .EntityName }}}Service) Detail({{{ title (toCamelC
res.Avatar = util.UrlUtil.ToAbsoluteUrl(res.Avatar)
{{{- end }}}
{{{- end }}}
service.SetCache(obj)
cacheUtil.SetCache(obj.{{{ toUpperCamelCase .PrimaryKey }}}, obj)
}
@@ -149,24 +129,24 @@ func (service {{{ toCamelCase .EntityName }}}Service) Detail({{{ title (toCamelC
}
// Add {{{ .FunctionName }}}新增
func (service {{{ toCamelCase .EntityName }}}Service) Add(addReq {{{ title (toCamelCase .EntityName) }}}AddReq) (createId int,e error) {
var obj model.{{{ title (toCamelCase .EntityName) }}}
func (service {{{ toCamelCase .EntityName }}}Service) Add(addReq {{{ toUpperCamelCase .EntityName }}}AddReq) (createId int,e error) {
var obj model.{{{ toUpperCamelCase .EntityName }}}
response.Copy(&obj, addReq)
err := service.db.Create(&obj).Error
e = response.CheckMysqlErr(err)
if e != nil {
return 0,e
}
service.SetCache(obj)
createId = obj.{{{ title (toCamelCase .PrimaryKey) }}}
cacheUtil.SetCache(obj.{{{ toUpperCamelCase .PrimaryKey }}}, obj)
createId = obj.{{{ toUpperCamelCase .PrimaryKey }}}
e = response.CheckErr(err, "添加失败")
return
}
// Edit {{{ .FunctionName }}}编辑
func (service {{{ toCamelCase .EntityName }}}Service) Edit(editReq {{{ title (toCamelCase .EntityName) }}}EditReq) (e error) {
var obj model.{{{ title (toCamelCase .EntityName) }}}
err := service.db.Where("{{{ $.PrimaryKey }}} = ?{{{ if contains .AllFields "is_delete" }}} AND is_delete = ?{{{ end }}}", editReq.{{{ title (toCamelCase .PrimaryKey) }}}{{{ if contains .AllFields "is_delete" }}}, 0{{{ end }}}).Limit(1).First(&obj).Error
func (service {{{ toCamelCase .EntityName }}}Service) Edit(editReq {{{ toUpperCamelCase .EntityName }}}EditReq) (e error) {
var obj model.{{{ toUpperCamelCase .EntityName }}}
err := service.db.Where("{{{ $.PrimaryKey }}} = ?{{{ if contains .AllFields "is_delete" }}} AND is_delete = ?{{{ end }}}", editReq.{{{ toUpperCamelCase .PrimaryKey }}}{{{ if contains .AllFields "is_delete" }}}, 0{{{ end }}}).Limit(1).First(&obj).Error
//
if e = response.CheckErrDBNotRecord(err, "数据不存在!"); e != nil {
return
@@ -180,14 +160,14 @@ func (service {{{ toCamelCase .EntityName }}}Service) Edit(editReq {{{ title (to
if e = response.CheckErr(err, "编辑失败"); e != nil {
return
}
service.SetCache(obj)
cacheUtil.SetCache(obj.{{{ toUpperCamelCase .PrimaryKey }}}, obj)
return
}
// Del {{{ .FunctionName }}}删除
func (service {{{ toCamelCase .EntityName }}}Service) Del({{{ title (toCamelCase .PrimaryKey) }}} int) (e error) {
var obj model.{{{ title (toCamelCase .EntityName) }}}
err := service.db.Where("{{{ $.PrimaryKey }}} = ?{{{ if contains .AllFields "is_delete" }}} AND is_delete = ?{{{ end }}}", {{{ title (toCamelCase .PrimaryKey) }}}{{{ if contains .AllFields "is_delete" }}}, 0{{{ end }}}).Limit(1).First(&obj).Error
func (service {{{ toCamelCase .EntityName }}}Service) Del({{{ toUpperCamelCase .PrimaryKey }}} int) (e error) {
var obj model.{{{ toUpperCamelCase .EntityName }}}
err := service.db.Where("{{{ $.PrimaryKey }}} = ?{{{ if contains .AllFields "is_delete" }}} AND is_delete = ?{{{ end }}}", {{{ toUpperCamelCase .PrimaryKey }}}{{{ if contains .AllFields "is_delete" }}}, 0{{{ end }}}).Limit(1).First(&obj).Error
//
if e = response.CheckErrDBNotRecord(err, "数据不存在!"); e != nil {
return
@@ -207,29 +187,29 @@ func (service {{{ toCamelCase .EntityName }}}Service) Del({{{ title (toCamelCase
err = service.db.Delete(&obj).Error
e = response.CheckErr(err, "删除失败")
{{{- end }}}
service.RemoveCache(obj)
cacheUtil.RemoveCache(obj.{{{ toUpperCamelCase .PrimaryKey }}})
return
}
// ExportFile {{{ .FunctionName }}}导出
func (service {{{ toCamelCase .EntityName }}}Service) ExportFile(listReq {{{ title (toCamelCase .EntityName) }}}ListReq) (res []{{{ title (toCamelCase .EntityName) }}}Resp, e error) {
func (service {{{ toCamelCase .EntityName }}}Service) ExportFile(listReq {{{ toUpperCamelCase .EntityName }}}ListReq) (res []{{{ toUpperCamelCase .EntityName }}}Resp, e error) {
//
dbModel := service.GetModel(listReq)
//
var modelList []model.{{{ title (toCamelCase .EntityName) }}}
var modelList []model.{{{ toUpperCamelCase .EntityName }}}
err := dbModel.Order("id asc").Find(&modelList).Error
if e = response.CheckErr(err, "查询失败"); e != nil {
return
}
result := []{{{ title (toCamelCase .EntityName) }}}Resp{}
result := []{{{ toUpperCamelCase .EntityName }}}Resp{}
response.Copy(&result, modelList)
return result, nil
}
// 导入
func (service {{{ toCamelCase .EntityName }}}Service) ImportFile(importReq []{{{ title (toCamelCase .EntityName) }}}Resp) (e error) {
var importData []model.{{{ title (toCamelCase .EntityName) }}}
func (service {{{ toCamelCase .EntityName }}}Service) ImportFile(importReq []{{{ toUpperCamelCase .EntityName }}}Resp) (e error) {
var importData []model.{{{ toUpperCamelCase .EntityName }}}
response.Copy(&importData, importReq)
err := service.db.Create(&importData).Error
e = response.CheckErr(err, "添加失败")

View File

@@ -6,6 +6,8 @@
<uv-form-item label="{{{.ColumnComment}}}" prop="{{{(toCamelCase .GoField)}}}" borderBottom>
{{{- if and (ne .DictType "") (or (eq .HtmlType "select") (eq .HtmlType "radio") (eq .HtmlType "checkbox")) }}}
<dict-value :options="dictData.{{{ .DictType }}}" :value="row.{{{ (toCamelCase .GoField) }}}" />
{{{- else if and (ne .ListAllApi "") (or (eq .HtmlType "select") (eq .HtmlType "radio") (eq .HtmlType "checkbox")) }}}
<dict-value :options="listAllData.{{{pathToName .ListAllApi }}}" :value="row.{{{ (toCamelCase .GoField) }}}" labelKey='id' valueKey='id' />
{{{- else if eq .HtmlType "imageUpload" }}}
<uv-image :src="$filePath(form.{{{(toCamelCase .GoField)}}})" width="100%"></uv-image>
{{{- else }}}
@@ -29,7 +31,7 @@
<script setup lang="ts">
import {ref} from "vue";
import { onLoad,onShow } from "@dcloudio/uni-app";
import { useDictData } from "@/hooks/useDictOptions";
import { useDictData,useListAllData } from "@/hooks/useDictOptions";
import { {{{ .ModuleName }}}_detail } from "@/api/{{{ .ModuleName }}}";
@@ -46,6 +48,7 @@
{{{- end }}}
{{{- end }}}
});
{{{- if ge (len .DictFields) 1 }}}
{{{- $dictSize := sub (len .DictFields) 1 }}}
const { dictData } = useDictData<
@@ -55,6 +58,20 @@ const { dictData } = useDictData<
{{{- end }}}
}>([{{{- range .DictFields }}}'{{{ . }}}'{{{- if ne (index $.DictFields $dictSize) . }}},{{{- end }}}{{{- end }}}])
{{{- end }}}
{{{- if ge (len .ListAllFields) 1 }}}
{{{- $list_all_size := sub (len .ListAllFields) 1 }}}
const { listAllData } = useListAllData<{
{{{- range .ListAllFields }}}
{{{pathToName . }}}: any[]
{{{- end }}}
}>({
{{{- range .ListAllFields }}}
{{{pathToName . }}}:'{{{deletePathPrefix . }}}',
{{{- end }}}
})
{{{- end }}}
onLoad((e) => {
console.log("onLoad", e);
getDetails(e.id);
@@ -85,7 +102,7 @@ const { dictData } = useDictData<
}
function edit() {
toPath("/pages/{{{ .ModuleName }}}/edit", { id: form.value.id });
toPath("/pages/{{{nameToPath .ModuleName }}}/edit", { id: form.value.id });
}
</script>

View File

@@ -15,6 +15,8 @@
{{{- else if or (eq .HtmlType "checkbox") (eq .HtmlType "radio") (eq .HtmlType "select")}}}
{{{- if ne .DictType "" }}}
<x-picker v-model="form.{{{ (toCamelCase .GoField) }}}" valueKey="value" labelKey="name" :columns="dictData.{{{ .DictType }}}"></x-picker>
{{{- else if ne .ListAllApi "" }}}
<x-picker v-model="form.{{{ (toCamelCase .GoField) }}}" valueKey="id" labelKey="id" :columns="listAllData.{{{pathToName .ListAllApi}}}"></x-picker>
{{{- else }}}
请选择字典生成代码
{{{- end }}}
@@ -46,8 +48,9 @@
alert
} from "@/utils/utils";
import {
useDictData
useDictData,useListAllData
} from "@/hooks/useDictOptions";
import type { type_dict } from '@/hooks/useDictOptions'
let formRef = ref();
let form = ref<type_{{{ .ModuleName }}}_edit>({
@@ -94,11 +97,24 @@
{{{- $dictSize := sub (len .DictFields) 1 }}}
const { dictData } = useDictData<{
{{{- range .DictFields }}}
{{{ . }}}: any[]
{{{ . }}}: type_dict[]
{{{- end }}}
}>([{{{- range .DictFields }}}'{{{ . }}}'{{{- if ne (index $.DictFields $dictSize) . }}},{{{- end }}}{{{- end }}}])
{{{- end }}}
{{{- if ge (len .ListAllFields) 1 }}}
{{{- $list_all_size := sub (len .ListAllFields) 1 }}}
const { listAllData } = useListAllData<{
{{{- range .ListAllFields }}}
{{{pathToName . }}}: any[]
{{{- end }}}
}>({
{{{- range .ListAllFields }}}
{{{pathToName . }}}:'{{{deletePathPrefix . }}}',
{{{- end }}}
})
{{{- end }}}
function getDetails(id) {
{{{ .ModuleName }}}_detail(id).then((res) => {
if (res.code == 200) {

View File

@@ -110,13 +110,13 @@ onReachBottom(() => {
});
function toDetails(item) {
toPath("/pages/{{{ .ModuleName }}}/details", { id: item.id });
toPath("/pages/{{{nameToPath .ModuleName }}}/details", { id: item.id });
}
function moreSearch() {
toPath("/pages/{{{ .ModuleName }}}/search");
toPath("/pages/{{{nameToPath .ModuleName }}}/search");
}
function add() {
toPath("/pages/{{{ .ModuleName }}}/edit");
toPath("/pages/{{{nameToPath .ModuleName }}}/edit");
}
</script>

View File

@@ -7,9 +7,11 @@
{{{- if eq .HtmlType "datetime" }}}
<x-date-range v-model:startTime="form.{{{ (toCamelCase .GoField) }}}Start"
v-model:endTime="form.{{{ (toCamelCase .GoField) }}}End"></x-date-range>
{{{- else if or (eq .HtmlType "select") (eq .HtmlType "radio") }}}
{{{- else if or (eq .HtmlType "checkbox") (eq .HtmlType "radio") (eq .HtmlType "select") }}}
{{{- if ne .DictType "" }}}
<x-picker v-model="form.{{{ (toCamelCase .GoField) }}}" valueKey="value" labelKey="name" :columns="dictData.{{{ .DictType }}}"></x-picker>
{{{- else if ne .ListAllApi "" }}}
<x-picker v-model="form.{{{ (toCamelCase .GoField) }}}" valueKey="id" labelKey="id" :columns="listAllData.{{{pathToName .ListAllApi}}}"></x-picker>
{{{- end }}}
{{{- else if eq .HtmlType "input" }}}
<uv-input v-model="form.{{{ (toCamelCase .GoField) }}}"> </uv-input>
@@ -39,7 +41,7 @@
clearObjEmpty
} from "@/utils/utils";
import {
useDictData
useDictData,useListAllData
} from "@/hooks/useDictOptions";
import xDateRange from "@/components/x-date-range/x-date-range.vue";
import type {type_{{{.ModuleName}}}_query} from "@/api/monitor_project";
@@ -52,15 +54,27 @@ const { dictData } = useDictData<{
}>([{{{- range .DictFields }}}'{{{ . }}}'{{{- if ne (index $.DictFields $dictSize) . }}},{{{- end }}}{{{- end }}}])
{{{- end }}}
{{{- if ge (len .ListAllFields) 1 }}}
{{{- $list_all_size := sub (len .ListAllFields) 1 }}}
const { listAllData } = useListAllData<{
{{{- range .ListAllFields }}}
{{{pathToName . }}}: any[]
{{{- end }}}
}>({
{{{- range .ListAllFields }}}
{{{pathToName . }}}:'{{{deletePathPrefix . }}}',
{{{- end }}}
})
{{{- end }}}
let form = ref<type_{{{.ModuleName}}}_query>({
{{{- range .Columns }}}
{{{- if .IsQuery }}}
{{{- if eq .HtmlType "datetime" }}}
{{{ (toCamelCase .GoField) }}}Start: '',
{{{ (toCamelCase .GoField) }}}End: '',
{{{ (toCamelCase .GoField) }}}Start: null,
{{{ (toCamelCase .GoField) }}}End: null,
{{{- else }}}
{{{ (toCamelCase .GoField) }}}: '',
{{{ (toCamelCase .GoField) }}}: null,
{{{- end }}}
{{{- end }}}
{{{- end }}}
@@ -75,7 +89,7 @@ const { dictData } = useDictData<{
return toast("请输入查询条件");
}
toPath("/pages/{{{ .ModuleName }}}/index", search);
toPath("/pages/{{{nameToPath .ModuleName }}}/index", search);
}
</script>

View File

@@ -33,7 +33,7 @@
</el-form-item>
{{{- else if eq .HtmlType "number" }}}
<el-form-item label="{{{ .ColumnComment }}}" prop="{{{ (toCamelCase .GoField) }}}">
<el-input-number v-model="formData.{{{ (toCamelCase .GoField) }}}" :max="9999" />
<el-input-number v-model="formData.{{{ (toCamelCase .GoField) }}}" />
</el-form-item>
{{{- else if eq .HtmlType "textarea" }}}
<el-form-item label="{{{ .ColumnComment }}}" prop="{{{ (toCamelCase .GoField) }}}">
@@ -51,11 +51,17 @@
<el-checkbox
v-for="(item, index) in dictData.{{{ .DictType }}}"
:key="index"
:label="item.value"
:label="item.name"
:value="item.value"
:disabled="!item.status"
>
{{ item.name }}
</el-checkbox>
></el-checkbox>
{{{- else if ne .ListAllApi "" }}}
<el-checkbox
v-for="(item, index) in listAllData.{{{pathToName .ListAllApi }}}"
:key="index"
:label="item.id"
:value="item.id"
></el-checkbox>
{{{- else }}}
<el-checkbox>请选择字典生成</el-checkbox>
{{{- end }}}
@@ -76,6 +82,18 @@
{{{- end }}}
clearable
:disabled="!item.status"
/>
{{{- else if ne .ListAllApi "" }}}
<el-option
v-for="(item, index) in listAllData.{{{pathToName .ListAllApi }}}"
:key="index"
:label="item.id"
{{{- if eq .GoType "int" }}}
:value="parseInt(item.id)"
{{{- else }}}
:value="String(item.id)"
{{{- end }}}
clearable
/>
{{{- else }}}
<el-option label="请选择字典生成" value="" />
@@ -89,14 +107,26 @@
<el-radio
v-for="(item, index) in dictData.{{{ .DictType }}}"
:key="index"
:label="item.name"
{{{- if eq .GoType "int" }}}
:label="parseInt(item.value)"
:value="parseInt(item.value)"
{{{- else }}}
:label="item.value"
:value="item.value"
{{{- end }}}
:disabled="!item.status"
></el-radio>
{{{- else if ne .ListAllApi "" }}}
<el-radio
v-for="(item, index) in listAllData.{{{ pathToName .ListAllApi }}}"
:key="index"
:label="item.name"
{{{- if eq .GoType "int" }}}
:value="parseInt(item.id)"
{{{- else }}}
:value="item.id"
{{{- end }}}
>
{{ item.name }}
{{ item.id }}
</el-radio>
{{{- else }}}
<el-radio label="0">请选择字典生成</el-radio>
@@ -141,6 +171,10 @@ defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
},
listAllData:{
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])

View File

@@ -18,9 +18,7 @@
clearable
>
{{{- if eq .DictType "" }}}
<el-option label="请选择字典生成" value="" />
{{{- else }}}
{{{- if ne .DictType "" }}}
<el-option label="全部" value="" />
<el-option
v-for="(item, index) in dictData.{{{ .DictType }}}"
@@ -28,6 +26,16 @@
:label="item.name"
:value="item.value"
/>
{{{- else if ne .ListAllApi ""}}}
<el-option label="全部" value="" />
<el-option
v-for="(item, index) in listAllData.{{{pathToName .ListAllApi}}}"
:key="index"
:label="item.id"
:value="item.id"
/>
{{{- else }}}
<el-option label="请选择字典生成" value="" />
{{{- end }}}
</el-select>
</el-form-item>
@@ -71,6 +79,12 @@
<dict-value :options="dictData.{{{ .DictType }}}" :value="row.{{{ (toCamelCase .GoField) }}}" />
</template>
</el-table-column>
{{{- else if and (ne .ListAllApi "") (or (eq .HtmlType "select") (eq .HtmlType "radio") (eq .HtmlType "checkbox")) }}}
<el-table-column label="{{{ .ColumnComment }}}" prop="{{{ (toCamelCase .GoField) }}}" min-width="100">
<template #default="{ row }">
<dict-value :options="listAllData.{{{pathToName .ListAllApi }}}" :value="row.{{{ (toCamelCase .GoField) }}}" labelKey='id' valueKey='id' />
</template>
</el-table-column>
{{{- else if eq .HtmlType "imageUpload" }}}
<el-table-column label="{{{ .ColumnComment }}}" prop="{{{ (toCamelCase .GoField) }}}" min-width="100">
<template #default="{ row }">
@@ -125,6 +139,9 @@
{{{- if ge (len .DictFields) 1 }}}
:dict-data="dictData"
{{{- end }}}
{{{- if ge (len .ListAllFields) 1 }}}
:list-all-data="listAllData"
{{{- end }}}
@success="getLists"
@close="showEdit = false"
/>
@@ -132,11 +149,14 @@
</template>
<script lang="ts" setup>
import { {{{ .ModuleName }}}_delete, {{{ .ModuleName }}}_list } from '@/api/{{{ .ModuleName }}}'
import type { type_{{{ .ModuleName }}},type_{{{.ModuleName}}}_query } from "@/api/{{{ .ModuleName }}}";
import EditPopup from './edit.vue'
import feedback from '@/utils/feedback'
{{{- if ge (len .DictFields) 1 }}}
import { useDictData } from '@/hooks/useDictOptions'
{{{- end }}}
import { useDictData,useListAllData } from '@/hooks/useDictOptions'
import type { type_dict } from '@/hooks/useDictOptions'
import type { ElTable } from 'element-plus'
defineOptions({
name:"{{{ .ModuleName }}}"
@@ -146,9 +166,9 @@ const editRef = shallowRef<InstanceType<typeof EditPopup>>()
let isExpand = false
const showEdit = ref(false)
const loading = ref(false)
const lists = ref<any[]>([])
const lists = ref<type_{{{ .ModuleName }}}[]>([])
const queryParams = reactive({
const queryParams = reactive<type_{{{.ModuleName}}}_query>({
{{{- range .Columns }}}
{{{- if .IsQuery }}}
{{{- if eq .HtmlType "datetime" }}}
@@ -176,11 +196,24 @@ const getLists = async () => {
{{{- $dictSize := sub (len .DictFields) 1 }}}
const { dictData } = useDictData<{
{{{- range .DictFields }}}
{{{ . }}}: any[]
{{{ . }}}: type_dict[]
{{{- end }}}
}>([{{{- range .DictFields }}}'{{{ . }}}'{{{- if ne (index $.DictFields $dictSize) . }}},{{{- end }}}{{{- end }}}])
{{{- end }}}
{{{- if ge (len .ListAllFields) 1 }}}
{{{- $list_all_size := sub (len .ListAllFields) 1 }}}
const { listAllData } = useListAllData<{
{{{- range .ListAllFields }}}
{{{pathToName . }}}: any[]
{{{- end }}}
}>({
{{{- range .ListAllFields }}}
{{{pathToName . }}}:'{{{deletePathPrefix . }}}',
{{{- end }}}
})
{{{- end }}}
const handleAdd = async ({{{ .Table.TreePrimary }}}?: number) => {
showEdit.value = true
await nextTick()

View File

@@ -18,9 +18,8 @@
v-model="queryParams.{{{ (toCamelCase .GoField) }}}"
clearable
>
{{{- if eq .DictType "" }}}
<el-option label="请选择字典生成" value="" />
{{{- else }}}
{{{- if ne .DictType "" }}}
<el-option label="全部" value="" />
<el-option
v-for="(item, index) in dictData.{{{ .DictType }}}"
@@ -28,6 +27,16 @@
:label="item.name"
:value="item.value"
/>
{{{- else if ne .ListAllApi ""}}}
<el-option label="全部" value="" />
<el-option
v-for="(item, index) in listAllData.{{{pathToName .ListAllApi}}}"
:key="index"
:label="item.id"
:value="item.id"
/>
{{{- else }}}
<el-option label="请选择字典生成" value="" />
{{{- end }}}
</el-select>
</el-form-item>
@@ -88,6 +97,13 @@
<dict-value :options="dictData.{{{ .DictType }}}" :value="row.{{{ (toCamelCase .GoField) }}}" />
</template>
</el-table-column>
{{{- else if and (ne .ListAllApi "") (or (eq .HtmlType "select") (eq .HtmlType "radio") (eq .HtmlType "checkbox")) }}}
<el-table-column label="{{{ .ColumnComment }}}" prop="{{{ (toCamelCase .GoField) }}}" min-width="100">
<template #default="{ row }">
<dict-value :options="listAllData.{{{pathToName .ListAllApi }}}" :value="row.{{{ (toCamelCase .GoField) }}}" labelKey='id' valueKey='id' />
</template>
</el-table-column>
{{{- else if eq .HtmlType "imageUpload" }}}
<el-table-column label="{{{ .ColumnComment }}}" prop="{{{ (toCamelCase .GoField) }}}" min-width="100">
<template #default="{ row }">
@@ -137,6 +153,9 @@
{{{- if ge (len .DictFields) 1 }}}
:dict-data="dictData"
{{{- end }}}
{{{- if ge (len .ListAllFields) 1 }}}
:list-all-data="listAllData"
{{{- end }}}
@success="getLists"
@close="showEdit = false"
/>
@@ -146,9 +165,10 @@
import { {{{ .ModuleName }}}_delete, {{{ .ModuleName }}}_list,{{{.ModuleName}}}_import_file, {{{.ModuleName}}}_export_file } from '@/api/{{{ .ModuleName }}}'
import type { type_{{{ .ModuleName }}},type_{{{.ModuleName}}}_query } from "@/api/{{{ .ModuleName }}}";
{{{- if ge (len .DictFields) 1 }}}
import { useDictData } from '@/hooks/useDictOptions'
{{{- end }}}
import { useDictData,useListAllData } from '@/hooks/useDictOptions'
import type { type_dict } from '@/hooks/useDictOptions'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
@@ -161,10 +181,10 @@ const queryParams = reactive<type_{{{.ModuleName}}}_query>({
{{{- range .Columns }}}
{{{- if .IsQuery }}}
{{{- if eq .HtmlType "datetime" }}}
{{{ (toCamelCase .GoField) }}}Start: '',
{{{ (toCamelCase .GoField) }}}End: '',
{{{ (toCamelCase .GoField) }}}Start: null,
{{{ (toCamelCase .GoField) }}}End: null,
{{{- else }}}
{{{ (toCamelCase .GoField) }}}: '',
{{{ (toCamelCase .GoField) }}}: null,
{{{- end }}}
{{{- end }}}
{{{- end }}}
@@ -179,11 +199,24 @@ const { pager, getLists, resetPage, resetParams } = usePaging<type_{{{ .ModuleNa
{{{- $dictSize := sub (len .DictFields) 1 }}}
const { dictData } = useDictData<{
{{{- range .DictFields }}}
{{{ . }}}: any[]
{{{ . }}}: type_dict[]
{{{- end }}}
}>([{{{- range .DictFields }}}'{{{ . }}}'{{{- if ne (index $.DictFields $dictSize) . }}},{{{- end }}}{{{- end }}}])
{{{- end }}}
{{{- if ge (len .ListAllFields) 1 }}}
{{{- $list_all_size := sub (len .ListAllFields) 1 }}}
const { listAllData } = useListAllData<{
{{{- range .ListAllFields }}}
{{{pathToName . }}}: any[]
{{{- end }}}
}>({
{{{- range .ListAllFields }}}
{{{pathToName . }}}:'{{{deletePathPrefix . }}}',
{{{- end }}}
})
{{{- end }}}
const handleAdd = async () => {
showEdit.value = true

View File

@@ -19,13 +19,16 @@ var TemplateUtil = templateUtil{
template.FuncMap{
"sub": sub,
"slice": slice,
"title": strings.Title,
"toSnakeCase": util.StringUtil.ToSnakeCase,
"toCamelCase": util.StringUtil.ToCamelCase,
"toUpperCamelCase": util.StringUtil.ToUpperCamelCase,
"contains": util.ToolsUtil.Contains,
"goToTsType": util.ToolsUtil.GoToTsType,
"getPageResp": util.ToolsUtil.GetPageResp,
"nameToPath": util.ToolsUtil.NameToPath,
"goToTsType": GenUtil.GoToTsType,
"goToNullType": GenUtil.GoToNullType,
"getPageResp": GenUtil.GetPageResp,
"nameToPath": GenUtil.NameToPath,
"pathToName": GenUtil.PathToName,
"deletePathPrefix": GenUtil.DeletePathPrefix,
}),
}
@@ -65,6 +68,7 @@ type TplVars struct {
ListFields []string
DetailFields []string
DictFields []string
ListAllFields []string
IsSearch bool
ModelOprMap map[string]string
Table gen_model.GenTable
@@ -91,6 +95,7 @@ func (tu templateUtil) PrepareVars(table gen_model.GenTable, columns []gen_model
var listFields []string
var detailFields []string
var dictFields []string
var listAllFields []string
var subColumns []gen_model.GenTableColumn
var oriSubColNames []string
for _, column := range oriSubCols {
@@ -122,6 +127,9 @@ func (tu templateUtil) PrepareVars(table gen_model.GenTable, columns []gen_model
if column.DictType != "" && !util.ToolsUtil.Contains(dictFields, column.DictType) {
dictFields = append(dictFields, column.DictType)
}
if column.ListAllApi != "" && !util.ToolsUtil.Contains(listAllFields, column.ListAllApi) {
listAllFields = append(listAllFields, column.ListAllApi)
}
}
//QueryType转换查询比较运算符
modelOprMap := map[string]string{
@@ -150,6 +158,7 @@ func (tu templateUtil) PrepareVars(table gen_model.GenTable, columns []gen_model
ListFields: listFields,
DetailFields: detailFields,
DictFields: dictFields,
ListAllFields: listAllFields,
IsSearch: isSearch,
ModelOprMap: modelOprMap,
Columns: columns,
@@ -223,16 +232,16 @@ func (tu templateUtil) GetFilePaths(tplCodeMap map[string]string, ModuleName str
"gocode/controller.go.tpl": strings.Join([]string{"server/admin/", ModuleName, "/", ModuleName, "_ctl.go"}, ""), //"server/admin/%s/%s_ctl.go",
"vue/api.ts.tpl": strings.Join([]string{"admin/src/api/", ModuleName, ".ts"}, ""), // "admin/src/api/%s.ts",
"vue/edit.vue.tpl": strings.Join([]string{"admin/src/views/", util.ToolsUtil.NameToPath(ModuleName), "/edit.vue"}, ""), // "admin/src/views/%s/edit.vue",
"vue/index.vue.tpl": strings.Join([]string{"admin/src/views/", util.ToolsUtil.NameToPath(ModuleName), "/index.vue"}, ""), // "admin/src/views/%s/index.vue",
"vue/index-tree.vue.tpl": strings.Join([]string{"admin/src/views/", util.ToolsUtil.NameToPath(ModuleName), "/index-tree.vue"}, ""), // "admin/src/views/%s/index-tree.vue",
"vue/edit.vue.tpl": strings.Join([]string{"admin/src/views/", GenUtil.NameToPath(ModuleName), "/edit.vue"}, ""), // "admin/src/views/%s/edit.vue",
"vue/index.vue.tpl": strings.Join([]string{"admin/src/views/", GenUtil.NameToPath(ModuleName), "/index.vue"}, ""), // "admin/src/views/%s/index.vue",
"vue/index-tree.vue.tpl": strings.Join([]string{"admin/src/views/", GenUtil.NameToPath(ModuleName), "/index-tree.vue"}, ""), // "admin/src/views/%s/index-tree.vue",
"uniapp/api.ts.tpl": strings.Join([]string{"x_admin_app/api/", ModuleName, ".ts"}, ""),
"uniapp/edit.vue.tpl": strings.Join([]string{"x_admin_app/pages/", util.ToolsUtil.NameToPath(ModuleName), "/edit.vue"}, ""),
"uniapp/index.vue.tpl": strings.Join([]string{"x_admin_app/pages/", util.ToolsUtil.NameToPath(ModuleName), "/index.vue"}, ""),
"uniapp/search.vue.tpl": strings.Join([]string{"x_admin_app/pages/", util.ToolsUtil.NameToPath(ModuleName), "/search.vue"}, ""),
"uniapp/details.vue.tpl": strings.Join([]string{"x_admin_app/pages/", util.ToolsUtil.NameToPath(ModuleName), "/details.vue"}, ""),
"uniapp/pages.json.tpl": strings.Join([]string{"x_admin_app/pages/", util.ToolsUtil.NameToPath(ModuleName), "/pages.json"}, ""),
"uniapp/edit.vue.tpl": strings.Join([]string{"x_admin_app/pages/", GenUtil.NameToPath(ModuleName), "/edit.vue"}, ""),
"uniapp/index.vue.tpl": strings.Join([]string{"x_admin_app/pages/", GenUtil.NameToPath(ModuleName), "/index.vue"}, ""),
"uniapp/search.vue.tpl": strings.Join([]string{"x_admin_app/pages/", GenUtil.NameToPath(ModuleName), "/search.vue"}, ""),
"uniapp/details.vue.tpl": strings.Join([]string{"x_admin_app/pages/", GenUtil.NameToPath(ModuleName), "/details.vue"}, ""),
"uniapp/pages.json.tpl": strings.Join([]string{"x_admin_app/pages/", GenUtil.NameToPath(ModuleName), "/pages.json"}, ""),
}
filePath := make(map[string]string)
for tplPath, tplCode := range tplCodeMap {

View File

@@ -211,3 +211,74 @@ func (gu genUtil) GetTablePriCol(columns []gen_model.GenTableColumn) (res gen_mo
}
return
}
/**
* @description: Go类型转TS类型
*/
func (gu genUtil) GoToTsType(s string) string {
if s == "int" || s == "int8" || s == "int16" || s == "int32" || s == "int64" {
return "number"
} else if s == "float" || s == "float32" || s == "float64" {
return "number"
} else if s == "string" {
return "string"
} else if s == "bool" {
return "boolean"
} else if s == "time.Time" {
return "Date"
} else if s == "[]byte" {
return "string"
} else if s == "[]string" {
return "string[]"
} else if s == "[]int" {
return "number[]"
} else if s == "[]float" {
return "number[]"
} else if s == "core.TsTime" {
return "string"
}
return "string"
}
/**
* @description: Go类型转可为null类型转换后还能解决前端对int传了string类型错误问题
*/
func (gu genUtil) GoToNullType(s string) string {
if s == "int64" {
return "null.Int"
} else if s == "int32" || s == "int" {
return "null.Int32"
} else if s == "int8" || s == "int16" {
return "null.Int16"
} else if s == "float" || s == "float32" || s == "float64" {
return "null.Float"
} else if s == "string" {
return "null.String"
} else if s == "bool" {
return "null.Bool"
} else if s == "time.Time" {
return "null.Time"
}
return s
}
// 拼接字符串
func (gu genUtil) GetPageResp(s string) string {
return `response.Response{ data=response.PageResp{ lists= []` + s + `Resp}}`
}
// NameToPath 下划线文件路径
func (gu genUtil) NameToPath(s string) string {
return strings.ReplaceAll(s, "_", "/")
}
func (gu genUtil) PathToName(s string) string {
// 去掉前缀urlPrefix
s = strings.Replace(s, "/api/admin/", "", 1)
return strings.ReplaceAll(s, "/", "_")
}
func (gu genUtil) DeletePathPrefix(s string) string {
// 去掉前缀urlPrefix
s = strings.Replace(s, "/api/admin", "", 1)
return s
}

View File

@@ -1,6 +1,8 @@
module x_admin
go 1.21
go 1.21.4
toolchain go1.22.4
require (
github.com/fatih/structs v1.1.0
@@ -28,8 +30,11 @@ require (
)
require (
github.com/guregu/null/v5 v5.0.0
github.com/redis/go-redis/v9 v9.5.2
go.uber.org/ratelimit v0.3.1
golang.org/x/sync v0.7.0
golang.org/x/text v0.16.0
)
require (
@@ -85,13 +90,11 @@ require (
github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/ratelimit v0.3.1 // indirect
golang.org/x/arch v0.8.0 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
google.golang.org/protobuf v1.34.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect

View File

@@ -79,6 +79,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/guregu/null/v5 v5.0.0 h1:PRxjqyOekS11W+w/7Vfz6jgJE/BCwELWtgvOJzddimw=
github.com/guregu/null/v5 v5.0.0/go.mod h1:SjupzNy+sCPtwQTKWhUCqjhVCO69hpsl2QsZrWHjlwU=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=

View File

@@ -43,6 +43,7 @@ type GenTableColumn struct {
QueryType string `gorm:"not null;default:'=';comment:'查询方式: [等于、不等于、大于、小于、范围]'"`
HtmlType string `gorm:"not null;default:'';comment:'显示类型: [文本框、文本域、下拉框、复选框、单选框、日期控件]'"`
DictType string `gorm:"not null;default:'';comment:'字典类型'"`
ListAllApi string `gorm:"not null;default:'';comment:'列表数据来源'"`
Sort int `gorm:"not null;default:0;comment:'排序编号'"`
CreateTime core.TsTime `gorm:"autoCreateTime;not null;comment:'创建时间'"`
UpdateTime core.TsTime `gorm:"autoUpdateTime;not null;comment:'更新时间'"`

67
server/util/cache.go Normal file
View File

@@ -0,0 +1,67 @@
package util
import (
"errors"
"strconv"
)
// var CacheUtil = toolsUtil{}
type CacheUtil struct {
Name string
}
// 设置缓存
func (c CacheUtil) SetCache(key interface{}, obj interface{}) bool {
str, e := ToolsUtil.ObjToJson(obj)
if e != nil {
return false
}
var cacheKey string
switch k := key.(type) {
case int:
cacheKey = strconv.Itoa(k)
case string:
cacheKey = k
default:
return false
}
return RedisUtil.HSet(c.Name, cacheKey, str, 3600)
}
// 获取缓存
func (c CacheUtil) GetCache(key interface{}, obj interface{}) error {
var cacheKey string
switch k := key.(type) {
case int:
cacheKey = strconv.Itoa(k)
case string:
cacheKey = k
default:
return errors.New("缓存key无效")
}
str := RedisUtil.HGet(c.Name, cacheKey)
if str == "" {
return errors.New("获取缓存失败")
}
err := ToolsUtil.JsonToObj(str, &obj)
if err != nil {
return errors.New("解析缓存失败")
}
return nil
}
// 删除缓存
func (c CacheUtil) RemoveCache(key interface{}) bool {
var cacheKey string
switch k := key.(type) {
case int:
cacheKey = strconv.Itoa(k)
case string:
cacheKey = k
default:
return false
}
return RedisUtil.HDel(c.Name, cacheKey)
}

View File

@@ -4,6 +4,9 @@ import (
"bytes"
"strings"
"unicode"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)
var StringUtil = stringUtil{}
@@ -25,10 +28,23 @@ func (su stringUtil) ToSnakeCase(s string) string {
}
return buf.String()
}
// 转换为小驼峰命名
func (su stringUtil) ToCamelCase(s string) string {
words := strings.Split(s, "_")
c := cases.Title(language.Und, cases.NoLower)
for i := 1; i < len(words); i++ {
words[i] = strings.Title(words[i])
words[i] = c.String(words[i])
}
return strings.Join(words, "")
}
// 转换为大驼峰命名
func (su stringUtil) ToUpperCamelCase(s string) string {
words := strings.Split(s, "_")
c := cases.Title(language.Und, cases.NoLower)
for i := 0; i < len(words); i++ {
words[i] = c.String(words[i])
}
return strings.Join(words, "")
}

View File

@@ -69,44 +69,6 @@ func (tu toolsUtil) Contains(src interface{}, elem interface{}) bool {
return false
}
/**
* @description: Go类型转TS类型
*/
func (tu toolsUtil) GoToTsType(s string) string {
if s == "int" || s == "int8" || s == "int16" || s == "int32" || s == "int64" {
return "number"
} else if s == "float" || s == "float32" || s == "float64" {
return "number"
} else if s == "string" {
return "string"
} else if s == "bool" {
return "boolean"
} else if s == "time.Time" {
return "Date"
} else if s == "[]byte" {
return "string"
} else if s == "[]string" {
return "string[]"
} else if s == "[]int" {
return "number[]"
} else if s == "[]float" {
return "number[]"
} else if s == "core.TsTime" {
return "string"
}
return "string"
}
// 拼接字符串
func (tu toolsUtil) GetPageResp(s string) string {
return `response.Response{ data=response.PageResp{ lists= []` + s + `Resp}}`
}
// NameToPath 下划线文件路径
func (tu toolsUtil) NameToPath(s string) string {
return strings.ReplaceAll(s, "_", "/")
}
// Round float四舍五入
func (tu toolsUtil) Round(val float64, n int) float64 {
base := math.Pow(10, float64(n))

View File

@@ -1,5 +1,5 @@
import { request } from "@/utils/request";
import { reactive, toRaw } from "vue";
import { reactive } from "vue";
interface Options {
[propName: string]: string
@@ -39,6 +39,19 @@ export function useDictOptions<T = any>(options: Options) {
};
}
export type type_dict = {
color?: string
createTime?: string
id?: number
name?: string
remark?: string
sort?: number
status?: number
typeId?: number
updateTime?: string
value?: string
}
export function useDictData<T = any>(dict: string[]) {
const options: Options = {};
for (const type of dict) {
@@ -52,4 +65,14 @@ export function useDictData<T = any>(dict: string[]) {
};
}
// export function useAllList<T = any>(options: Options) {}
export function useListAllData<T = any>(paths: string[]) {
const options: Options = {}
for (const key in paths) {
options[key] = paths[key]
}
const { optionsData } = useDictOptions<T>(options)
return {
listAllData: optionsData
}
}

View File

@@ -41,6 +41,7 @@ export function usePaging<T>(options: Options) {
// 请求分页接口
const getLists = () => {
pager.loading = "loading";
console.log('params', params);
return fetchFun({
pageNo: pager.pageNo,
pageSize: pager.pageSize,